@ -81,6 +81,9 @@ namespace Jellyfin.Api.Controllers
/// <summary>
/// <summary>
/// Gets live playback media info for an item.
/// Gets live playback media info for an item.
/// </summary>
/// </summary>
/// <remarks>
/// For backwards compatibility parameters can be sent via Query or Body, with Query having higher precedence.
/// </remarks>
/// <param name="itemId">The item id.</param>
/// <param name="itemId">The item id.</param>
/// <param name="userId">The user id.</param>
/// <param name="userId">The user id.</param>
/// <param name="maxStreamingBitrate">The maximum streaming bitrate.</param>
/// <param name="maxStreamingBitrate">The maximum streaming bitrate.</param>
@ -90,13 +93,13 @@ namespace Jellyfin.Api.Controllers
/// <param name="maxAudioChannels">The maximum number of audio channels.</param>
/// <param name="maxAudioChannels">The maximum number of audio channels.</param>
/// <param name="mediaSourceId">The media source id.</param>
/// <param name="mediaSourceId">The media source id.</param>
/// <param name="liveStreamId">The livestream id.</param>
/// <param name="liveStreamId">The livestream id.</param>
/// <param name="deviceProfile">The device profile.</param>
/// <param name="autoOpenLiveStream">Whether to auto open the livestream.</param>
/// <param name="autoOpenLiveStream">Whether to auto open the livestream.</param>
/// <param name="enableDirectPlay">Whether to enable direct play. Default: true.</param>
/// <param name="enableDirectPlay">Whether to enable direct play. Default: true.</param>
/// <param name="enableDirectStream">Whether to enable direct stream. Default: true.</param>
/// <param name="enableDirectStream">Whether to enable direct stream. Default: true.</param>
/// <param name="enableTranscoding">Whether to enable transcoding. Default: true.</param>
/// <param name="enableTranscoding">Whether to enable transcoding. Default: true.</param>
/// <param name="allowVideoStreamCopy">Whether to allow to copy the video stream. Default: true.</param>
/// <param name="allowVideoStreamCopy">Whether to allow to copy the video stream. Default: true.</param>
/// <param name="allowAudioStreamCopy">Whether to allow to copy the audio stream. Default: true.</param>
/// <param name="allowAudioStreamCopy">Whether to allow to copy the audio stream. Default: true.</param>
/// <param name="playbackInfoDto">The playback info.</param>
/// <response code="200">Playback info returned.</response>
/// <response code="200">Playback info returned.</response>
/// <returns>A <see cref="Task"/> containing a <see cref="PlaybackInfoResponse"/> with the playback info.</returns>
/// <returns>A <see cref="Task"/> containing a <see cref="PlaybackInfoResponse"/> with the playback info.</returns>
[HttpPost("Items/{itemId}/PlaybackInfo")]
[HttpPost("Items/{itemId}/PlaybackInfo")]
@ -111,18 +114,17 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? maxAudioChannels ,
[FromQuery] int? maxAudioChannels ,
[FromQuery] string? mediaSourceId ,
[FromQuery] string? mediaSourceId ,
[FromQuery] string? liveStreamId ,
[FromQuery] string? liveStreamId ,
[From Body] DeviceProfileDto ? deviceProfile ,
[From Query] bool? autoOpenLiveStream ,
[FromQuery] bool autoOpenLiveStream = false ,
[FromQuery] bool ? enableDirectPlay ,
[FromQuery] bool enableDirectPlay = true ,
[FromQuery] bool ? enableDirectStream ,
[FromQuery] bool enableDirectStream = true ,
[FromQuery] bool ? enableTranscoding ,
[FromQuery] bool enableTranscoding = true ,
[FromQuery] bool ? allowVideoStreamCopy ,
[FromQuery] bool allowVideoStreamCopy = true ,
[FromQuery] bool ? allowAudioStreamCopy ,
[From Query] bool allowAudioStreamCopy = true )
[From Body] PlaybackInfoDto ? playbackInfoDto )
{
{
var authInfo = _authContext . GetAuthorizationInfo ( Request ) ;
var authInfo = _authContext . GetAuthorizationInfo ( Request ) ;
var profile = deviceProfile ? . DeviceProfile ;
var profile = playbackInfoDto ? . DeviceProfile ? . DeviceProfile ;
_logger . LogInformation ( "GetPostedPlaybackInfo profile: {@Profile}" , profile ) ;
_logger . LogInformation ( "GetPostedPlaybackInfo profile: {@Profile}" , profile ) ;
if ( profile = = null )
if ( profile = = null )
@ -134,6 +136,22 @@ namespace Jellyfin.Api.Controllers
}
}
}
}
// Copy params from posted body
userId ? ? = playbackInfoDto ? . UserId ;
maxStreamingBitrate ? ? = playbackInfoDto ? . MaxStreamingBitrate ;
startTimeTicks ? ? = playbackInfoDto ? . StartTimeTicks ;
audioStreamIndex ? ? = playbackInfoDto ? . AudioStreamIndex ;
subtitleStreamIndex ? ? = playbackInfoDto ? . SubtitleStreamIndex ;
maxAudioChannels ? ? = playbackInfoDto ? . MaxAudioChannels ;
mediaSourceId ? ? = playbackInfoDto ? . MediaSourceId ;
liveStreamId ? ? = playbackInfoDto ? . LiveStreamId ;
autoOpenLiveStream ? ? = playbackInfoDto ? . AutoOpenLiveStream ? ? false ;
enableDirectPlay ? ? = playbackInfoDto ? . EnableDirectPlay ? ? true ;
enableDirectStream ? ? = playbackInfoDto ? . EnableDirectStream ? ? true ;
enableTranscoding ? ? = playbackInfoDto ? . EnableTranscoding ? ? true ;
allowVideoStreamCopy ? ? = playbackInfoDto ? . AllowVideoStreamCopy ? ? true ;
allowAudioStreamCopy ? ? = playbackInfoDto ? . AllowAudioStreamCopy ? ? true ;
var info = await _mediaInfoHelper . GetPlaybackInfo (
var info = await _mediaInfoHelper . GetPlaybackInfo (
itemId ,
itemId ,
userId ,
userId ,
@ -161,18 +179,18 @@ namespace Jellyfin.Api.Controllers
maxAudioChannels ,
maxAudioChannels ,
info ! . PlaySessionId ! ,
info ! . PlaySessionId ! ,
userId ? ? Guid . Empty ,
userId ? ? Guid . Empty ,
enableDirectPlay ,
enableDirectPlay .Value ,
enableDirectStream ,
enableDirectStream .Value ,
enableTranscoding ,
enableTranscoding .Value ,
allowVideoStreamCopy ,
allowVideoStreamCopy .Value ,
allowAudioStreamCopy ,
allowAudioStreamCopy .Value ,
Request . HttpContext . GetNormalizedRemoteIp ( ) ) ;
Request . HttpContext . GetNormalizedRemoteIp ( ) ) ;
}
}
_mediaInfoHelper . SortMediaSources ( info , maxStreamingBitrate ) ;
_mediaInfoHelper . SortMediaSources ( info , maxStreamingBitrate ) ;
}
}
if ( autoOpenLiveStream )
if ( autoOpenLiveStream .Value )
{
{
var mediaSource = string . IsNullOrWhiteSpace ( mediaSourceId ) ? info . MediaSources [ 0 ] : info . MediaSources . FirstOrDefault ( i = > string . Equals ( i . Id , mediaSourceId , StringComparison . Ordinal ) ) ;
var mediaSource = string . IsNullOrWhiteSpace ( mediaSourceId ) ? info . MediaSources [ 0 ] : info . MediaSources . FirstOrDefault ( i = > string . Equals ( i . Id , mediaSourceId , StringComparison . Ordinal ) ) ;
@ -183,9 +201,9 @@ namespace Jellyfin.Api.Controllers
new LiveStreamRequest
new LiveStreamRequest
{
{
AudioStreamIndex = audioStreamIndex ,
AudioStreamIndex = audioStreamIndex ,
DeviceProfile = d eviceProfile? . DeviceProfile ,
DeviceProfile = playbackInfoDto? . D eviceProfile? . DeviceProfile ,
EnableDirectPlay = enableDirectPlay ,
EnableDirectPlay = enableDirectPlay .Value ,
EnableDirectStream = enableDirectStream ,
EnableDirectStream = enableDirectStream .Value ,
ItemId = itemId ,
ItemId = itemId ,
MaxAudioChannels = maxAudioChannels ,
MaxAudioChannels = maxAudioChannels ,
MaxStreamingBitrate = maxStreamingBitrate ,
MaxStreamingBitrate = maxStreamingBitrate ,