diff --git a/ConfusedPolarBear.Plugin.IntroSkipper/Controllers/SkipIntroController.cs b/ConfusedPolarBear.Plugin.IntroSkipper/Controllers/SkipIntroController.cs index d2bf61a..862aded 100644 --- a/ConfusedPolarBear.Plugin.IntroSkipper/Controllers/SkipIntroController.cs +++ b/ConfusedPolarBear.Plugin.IntroSkipper/Controllers/SkipIntroController.cs @@ -21,24 +21,19 @@ public class SkipIntroController : ControllerBase } /// - /// Returns the timestamps of the introduction in a television episode. + /// Returns the timestamps of the introduction in a television episode. Responses are in API version 1 format. /// /// ID of the episode. Required. /// Episode contains an intro. /// Failed to find an intro in the provided episode. /// Detected intro. [HttpGet("Episode/{id}/IntroTimestamps")] + [HttpGet("Episode/{id}/IntroTimestamps/v1")] public ActionResult GetIntroTimestamps([FromRoute] Guid id) { - if (!Plugin.Instance!.Intros.ContainsKey(id)) - { - return NotFound(); - } + var intro = GetIntro(id); - var intro = Plugin.Instance!.Intros[id]; - - // Check that the episode was analyzed successfully. - if (!intro.Valid) + if (intro is null || !intro.Valid) { return NotFound(); } @@ -51,6 +46,19 @@ public class SkipIntroController : ControllerBase return intro; } + /// Lookup and return the intro timestamps for the provided item. + /// Unique identifier of this episode. + /// Intro object if the provided item has an intro, null otherwise. + private Intro? GetIntro(Guid id) + { + if (!Plugin.Instance!.Intros.ContainsKey(id)) + { + return null; + } + + return Plugin.Instance!.Intros[id]; + } + /// /// Erases all previously discovered introduction timestamps. /// diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..6af4de7 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,54 @@ +# API + +## General + +The main API endpoint exposed by this plugin is `/Episode/{ItemId}/IntroTimestamps`. If an introduction was detected inside of a television episode, this endpoint will return the timestamps of that intro. + +An API version can be optionally selected by appending `/v{Version}` to the URL. If a version is not specified, version 1 will be selected. + +## API version 1 (default) + +API version 1 was introduced with the initial alpha release of the plugin. It is accessible (via a `GET` request) on the following URLs: +* `/Episode/{ItemId}/IntroTimestamps` +* `/Episode/{ItemId}/IntroTimestamps/v1` + +Both of these endpoints require an authorization token to be provided. + +The possible status codes of this endpoint are: +* `200 (OK)`: An introduction was detected for this item and the response is deserializable as JSON using the schema below. +* `404 (Not Found)`: Either no introduction was detected for this item or it is not a television episode. + +JSON schema: + +```jsonc +{ + "EpisodeId": "{item id}", // Unique GUID for this item as provided by Jellyfin. + "Valid": true, // Used internally to mark items that have intros. Should be ignored as it will always be true. + "IntroStart": 100.5, // Start time (in seconds) of the introduction. + "IntroEnd": 130.42, // End time (in seconds) of the introduction. + "ShowSkipPromptAt": 95.5, // Recommended time to display an on-screen intro skip prompt to the user. + "HideSkipPromptAt": 110.5 // Recommended time to hide the on-screen intro skip prompt. +} +``` + +The `ShowSkipPromptAt` and `HideSkipPromptAt` properties are derived from the start time of the introduction and are customizable by the user from the plugin's settings. + +### Example curl command + +`curl` command to get introduction timestamps for the item with id `12345678901234567890123456789012`: + +```shell +curl http://127.0.0.1:8096/Episode/12345678901234567890123456789012/IntroTimestamps/v1 -H 'Authorization: MediaBrowser Token="98765432109876543210987654321098"' +``` + +This returns the following JSON object: +```json +{ + "EpisodeId": "12345678901234567890123456789012", + "Valid": true, + "IntroStart": 304, + "IntroEnd": 397.48, + "ShowSkipPromptAt": 299, + "HideSkipPromptAt": 314 +} +```