aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Api
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Api')
-rw-r--r--Jellyfin.Api/Controllers/ChannelsController.cs6
-rw-r--r--Jellyfin.Api/Controllers/DynamicHlsController.cs43
-rw-r--r--Jellyfin.Api/Controllers/ItemUpdateController.cs5
-rw-r--r--Jellyfin.Api/Controllers/LiveTvController.cs10
-rw-r--r--Jellyfin.Api/Helpers/DynamicHlsHelper.cs13
-rw-r--r--Jellyfin.Api/Helpers/StreamingHelpers.cs16
-rw-r--r--Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs4
7 files changed, 68 insertions, 29 deletions
diff --git a/Jellyfin.Api/Controllers/ChannelsController.cs b/Jellyfin.Api/Controllers/ChannelsController.cs
index b5c4d8346..11c4ac376 100644
--- a/Jellyfin.Api/Controllers/ChannelsController.cs
+++ b/Jellyfin.Api/Controllers/ChannelsController.cs
@@ -52,7 +52,7 @@ public class ChannelsController : BaseJellyfinApiController
/// <returns>An <see cref="OkResult"/> containing the channels.</returns>
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
- public ActionResult<QueryResult<BaseItemDto>> GetChannels(
+ public async Task<ActionResult<QueryResult<BaseItemDto>>> GetChannels(
[FromQuery] Guid? userId,
[FromQuery] int? startIndex,
[FromQuery] int? limit,
@@ -61,7 +61,7 @@ public class ChannelsController : BaseJellyfinApiController
[FromQuery] bool? isFavorite)
{
userId = RequestHelpers.GetUserId(User, userId);
- return _channelManager.GetChannels(new ChannelQuery
+ return await _channelManager.GetChannelsAsync(new ChannelQuery
{
Limit = limit,
StartIndex = startIndex,
@@ -69,7 +69,7 @@ public class ChannelsController : BaseJellyfinApiController
SupportsLatestItems = supportsLatestItems,
SupportsMediaDeletion = supportsMediaDeletion,
IsFavorite = isFavorite
- });
+ }).ConfigureAwait(false);
}
/// <summary>
diff --git a/Jellyfin.Api/Controllers/DynamicHlsController.cs b/Jellyfin.Api/Controllers/DynamicHlsController.cs
index 16c77a923..42a7ac2b1 100644
--- a/Jellyfin.Api/Controllers/DynamicHlsController.cs
+++ b/Jellyfin.Api/Controllers/DynamicHlsController.cs
@@ -12,6 +12,7 @@ using Jellyfin.Api.Attributes;
using Jellyfin.Api.Helpers;
using Jellyfin.Api.Models.PlaybackDtos;
using Jellyfin.Api.Models.StreamingDtos;
+using Jellyfin.Extensions;
using Jellyfin.MediaEncoding.Hls.Playlist;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Configuration;
@@ -1687,14 +1688,25 @@ public class DynamicHlsController : BaseJellyfinApiController
audioTranscodeParams += "-acodec " + audioCodec;
- if (state.OutputAudioBitrate.HasValue)
+ var audioBitrate = state.OutputAudioBitrate;
+ var audioChannels = state.OutputAudioChannels;
+
+ if (audioBitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(state.ActualOutputAudioCodec, StringComparison.OrdinalIgnoreCase))
{
- audioTranscodeParams += " -ab " + state.OutputAudioBitrate.Value.ToString(CultureInfo.InvariantCulture);
+ var vbrParam = _encodingHelper.GetAudioVbrModeParam(audioCodec, audioBitrate.Value / (audioChannels ?? 2));
+ if (_encodingOptions.EnableAudioVbr && vbrParam is not null)
+ {
+ audioTranscodeParams += vbrParam;
+ }
+ else
+ {
+ audioTranscodeParams += " -ab " + audioBitrate.Value.ToString(CultureInfo.InvariantCulture);
+ }
}
- if (state.OutputAudioChannels.HasValue)
+ if (audioChannels.HasValue)
{
- audioTranscodeParams += " -ac " + state.OutputAudioChannels.Value.ToString(CultureInfo.InvariantCulture);
+ audioTranscodeParams += " -ac " + audioChannels.Value.ToString(CultureInfo.InvariantCulture);
}
if (state.OutputAudioSampleRate.HasValue)
@@ -1708,11 +1720,11 @@ public class DynamicHlsController : BaseJellyfinApiController
// dts, flac, opus and truehd are experimental in mp4 muxer
var strictArgs = string.Empty;
-
- if (string.Equals(state.ActualOutputAudioCodec, "flac", StringComparison.OrdinalIgnoreCase)
- || string.Equals(state.ActualOutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase)
- || string.Equals(state.ActualOutputAudioCodec, "dts", StringComparison.OrdinalIgnoreCase)
- || string.Equals(state.ActualOutputAudioCodec, "truehd", StringComparison.OrdinalIgnoreCase))
+ var actualOutputAudioCodec = state.ActualOutputAudioCodec;
+ if (string.Equals(actualOutputAudioCodec, "flac", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(actualOutputAudioCodec, "opus", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(actualOutputAudioCodec, "dts", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(actualOutputAudioCodec, "truehd", StringComparison.OrdinalIgnoreCase))
{
strictArgs = " -strict -2";
}
@@ -1746,10 +1758,17 @@ public class DynamicHlsController : BaseJellyfinApiController
}
var bitrate = state.OutputAudioBitrate;
-
- if (bitrate.HasValue)
+ if (bitrate.HasValue && !EncodingHelper.LosslessAudioCodecs.Contains(actualOutputAudioCodec, StringComparison.OrdinalIgnoreCase))
{
- args += " -ab " + bitrate.Value.ToString(CultureInfo.InvariantCulture);
+ var vbrParam = _encodingHelper.GetAudioVbrModeParam(audioCodec, bitrate.Value / (channels ?? 2));
+ if (_encodingOptions.EnableAudioVbr && vbrParam is not null)
+ {
+ args += vbrParam;
+ }
+ else
+ {
+ args += " -ab " + bitrate.Value.ToString(CultureInfo.InvariantCulture);
+ }
}
if (state.OutputAudioSampleRate.HasValue)
diff --git a/Jellyfin.Api/Controllers/ItemUpdateController.cs b/Jellyfin.Api/Controllers/ItemUpdateController.cs
index 9c7148241..ece053a9a 100644
--- a/Jellyfin.Api/Controllers/ItemUpdateController.cs
+++ b/Jellyfin.Api/Controllers/ItemUpdateController.cs
@@ -246,6 +246,11 @@ public class ItemUpdateController : BaseJellyfinApiController
episode.AirsBeforeSeasonNumber = request.AirsBeforeSeasonNumber;
}
+ if (request.Height is not null && item is LiveTvChannel channel)
+ {
+ channel.Height = request.Height.Value;
+ }
+
item.Tags = request.Tags;
if (request.Taglines is not null)
diff --git a/Jellyfin.Api/Controllers/LiveTvController.cs b/Jellyfin.Api/Controllers/LiveTvController.cs
index 96fc91f93..267ba4afb 100644
--- a/Jellyfin.Api/Controllers/LiveTvController.cs
+++ b/Jellyfin.Api/Controllers/LiveTvController.cs
@@ -252,7 +252,7 @@ public class LiveTvController : BaseJellyfinApiController
[HttpGet("Recordings")]
[ProducesResponseType(StatusCodes.Status200OK)]
[Authorize(Policy = Policies.LiveTvAccess)]
- public ActionResult<QueryResult<BaseItemDto>> GetRecordings(
+ public async Task<ActionResult<QueryResult<BaseItemDto>>> GetRecordings(
[FromQuery] string? channelId,
[FromQuery] Guid? userId,
[FromQuery] int? startIndex,
@@ -278,7 +278,7 @@ public class LiveTvController : BaseJellyfinApiController
.AddClientFields(User)
.AddAdditionalDtoOptions(enableImages, enableUserData, imageTypeLimit, enableImageTypes);
- return _liveTvManager.GetRecordings(
+ return await _liveTvManager.GetRecordingsAsync(
new RecordingQuery
{
ChannelId = channelId,
@@ -299,7 +299,7 @@ public class LiveTvController : BaseJellyfinApiController
ImageTypeLimit = imageTypeLimit,
EnableImages = enableImages
},
- dtoOptions);
+ dtoOptions).ConfigureAwait(false);
}
/// <summary>
@@ -383,13 +383,13 @@ public class LiveTvController : BaseJellyfinApiController
[HttpGet("Recordings/Folders")]
[ProducesResponseType(StatusCodes.Status200OK)]
[Authorize(Policy = Policies.LiveTvAccess)]
- public ActionResult<QueryResult<BaseItemDto>> GetRecordingFolders([FromQuery] Guid? userId)
+ public async Task<ActionResult<QueryResult<BaseItemDto>>> GetRecordingFolders([FromQuery] Guid? userId)
{
userId = RequestHelpers.GetUserId(User, userId);
var user = userId.Value.Equals(default)
? null
: _userManager.GetUserById(userId.Value);
- var folders = _liveTvManager.GetRecordingFolders(user);
+ var folders = await _liveTvManager.GetRecordingFoldersAsync(user).ConfigureAwait(false);
var returnArray = _dtoService.GetBaseItemDtos(folders, new DtoOptions(), user);
diff --git a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
index 245239233..4486954c6 100644
--- a/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
+++ b/Jellyfin.Api/Helpers/DynamicHlsHelper.cs
@@ -9,6 +9,7 @@ using System.Threading;
using System.Threading.Tasks;
using Jellyfin.Api.Extensions;
using Jellyfin.Api.Models.StreamingDtos;
+using Jellyfin.Extensions;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
@@ -223,9 +224,17 @@ public class DynamicHlsHelper
sdrVideoUrl += "&AllowVideoStreamCopy=false";
var sdrOutputVideoBitrate = _encodingHelper.GetVideoBitrateParamValue(state.VideoRequest, state.VideoStream, state.OutputVideoCodec);
- var sdrOutputAudioBitrate = _encodingHelper.GetAudioBitrateParam(state.VideoRequest, state.AudioStream) ?? 0;
- var sdrTotalBitrate = sdrOutputAudioBitrate + sdrOutputVideoBitrate;
+ var sdrOutputAudioBitrate = 0;
+ if (EncodingHelper.LosslessAudioCodecs.Contains(state.VideoRequest.AudioCodec, StringComparison.OrdinalIgnoreCase))
+ {
+ sdrOutputAudioBitrate = state.AudioStream.BitRate ?? 0;
+ }
+ else
+ {
+ sdrOutputAudioBitrate = _encodingHelper.GetAudioBitrateParam(state.VideoRequest, state.AudioStream, state.OutputAudioChannels) ?? 0;
+ }
+ var sdrTotalBitrate = sdrOutputAudioBitrate + sdrOutputVideoBitrate;
var sdrPlaylist = AppendPlaylist(builder, state, sdrVideoUrl, sdrTotalBitrate, subtitleGroup);
// Provide a workaround for the case issue between flac and fLaC.
diff --git a/Jellyfin.Api/Helpers/StreamingHelpers.cs b/Jellyfin.Api/Helpers/StreamingHelpers.cs
index 9b5a14c4d..9c91dcc6f 100644
--- a/Jellyfin.Api/Helpers/StreamingHelpers.cs
+++ b/Jellyfin.Api/Helpers/StreamingHelpers.cs
@@ -181,12 +181,18 @@ public static class StreamingHelpers
: GetOutputFileExtension(state, mediaSource);
}
- state.OutputContainer = (containerInternal ?? string.Empty).TrimStart('.');
-
- state.OutputAudioBitrate = encodingHelper.GetAudioBitrateParam(streamingRequest.AudioBitRate, streamingRequest.AudioCodec, state.AudioStream);
-
- state.OutputAudioCodec = streamingRequest.AudioCodec;
+ var outputAudioCodec = streamingRequest.AudioCodec;
+ if (EncodingHelper.LosslessAudioCodecs.Contains(outputAudioCodec))
+ {
+ state.OutputAudioBitrate = state.AudioStream.BitRate ?? 0;
+ }
+ else
+ {
+ state.OutputAudioBitrate = encodingHelper.GetAudioBitrateParam(streamingRequest.AudioBitRate, streamingRequest.AudioCodec, state.AudioStream, state.OutputAudioChannels) ?? 0;
+ }
+ state.OutputAudioCodec = outputAudioCodec;
+ state.OutputContainer = (containerInternal ?? string.Empty).TrimStart('.');
state.OutputAudioChannels = encodingHelper.GetNumAudioChannelsParam(state, state.AudioStream, state.OutputAudioCodec);
if (state.VideoRequest is not null)
diff --git a/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs b/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
index 3eac81419..4a5e0ecd4 100644
--- a/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
+++ b/Jellyfin.Api/WebSocketListeners/ActivityLogWebSocketListener.cs
@@ -56,8 +56,8 @@ public class ActivityLogWebSocketListener : BasePeriodicWebSocketListener<Activi
base.Dispose(dispose);
}
- private void OnEntryCreated(object? sender, GenericEventArgs<ActivityLogEntry> e)
+ private async void OnEntryCreated(object? sender, GenericEventArgs<ActivityLogEntry> e)
{
- SendData(true).GetAwaiter().GetResult();
+ await SendData(true).ConfigureAwait(false);
}
}