mirror of
https://github.com/jellyfin/jellyfin.git
synced 2025-08-06 06:07:05 +02:00
Fix MaxActiveVideoStreams limit check to prevent transcoding before validation
Move video stream limit validation from SessionManager.OnPlaybackStart() to DynamicHlsController.GetLiveHlsStream() before transcoding starts. This prevents FFmpeg processes from starting when users exceed their concurrent video stream limits.
This commit is contained in:
parent
22783bbff1
commit
03125c8904
@ -755,27 +755,6 @@ namespace Emby.Server.Implementations.Session
|
||||
? null
|
||||
: GetNowPlayingItem(session, info.ItemId);
|
||||
|
||||
// Check video stream limits before allowing playback
|
||||
if (libraryItem?.MediaType == MediaType.Video)
|
||||
{
|
||||
var sessionUsers = GetUsers(session);
|
||||
foreach (var user in sessionUsers)
|
||||
{
|
||||
if (user.MaxActiveVideoStreams > 0)
|
||||
{
|
||||
var activeVideoStreams = Sessions.Count(s =>
|
||||
s.UserId.Equals(user.Id) &&
|
||||
s.NowPlayingItem?.MediaType == MediaType.Video);
|
||||
|
||||
_logger.LogInformation("Current/Max video streams for user {User}: {VideoStreams}/{MaxVideoStreams}", user.Username, activeVideoStreams, user.MaxActiveVideoStreams);
|
||||
if (activeVideoStreams >= user.MaxActiveVideoStreams)
|
||||
{
|
||||
throw new MediaBrowser.Controller.Net.SecurityException($"User '{user.Username}' has reached their maximum number of concurrent video streams ({user.MaxActiveVideoStreams}).");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await UpdateNowPlayingItem(session, info, libraryItem, true).ConfigureAwait(false);
|
||||
|
||||
if (!string.IsNullOrEmpty(session.DeviceId) && info.PlayMethod != PlayMethod.Transcode)
|
||||
|
@ -19,6 +19,7 @@ using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.MediaEncoding;
|
||||
using MediaBrowser.Controller.Session;
|
||||
using MediaBrowser.Controller.Streaming;
|
||||
using MediaBrowser.MediaEncoding.Encoder;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
@ -60,6 +61,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
private readonly IDynamicHlsPlaylistGenerator _dynamicHlsPlaylistGenerator;
|
||||
private readonly DynamicHlsHelper _dynamicHlsHelper;
|
||||
private readonly EncodingOptions _encodingOptions;
|
||||
private readonly ISessionManager _sessionManager;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DynamicHlsController"/> class.
|
||||
@ -75,6 +77,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
/// <param name="dynamicHlsHelper">Instance of <see cref="DynamicHlsHelper"/>.</param>
|
||||
/// <param name="encodingHelper">Instance of <see cref="EncodingHelper"/>.</param>
|
||||
/// <param name="dynamicHlsPlaylistGenerator">Instance of <see cref="IDynamicHlsPlaylistGenerator"/>.</param>
|
||||
/// <param name="sessionManager">Instance of the <see cref="ISessionManager"/> interface.</param>
|
||||
public DynamicHlsController(
|
||||
ILibraryManager libraryManager,
|
||||
IUserManager userManager,
|
||||
@ -86,7 +89,8 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
ILogger<DynamicHlsController> logger,
|
||||
DynamicHlsHelper dynamicHlsHelper,
|
||||
EncodingHelper encodingHelper,
|
||||
IDynamicHlsPlaylistGenerator dynamicHlsPlaylistGenerator)
|
||||
IDynamicHlsPlaylistGenerator dynamicHlsPlaylistGenerator,
|
||||
ISessionManager sessionManager)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_userManager = userManager;
|
||||
@ -99,6 +103,7 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
_dynamicHlsHelper = dynamicHlsHelper;
|
||||
_encodingHelper = encodingHelper;
|
||||
_dynamicHlsPlaylistGenerator = dynamicHlsPlaylistGenerator;
|
||||
_sessionManager = sessionManager;
|
||||
|
||||
_encodingOptions = serverConfigurationManager.GetEncodingOptions();
|
||||
}
|
||||
@ -297,6 +302,28 @@ public class DynamicHlsController : BaseJellyfinApiController
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// Check video stream limits before starting transcoding
|
||||
if (state.MediaSource?.VideoType is not null)
|
||||
{
|
||||
var userId = HttpContext.User.GetUserId();
|
||||
if (!userId.IsEmpty())
|
||||
{
|
||||
var user = _userManager.GetUserById(userId);
|
||||
if (user is not null && user.MaxActiveVideoStreams > 0)
|
||||
{
|
||||
var activeVideoStreams = _sessionManager.Sessions.Count(s =>
|
||||
s.UserId.Equals(user.Id) &&
|
||||
s.NowPlayingItem?.MediaType == MediaType.Video);
|
||||
|
||||
_logger.LogInformation("Current/Max video streams for user {User}: {VideoStreams}/{MaxVideoStreams}", user.Username, activeVideoStreams, user.MaxActiveVideoStreams);
|
||||
if (activeVideoStreams >= user.MaxActiveVideoStreams)
|
||||
{
|
||||
throw new MediaBrowser.Controller.Net.SecurityException($"User '{user.Username}' has reached their maximum number of concurrent video streams ({user.MaxActiveVideoStreams}).");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TranscodingJob? job = null;
|
||||
var playlistPath = Path.ChangeExtension(state.OutputFilePath, ".m3u8");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user