mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-07-11 08:43:01 +01:00
Merge branch 'master' into event-rewrite-1
# Conflicts: # Emby.Dlna/Emby.Dlna.csproj # Emby.Dlna/Eventing/DlnaEventManager.cs # Emby.Dlna/Service/BaseService.cs # Emby.Server.Implementations/ScheduledTasks/ScheduledTaskWorker.cs # MediaBrowser.Controller/Subtitles/SubtitleDownloadEventArgs.cs
This commit is contained in:
@@ -83,9 +83,9 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <param name="streamOptions">Optional. The streaming options.</param>
|
||||
/// <response code="200">Audio stream returned.</response>
|
||||
/// <returns>A <see cref="FileResult"/> containing the audio file.</returns>
|
||||
[HttpGet("{itemId}/{stream=stream}.{container?}", Name = "GetAudioStreamByContainer")]
|
||||
[HttpGet("{itemId}/stream.{container}", Name = "GetAudioStreamByContainer")]
|
||||
[HttpGet("{itemId}/stream", Name = "GetAudioStream")]
|
||||
[HttpHead("{itemId}/{stream=stream}.{container?}", Name = "HeadAudioStreamByContainer")]
|
||||
[HttpHead("{itemId}/stream.{container}", Name = "HeadAudioStreamByContainer")]
|
||||
[HttpHead("{itemId}/stream", Name = "HeadAudioStream")]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public async Task<ActionResult> GetAudioStream(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Constants;
|
||||
using Jellyfin.Api.Extensions;
|
||||
using Jellyfin.Api.Helpers;
|
||||
@@ -51,7 +52,7 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <returns>A <see cref="CollectionCreationOptions"/> with information about the new collection.</returns>
|
||||
[HttpPost]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
public ActionResult<CollectionCreationResult> CreateCollection(
|
||||
public async Task<ActionResult<CollectionCreationResult>> CreateCollection(
|
||||
[FromQuery] string? name,
|
||||
[FromQuery] string? ids,
|
||||
[FromQuery] Guid? parentId,
|
||||
@@ -59,14 +60,14 @@ namespace Jellyfin.Api.Controllers
|
||||
{
|
||||
var userId = _authContext.GetAuthorizationInfo(Request).UserId;
|
||||
|
||||
var item = _collectionManager.CreateCollection(new CollectionCreationOptions
|
||||
var item = await _collectionManager.CreateCollectionAsync(new CollectionCreationOptions
|
||||
{
|
||||
IsLocked = isLocked,
|
||||
Name = name,
|
||||
ParentId = parentId,
|
||||
ItemIdList = RequestHelpers.Split(ids, ',', true),
|
||||
UserIds = new[] { userId }
|
||||
});
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var dtoOptions = new DtoOptions().AddClientFields(Request);
|
||||
|
||||
@@ -87,9 +88,9 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
|
||||
[HttpPost("{collectionId}/Items")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult AddToCollection([FromRoute] Guid collectionId, [FromQuery, Required] string? itemIds)
|
||||
public async Task<ActionResult> AddToCollection([FromRoute] Guid collectionId, [FromQuery, Required] string? itemIds)
|
||||
{
|
||||
_collectionManager.AddToCollection(collectionId, RequestHelpers.Split(itemIds, ',', true));
|
||||
await _collectionManager.AddToCollectionAsync(collectionId, RequestHelpers.GetGuids(itemIds)).ConfigureAwait(true);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
@@ -102,9 +103,9 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
|
||||
[HttpDelete("{collectionId}/Items")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult RemoveFromCollection([FromRoute] Guid collectionId, [FromQuery, Required] string? itemIds)
|
||||
public async Task<ActionResult> RemoveFromCollection([FromRoute] Guid collectionId, [FromQuery, Required] string? itemIds)
|
||||
{
|
||||
_collectionManager.RemoveFromCollection(collectionId, RequestHelpers.Split(itemIds, ',', true));
|
||||
await _collectionManager.RemoveFromCollectionAsync(collectionId, RequestHelpers.GetGuids(itemIds)).ConfigureAwait(false);
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ namespace Jellyfin.Api.Controllers
|
||||
[HttpPost("MediaEncoder/Path")]
|
||||
[Authorize(Policy = Policies.FirstTimeSetupOrElevated)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult UpdateMediaEncoderPath([FromForm, Required] MediaEncoderPathDto mediaEncoderPath)
|
||||
public ActionResult UpdateMediaEncoderPath([FromBody, Required] MediaEncoderPathDto mediaEncoderPath)
|
||||
{
|
||||
_mediaEncoder.UpdateEncoderPath(mediaEncoderPath.Path, mediaEncoderPath.PathType);
|
||||
return NoContent();
|
||||
|
||||
@@ -221,9 +221,8 @@ namespace Jellyfin.Api.Controllers
|
||||
|
||||
private Task<ControlResponse> ProcessControlRequestInternalAsync(string id, Stream requestStream, IUpnpService service)
|
||||
{
|
||||
return service.ProcessControlRequestAsync(new ControlRequest
|
||||
return service.ProcessControlRequestAsync(new ControlRequest(Request.Headers)
|
||||
{
|
||||
Headers = Request.Headers,
|
||||
InputXml = requestStream,
|
||||
TargetServerUuId = id,
|
||||
RequestedUrl = GetAbsoluteUri()
|
||||
|
||||
@@ -1356,7 +1356,7 @@ namespace Jellyfin.Api.Controllers
|
||||
|
||||
return string.Format(
|
||||
CultureInfo.InvariantCulture,
|
||||
"{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -copyts -avoid_negative_ts disabled -f hls -max_delay 5000000 -hls_time {6} -individual_header_trailer 0 -hls_segment_type {7} -start_number {8} -hls_segment_filename \"{9}\" -hls_playlist_type vod -hls_list_size 0 -y \"{10}\"",
|
||||
"{0} {1} -map_metadata -1 -map_chapters -1 -threads {2} {3} {4} {5} -copyts -avoid_negative_ts disabled -max_muxing_queue_size 2048 -f hls -max_delay 5000000 -hls_time {6} -individual_header_trailer 0 -hls_segment_type {7} -start_number {8} -hls_segment_filename \"{9}\" -hls_playlist_type vod -hls_list_size 0 -y \"{10}\"",
|
||||
inputModifier,
|
||||
_encodingHelper.GetInputArgument(state, encodingOptions),
|
||||
threads,
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace Jellyfin.Api.Controllers
|
||||
user.ProfileImage = new Data.Entities.ImageInfo(Path.Combine(userDataPath, "profile" + MimeTypes.ToExtension(mimeType)));
|
||||
|
||||
await _providerManager
|
||||
.SaveImage(user, memoryStream, mimeType, user.ProfileImage.Path)
|
||||
.SaveImage(memoryStream, mimeType, user.ProfileImage.Path)
|
||||
.ConfigureAwait(false);
|
||||
await _userManager.UpdateUserAsync(user).ConfigureAwait(false);
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace Jellyfin.Api.Controllers
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult DeleteItemImage(
|
||||
public async Task<ActionResult> DeleteItemImage(
|
||||
[FromRoute] Guid itemId,
|
||||
[FromRoute] ImageType imageType,
|
||||
[FromRoute] int? imageIndex = null)
|
||||
@@ -185,7 +185,7 @@ namespace Jellyfin.Api.Controllers
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
item.DeleteImage(imageType, imageIndex ?? 0);
|
||||
await item.DeleteImageAsync(imageType, imageIndex ?? 0).ConfigureAwait(false);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace Jellyfin.Api.Controllers
|
||||
// Handle image/png; charset=utf-8
|
||||
var mimeType = Request.ContentType.Split(';').FirstOrDefault();
|
||||
await _providerManager.SaveImage(item, Request.Body, mimeType, imageType, null, CancellationToken.None).ConfigureAwait(false);
|
||||
item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
|
||||
await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
@@ -237,7 +237,7 @@ namespace Jellyfin.Api.Controllers
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult UpdateItemImageIndex(
|
||||
public async Task<ActionResult> UpdateItemImageIndex(
|
||||
[FromRoute] Guid itemId,
|
||||
[FromRoute] ImageType imageType,
|
||||
[FromRoute] int imageIndex,
|
||||
@@ -249,7 +249,7 @@ namespace Jellyfin.Api.Controllers
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
item.SwapImages(imageType, imageIndex, newIndex);
|
||||
await item.SwapImagesAsync(imageType, imageIndex, newIndex).ConfigureAwait(false);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace Jellyfin.Api.Controllers
|
||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult<IEnumerable<ImageInfo>> GetItemImageInfos([FromRoute] Guid itemId)
|
||||
public async Task<ActionResult<IEnumerable<ImageInfo>>> GetItemImageInfos([FromRoute] Guid itemId)
|
||||
{
|
||||
var item = _libraryManager.GetItemById(itemId);
|
||||
if (item == null)
|
||||
@@ -281,7 +281,7 @@ namespace Jellyfin.Api.Controllers
|
||||
return list;
|
||||
}
|
||||
|
||||
_libraryManager.UpdateImages(item); // this makes sure dimensions and hashes are correct
|
||||
await _libraryManager.UpdateImagesAsync(item).ConfigureAwait(false); // this makes sure dimensions and hashes are correct
|
||||
|
||||
foreach (var image in itemImages)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Constants;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
@@ -67,7 +68,7 @@ namespace Jellyfin.Api.Controllers
|
||||
[HttpPost("Items/{itemId}")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult UpdateItem([FromRoute] Guid itemId, [FromBody, Required] BaseItemDto request)
|
||||
public async Task<ActionResult> UpdateItem([FromRoute] Guid itemId, [FromBody, Required] BaseItemDto request)
|
||||
{
|
||||
var item = _libraryManager.GetItemById(itemId);
|
||||
if (item == null)
|
||||
@@ -101,7 +102,7 @@ namespace Jellyfin.Api.Controllers
|
||||
|
||||
item.OnMetadataChanged();
|
||||
|
||||
item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
|
||||
await item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
if (isLockedChanged && item.IsFolder)
|
||||
{
|
||||
@@ -110,7 +111,7 @@ namespace Jellyfin.Api.Controllers
|
||||
foreach (var child in folder.GetRecursiveChildren())
|
||||
{
|
||||
child.IsLocked = newLockData;
|
||||
child.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
|
||||
await child.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -269,9 +269,9 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
|
||||
[HttpPost("LiveStreams/Close")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult CloseLiveStream([FromQuery, Required] string? liveStreamId)
|
||||
public async Task<ActionResult> CloseLiveStream([FromQuery, Required] string? liveStreamId)
|
||||
{
|
||||
_mediaSourceManager.CloseLiveStream(liveStreamId).GetAwaiter().GetResult();
|
||||
await _mediaSourceManager.CloseLiveStream(liveStreamId).ConfigureAwait(false);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
@@ -83,12 +83,12 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <returns>An <see cref="NoContentResult"/> on success.</returns>
|
||||
[HttpPost("{playlistId}/Items")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult AddToPlaylist(
|
||||
[FromRoute] string? playlistId,
|
||||
public async Task<ActionResult> AddToPlaylist(
|
||||
[FromRoute] Guid playlistId,
|
||||
[FromQuery] string? ids,
|
||||
[FromQuery] Guid? userId)
|
||||
{
|
||||
_playlistManager.AddToPlaylist(playlistId, RequestHelpers.GetGuids(ids), userId ?? Guid.Empty);
|
||||
await _playlistManager.AddToPlaylistAsync(playlistId, RequestHelpers.GetGuids(ids), userId ?? Guid.Empty).ConfigureAwait(false);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
@@ -102,12 +102,12 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <returns>An <see cref="NoContentResult"/> on success.</returns>
|
||||
[HttpPost("{playlistId}/Items/{itemId}/Move/{newIndex}")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult MoveItem(
|
||||
public async Task<ActionResult> MoveItem(
|
||||
[FromRoute] string? playlistId,
|
||||
[FromRoute] string? itemId,
|
||||
[FromRoute] int newIndex)
|
||||
{
|
||||
_playlistManager.MoveItem(playlistId, itemId, newIndex);
|
||||
await _playlistManager.MoveItemAsync(playlistId, itemId, newIndex).ConfigureAwait(false);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
@@ -120,9 +120,9 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <returns>An <see cref="NoContentResult"/> on success.</returns>
|
||||
[HttpDelete("{playlistId}/Items")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult RemoveFromPlaylist([FromRoute] string? playlistId, [FromQuery] string? entryIds)
|
||||
public async Task<ActionResult> RemoveFromPlaylist([FromRoute] string? playlistId, [FromQuery] string? entryIds)
|
||||
{
|
||||
_playlistManager.RemoveFromPlaylist(playlistId, RequestHelpers.Split(entryIds, ',', true));
|
||||
await _playlistManager.RemoveFromPlaylistAsync(playlistId, RequestHelpers.Split(entryIds, ',', true)).ConfigureAwait(false);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace Jellyfin.Api.Controllers
|
||||
await _providerManager.SaveImage(item, imageUrl, type, null, CancellationToken.None)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None);
|
||||
await item.UpdateToRepositoryAsync(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
@@ -153,7 +153,6 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <param name="itemIds">The ids of the items to play, comma delimited.</param>
|
||||
/// <param name="startPositionTicks">The starting position of the first item.</param>
|
||||
/// <param name="playCommand">The type of play command to issue (PlayNow, PlayNext, PlayLast). Clients who have not yet implemented play next and play last may play now.</param>
|
||||
/// <param name="playRequest">The <see cref="PlayRequest"/>.</param>
|
||||
/// <response code="204">Instruction sent to session.</response>
|
||||
/// <returns>A <see cref="NoContentResult"/>.</returns>
|
||||
[HttpPost("Sessions/{sessionId}/Playing")]
|
||||
@@ -163,17 +162,14 @@ namespace Jellyfin.Api.Controllers
|
||||
[FromRoute, Required] string? sessionId,
|
||||
[FromQuery] Guid[] itemIds,
|
||||
[FromQuery] long? startPositionTicks,
|
||||
[FromQuery] PlayCommand playCommand,
|
||||
[FromBody, Required] PlayRequest playRequest)
|
||||
[FromQuery] PlayCommand playCommand)
|
||||
{
|
||||
if (playRequest == null)
|
||||
var playRequest = new PlayRequest
|
||||
{
|
||||
throw new ArgumentException("Request Body may not be null");
|
||||
}
|
||||
|
||||
playRequest.ItemIds = itemIds;
|
||||
playRequest.StartPositionTicks = startPositionTicks;
|
||||
playRequest.PlayCommand = playCommand;
|
||||
ItemIds = itemIds,
|
||||
StartPositionTicks = startPositionTicks,
|
||||
PlayCommand = playCommand
|
||||
};
|
||||
|
||||
_sessionManager.SendPlayCommand(
|
||||
RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Jellyfin.Api.Constants;
|
||||
@@ -64,21 +65,16 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <summary>
|
||||
/// Sets the initial startup wizard configuration.
|
||||
/// </summary>
|
||||
/// <param name="uiCulture">The UI language culture.</param>
|
||||
/// <param name="metadataCountryCode">The metadata country code.</param>
|
||||
/// <param name="preferredMetadataLanguage">The preferred language for metadata.</param>
|
||||
/// <param name="startupConfiguration">The updated startup configuration.</param>
|
||||
/// <response code="204">Configuration saved.</response>
|
||||
/// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
|
||||
[HttpPost("Configuration")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult UpdateInitialConfiguration(
|
||||
[FromForm] string? uiCulture,
|
||||
[FromForm] string? metadataCountryCode,
|
||||
[FromForm] string? preferredMetadataLanguage)
|
||||
public ActionResult UpdateInitialConfiguration([FromBody, Required] StartupConfigurationDto startupConfiguration)
|
||||
{
|
||||
_config.Configuration.UICulture = uiCulture;
|
||||
_config.Configuration.MetadataCountryCode = metadataCountryCode;
|
||||
_config.Configuration.PreferredMetadataLanguage = preferredMetadataLanguage;
|
||||
_config.Configuration.UICulture = startupConfiguration.UICulture;
|
||||
_config.Configuration.MetadataCountryCode = startupConfiguration.MetadataCountryCode;
|
||||
_config.Configuration.PreferredMetadataLanguage = startupConfiguration.PreferredMetadataLanguage;
|
||||
_config.SaveConfiguration();
|
||||
return NoContent();
|
||||
}
|
||||
@@ -86,16 +82,15 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <summary>
|
||||
/// Sets remote access and UPnP.
|
||||
/// </summary>
|
||||
/// <param name="enableRemoteAccess">Enable remote access.</param>
|
||||
/// <param name="enableAutomaticPortMapping">Enable UPnP.</param>
|
||||
/// <param name="startupRemoteAccessDto">The startup remote access dto.</param>
|
||||
/// <response code="204">Configuration saved.</response>
|
||||
/// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
|
||||
[HttpPost("RemoteAccess")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult SetRemoteAccess([FromForm] bool enableRemoteAccess, [FromForm] bool enableAutomaticPortMapping)
|
||||
public ActionResult SetRemoteAccess([FromBody, Required] StartupRemoteAccessDto startupRemoteAccessDto)
|
||||
{
|
||||
_config.Configuration.EnableRemoteAccess = enableRemoteAccess;
|
||||
_config.Configuration.EnableUPnP = enableAutomaticPortMapping;
|
||||
_config.Configuration.EnableRemoteAccess = startupRemoteAccessDto.EnableRemoteAccess;
|
||||
_config.Configuration.EnableUPnP = startupRemoteAccessDto.EnableAutomaticPortMapping;
|
||||
_config.SaveConfiguration();
|
||||
return NoContent();
|
||||
}
|
||||
@@ -131,7 +126,7 @@ namespace Jellyfin.Api.Controllers
|
||||
/// </returns>
|
||||
[HttpPost("User")]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public async Task<ActionResult> UpdateStartupUser([FromForm] StartupUserDto startupUserDto)
|
||||
public async Task<ActionResult> UpdateStartupUser([FromBody] StartupUserDto startupUserDto)
|
||||
{
|
||||
var user = _userManager.Users.First();
|
||||
|
||||
|
||||
@@ -85,9 +85,9 @@ namespace Jellyfin.Api.Controllers
|
||||
/// <response code="302">Redirected to remote audio stream.</response>
|
||||
/// <returns>A <see cref="Task"/> containing the audio file.</returns>
|
||||
[HttpGet("Audio/{itemId}/universal")]
|
||||
[HttpGet("Audio/{itemId}/{universal=universal}.{container?}", Name = "GetUniversalAudioStream_2")]
|
||||
[HttpGet("Audio/{itemId}/universal.{container}", Name = "GetUniversalAudioStream_2")]
|
||||
[HttpHead("Audio/{itemId}/universal", Name = "HeadUniversalAudioStream")]
|
||||
[HttpHead("Audio/{itemId}/{universal=universal}.{container?}", Name = "HeadUniversalAudioStream_2")]
|
||||
[HttpHead("Audio/{itemId}/universal.{container}", Name = "HeadUniversalAudioStream_2")]
|
||||
[Authorize(Policy = Policies.DefaultAuthorization)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status302Found)]
|
||||
|
||||
@@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public ActionResult DeleteAlternateSources([FromRoute] Guid itemId)
|
||||
public async Task<ActionResult> DeleteAlternateSources([FromRoute] Guid itemId)
|
||||
{
|
||||
var video = (Video)_libraryManager.GetItemById(itemId);
|
||||
|
||||
@@ -180,12 +180,12 @@ namespace Jellyfin.Api.Controllers
|
||||
link.SetPrimaryVersionId(null);
|
||||
link.LinkedAlternateVersions = Array.Empty<LinkedChild>();
|
||||
|
||||
link.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
|
||||
await link.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
video.LinkedAlternateVersions = Array.Empty<LinkedChild>();
|
||||
video.SetPrimaryVersionId(null);
|
||||
video.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
|
||||
await video.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
@@ -201,7 +201,7 @@ namespace Jellyfin.Api.Controllers
|
||||
[Authorize(Policy = Policies.RequiresElevation)]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||
public ActionResult MergeVersions([FromQuery, Required] string? itemIds)
|
||||
public async Task<ActionResult> MergeVersions([FromQuery, Required] string? itemIds)
|
||||
{
|
||||
var items = RequestHelpers.Split(itemIds, ',', true)
|
||||
.Select(i => _libraryManager.GetItemById(i))
|
||||
@@ -239,7 +239,7 @@ namespace Jellyfin.Api.Controllers
|
||||
{
|
||||
item.SetPrimaryVersionId(primaryVersion.Id.ToString("N", CultureInfo.InvariantCulture));
|
||||
|
||||
item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
|
||||
await item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
list.Add(new LinkedChild
|
||||
{
|
||||
@@ -258,12 +258,12 @@ namespace Jellyfin.Api.Controllers
|
||||
if (item.LinkedAlternateVersions.Length > 0)
|
||||
{
|
||||
item.LinkedAlternateVersions = Array.Empty<LinkedChild>();
|
||||
item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
|
||||
await item.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
primaryVersion.LinkedAlternateVersions = list.ToArray();
|
||||
primaryVersion.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
|
||||
await primaryVersion.UpdateToRepositoryAsync(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user