TrickplayController.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. using System;
  2. using System.ComponentModel.DataAnnotations;
  3. using System.Net.Mime;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Jellyfin.Api.Attributes;
  7. using Jellyfin.Api.Extensions;
  8. using Jellyfin.Api.Helpers;
  9. using MediaBrowser.Controller.Entities;
  10. using MediaBrowser.Controller.Library;
  11. using MediaBrowser.Controller.Trickplay;
  12. using MediaBrowser.Model;
  13. using Microsoft.AspNetCore.Authorization;
  14. using Microsoft.AspNetCore.Http;
  15. using Microsoft.AspNetCore.Mvc;
  16. namespace Jellyfin.Api.Controllers;
  17. /// <summary>
  18. /// Trickplay controller.
  19. /// </summary>
  20. [Route("")]
  21. [Authorize]
  22. public class TrickplayController : BaseJellyfinApiController
  23. {
  24. private readonly ILibraryManager _libraryManager;
  25. private readonly ITrickplayManager _trickplayManager;
  26. /// <summary>
  27. /// Initializes a new instance of the <see cref="TrickplayController"/> class.
  28. /// </summary>
  29. /// <param name="libraryManager">Instance of <see cref="ILibraryManager"/>.</param>
  30. /// <param name="trickplayManager">Instance of <see cref="ITrickplayManager"/>.</param>
  31. public TrickplayController(
  32. ILibraryManager libraryManager,
  33. ITrickplayManager trickplayManager)
  34. {
  35. _libraryManager = libraryManager;
  36. _trickplayManager = trickplayManager;
  37. }
  38. /// <summary>
  39. /// Gets an image tiles playlist for trickplay.
  40. /// </summary>
  41. /// <param name="itemId">The item id.</param>
  42. /// <param name="width">The width of a single tile.</param>
  43. /// <param name="mediaSourceId">The media version id, if using an alternate version.</param>
  44. /// <response code="200">Tiles playlist returned.</response>
  45. /// <returns>A <see cref="FileResult"/> containing the trickplay playlist file.</returns>
  46. [HttpGet("Videos/{itemId}/Trickplay/{width}/tiles.m3u8")]
  47. [ProducesResponseType(StatusCodes.Status200OK)]
  48. [ProducesResponseType(StatusCodes.Status404NotFound)]
  49. [ProducesPlaylistFile]
  50. public async Task<ActionResult> GetTrickplayHlsPlaylist(
  51. [FromRoute, Required] Guid itemId,
  52. [FromRoute, Required] int width,
  53. [FromQuery] Guid? mediaSourceId)
  54. {
  55. string? playlist = await _trickplayManager.GetHlsPlaylist(mediaSourceId ?? itemId, width, User.GetToken()).ConfigureAwait(false);
  56. if (string.IsNullOrEmpty(playlist))
  57. {
  58. return NotFound();
  59. }
  60. return Content(playlist, MimeTypes.GetMimeType("playlist.m3u8"), Encoding.UTF8);
  61. }
  62. /// <summary>
  63. /// Gets a trickplay tile image.
  64. /// </summary>
  65. /// <param name="itemId">The item id.</param>
  66. /// <param name="width">The width of a single tile.</param>
  67. /// <param name="index">The index of the desired tile.</param>
  68. /// <param name="mediaSourceId">The media version id, if using an alternate version.</param>
  69. /// <response code="200">Tile image returned.</response>
  70. /// <response code="200">Tile image not found at specified index.</response>
  71. /// <returns>A <see cref="FileResult"/> containing the trickplay tiles image.</returns>
  72. [HttpGet("Videos/{itemId}/Trickplay/{width}/{index}.jpg")]
  73. [ProducesResponseType(StatusCodes.Status200OK)]
  74. [ProducesResponseType(StatusCodes.Status404NotFound)]
  75. [ProducesImageFile]
  76. public async Task<ActionResult> GetTrickplayTileImageAsync(
  77. [FromRoute, Required] Guid itemId,
  78. [FromRoute, Required] int width,
  79. [FromRoute, Required] int index,
  80. [FromQuery] Guid? mediaSourceId)
  81. {
  82. var item = _libraryManager.GetItemById<BaseItem>(itemId, User.GetUserId());
  83. if (item is null)
  84. {
  85. return NotFound();
  86. }
  87. var saveWithMedia = _libraryManager.GetLibraryOptions(item).SaveTrickplayWithMedia;
  88. var path = await _trickplayManager.GetTrickplayTilePathAsync(item, width, index, saveWithMedia).ConfigureAwait(false);
  89. if (!string.IsNullOrEmpty(path) && System.IO.File.Exists(path))
  90. {
  91. Response.Headers.ContentDisposition = "attachment";
  92. return PhysicalFile(path, MediaTypeNames.Image.Jpeg);
  93. }
  94. return NotFound();
  95. }
  96. }