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