2020-04-19 23:36:05 +00:00
using System ;
2020-08-06 14:17:45 +00:00
using System.ComponentModel.DataAnnotations ;
2020-05-19 19:02:02 +00:00
using System.Net.Mime ;
2020-04-19 23:36:05 +00:00
using System.Threading ;
using System.Threading.Tasks ;
2020-11-15 17:58:39 +00:00
using Jellyfin.Api.Attributes ;
2020-04-19 23:36:05 +00:00
using MediaBrowser.Common.Extensions ;
using MediaBrowser.Controller.Library ;
using MediaBrowser.Controller.MediaEncoding ;
using Microsoft.AspNetCore.Http ;
using Microsoft.AspNetCore.Mvc ;
2023-01-31 11:18:10 +00:00
namespace Jellyfin.Api.Controllers ;
/// <summary>
/// Attachments controller.
/// </summary>
[Route("Videos")]
public class VideoAttachmentsController : BaseJellyfinApiController
2020-04-19 23:36:05 +00:00
{
2023-01-31 11:18:10 +00:00
private readonly ILibraryManager _libraryManager ;
private readonly IAttachmentExtractor _attachmentExtractor ;
2020-04-19 23:36:05 +00:00
/// <summary>
2023-01-31 11:18:10 +00:00
/// Initializes a new instance of the <see cref="VideoAttachmentsController"/> class.
2020-04-19 23:36:05 +00:00
/// </summary>
2023-01-31 11:18:10 +00:00
/// <param name="libraryManager">Instance of the <see cref="ILibraryManager"/> interface.</param>
/// <param name="attachmentExtractor">Instance of the <see cref="IAttachmentExtractor"/> interface.</param>
public VideoAttachmentsController (
ILibraryManager libraryManager ,
IAttachmentExtractor attachmentExtractor )
2020-04-19 23:36:05 +00:00
{
2023-01-31 11:18:10 +00:00
_libraryManager = libraryManager ;
_attachmentExtractor = attachmentExtractor ;
}
2020-04-19 23:36:05 +00:00
2023-01-31 11:18:10 +00:00
/// <summary>
/// Get video attachment.
/// </summary>
/// <param name="videoId">Video ID.</param>
/// <param name="mediaSourceId">Media Source ID.</param>
/// <param name="index">Attachment Index.</param>
/// <response code="200">Attachment retrieved.</response>
/// <response code="404">Video or attachment not found.</response>
/// <returns>An <see cref="FileStreamResult"/> containing the attachment stream on success, or a <see cref="NotFoundResult"/> if the attachment could not be found.</returns>
[HttpGet("{videoId}/{mediaSourceId}/Attachments/{index}")]
[ProducesFile(MediaTypeNames.Application.Octet)]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task < ActionResult > GetAttachment (
[FromRoute, Required] Guid videoId ,
[FromRoute, Required] string mediaSourceId ,
[FromRoute, Required] int index )
{
try
2020-04-19 23:36:05 +00:00
{
2023-01-31 11:18:10 +00:00
var item = _libraryManager . GetItemById ( videoId ) ;
if ( item is null )
2020-04-19 23:36:05 +00:00
{
2023-01-31 11:18:10 +00:00
return NotFound ( ) ;
}
2020-04-19 23:36:05 +00:00
2023-01-31 11:18:10 +00:00
var ( attachment , stream ) = await _attachmentExtractor . GetAttachment (
item ,
mediaSourceId ,
index ,
CancellationToken . None )
. ConfigureAwait ( false ) ;
2020-04-19 23:36:05 +00:00
2023-01-31 11:18:10 +00:00
var contentType = string . IsNullOrWhiteSpace ( attachment . MimeType )
? MediaTypeNames . Application . Octet
: attachment . MimeType ;
2020-04-19 23:36:05 +00:00
2023-01-31 11:18:10 +00:00
return new FileStreamResult ( stream , contentType ) ;
}
catch ( ResourceNotFoundException e )
{
return NotFound ( e . Message ) ;
2020-04-19 23:36:05 +00:00
}
}
}