Merge pull request #7325 from eyezak/issue/6450

pull/7449/head
Cody Robibero 3 years ago committed by GitHub
commit e6df698df1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -126,7 +126,7 @@ namespace Jellyfin.Api.Controllers
var authInfo = await _authContext.GetAuthorizationInfo(Request).ConfigureAwait(false);
var profile = playbackInfoDto?.DeviceProfile;
_logger.LogInformation("GetPostedPlaybackInfo profile: {@Profile}", profile);
_logger.LogDebug("GetPostedPlaybackInfo profile: {@Profile}", profile);
if (profile == null)
{
@ -225,14 +225,6 @@ namespace Jellyfin.Api.Controllers
}
}
if (info.MediaSources != null)
{
foreach (var mediaSource in info.MediaSources)
{
_mediaInfoHelper.NormalizeMediaSourceContainer(mediaSource, profile!, DlnaProfileType.Video);
}
}
return info;
}

@ -16,6 +16,7 @@ using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Session;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@ -223,7 +224,7 @@ namespace Jellyfin.Api.Controllers
DeInterlace = false,
RequireNonAnamorphic = false,
EnableMpegtsM2TsMode = false,
TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(',', mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray()),
TranscodeReasons = mediaSource.TranscodeReasons == 0 ? null : mediaSource.TranscodeReasons.ToString(),
Context = EncodingContext.Static,
StreamOptions = new Dictionary<string, string>(),
EnableAdaptiveBitrateStreaming = true
@ -254,7 +255,7 @@ namespace Jellyfin.Api.Controllers
CopyTimestamps = true,
StartTimeTicks = startTimeTicks,
SubtitleMethod = SubtitleDeliveryMethod.Embed,
TranscodeReasons = mediaSource.TranscodeReasons == null ? null : string.Join(',', mediaSource.TranscodeReasons.Select(i => i.ToString()).ToArray()),
TranscodeReasons = mediaSource.TranscodeReasons == 0 ? null : mediaSource.TranscodeReasons.ToString(),
Context = EncodingContext.Static
};

@ -191,7 +191,9 @@ namespace Jellyfin.Api.Helpers
DeviceId = auth.DeviceId,
ItemId = item.Id,
Profile = profile,
MaxAudioChannels = maxAudioChannels
MaxAudioChannels = maxAudioChannels,
AllowAudioStreamCopy = allowAudioStreamCopy,
AllowVideoStreamCopy = allowVideoStreamCopy
};
if (string.Equals(mediaSourceId, mediaSource.Id, StringComparison.OrdinalIgnoreCase))
@ -208,7 +210,7 @@ namespace Jellyfin.Api.Helpers
mediaSource.SupportsDirectPlay = false;
}
if (!enableDirectStream)
if (!enableDirectStream || !allowVideoStreamCopy)
{
mediaSource.SupportsDirectStream = false;
}
@ -235,168 +237,79 @@ namespace Jellyfin.Api.Helpers
user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding));
}
// Beginning of Playback Determination: Attempt DirectPlay first
if (mediaSource.SupportsDirectPlay)
{
if (mediaSource.IsRemote && user.HasPermission(PermissionKind.ForceRemoteSourceTranscoding))
{
mediaSource.SupportsDirectPlay = false;
}
else
{
var supportsDirectStream = mediaSource.SupportsDirectStream;
// Dummy this up to fool StreamBuilder
mediaSource.SupportsDirectStream = true;
options.MaxBitrate = maxBitrate;
options.MaxBitrate = GetMaxBitrate(maxBitrate, user, ipAddress);
if (item is Audio)
{
if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding))
{
options.ForceDirectPlay = true;
}
}
else if (item is Video)
{
if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding)
&& !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding)
&& !user.HasPermission(PermissionKind.EnablePlaybackRemuxing))
{
options.ForceDirectPlay = true;
}
}
if (!options.ForceDirectStream)
{
// direct-stream http streaming is currently broken
options.EnableDirectStream = false;
}
// The MediaSource supports direct stream, now test to see if the client supports it
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)
? streamBuilder.BuildAudioItem(options)
: streamBuilder.BuildVideoItem(options);
// Beginning of Playback Determination
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)
? streamBuilder.BuildAudioItem(options)
: streamBuilder.BuildVideoItem(options);
if (streamInfo == null || !streamInfo.IsDirectStream)
{
mediaSource.SupportsDirectPlay = false;
}
if (streamInfo != null)
{
streamInfo.PlaySessionId = playSessionId;
streamInfo.StartPositionTicks = startTimeTicks;
// Set this back to what it was
mediaSource.SupportsDirectStream = supportsDirectStream;
mediaSource.SupportsDirectPlay = streamInfo.PlayMethod == PlayMethod.DirectPlay;
// Players do not handle this being set according to PlayMethod
mediaSource.SupportsDirectStream = options.EnableDirectStream ? streamInfo.PlayMethod == PlayMethod.DirectPlay || streamInfo.PlayMethod == PlayMethod.DirectStream : streamInfo.PlayMethod == PlayMethod.DirectPlay;
mediaSource.SupportsTranscoding = streamInfo.PlayMethod == PlayMethod.DirectStream || mediaSource.TranscodingContainer != null;
if (streamInfo != null)
if (item is Audio)
{
if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding))
{
SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token);
mediaSource.DefaultAudioStreamIndex = streamInfo.AudioStreamIndex;
mediaSource.SupportsTranscoding = false;
}
}
}
if (mediaSource.SupportsDirectStream)
{
if (mediaSource.IsRemote && user.HasPermission(PermissionKind.ForceRemoteSourceTranscoding))
else if (item is Video)
{
mediaSource.SupportsDirectStream = false;
}
else
{
options.MaxBitrate = GetMaxBitrate(maxBitrate, user, ipAddress);
if (item is Audio)
if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding)
&& !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding)
&& !user.HasPermission(PermissionKind.EnablePlaybackRemuxing))
{
if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding))
{
options.ForceDirectStream = true;
}
}
else if (item is Video)
{
if (!user.HasPermission(PermissionKind.EnableAudioPlaybackTranscoding)
&& !user.HasPermission(PermissionKind.EnableVideoPlaybackTranscoding)
&& user.HasPermission(PermissionKind.EnablePlaybackRemuxing))
{
options.ForceDirectStream = true;
}
}
// The MediaSource supports direct stream, now test to see if the client supports it
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)
? streamBuilder.BuildAudioItem(options)
: streamBuilder.BuildVideoItem(options);
if (streamInfo == null || !streamInfo.IsDirectStream)
{
mediaSource.SupportsDirectStream = false;
}
if (streamInfo != null)
{
SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token);
mediaSource.DefaultAudioStreamIndex = streamInfo.AudioStreamIndex;
mediaSource.SupportsTranscoding = false;
}
}
}
if (mediaSource.SupportsTranscoding)
{
options.MaxBitrate = GetMaxBitrate(maxBitrate, user, ipAddress);
// The MediaSource supports direct stream, now test to see if the client supports it
var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase)
? streamBuilder.BuildAudioItem(options)
: streamBuilder.BuildVideoItem(options);
if (mediaSource.IsRemote && user.HasPermission(PermissionKind.ForceRemoteSourceTranscoding))
{
if (streamInfo != null)
{
streamInfo.PlaySessionId = playSessionId;
streamInfo.StartPositionTicks = startTimeTicks;
mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-');
mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false";
mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false";
mediaSource.TranscodingContainer = streamInfo.Container;
mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol;
// Do this after the above so that StartPositionTicks is set
SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token);
mediaSource.DefaultAudioStreamIndex = streamInfo.AudioStreamIndex;
}
mediaSource.SupportsDirectPlay = false;
mediaSource.SupportsDirectStream = false;
mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-');
mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false";
mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false";
mediaSource.TranscodingContainer = streamInfo.Container;
mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol;
}
else
{
if (streamInfo != null)
if (mediaSource.SupportsTranscoding || mediaSource.SupportsDirectStream)
{
streamInfo.PlaySessionId = playSessionId;
streamInfo.PlayMethod = PlayMethod.Transcode;
mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-');
if (streamInfo.PlayMethod == PlayMethod.Transcode)
if (!allowVideoStreamCopy)
{
streamInfo.StartPositionTicks = startTimeTicks;
mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).TrimStart('-');
if (!allowVideoStreamCopy)
{
mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false";
}
if (!allowAudioStreamCopy)
{
mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false";
}
mediaSource.TranscodingContainer = streamInfo.Container;
mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol;
mediaSource.TranscodingUrl += "&allowVideoStreamCopy=false";
}
if (!allowAudioStreamCopy)
{
mediaSource.TranscodingUrl += "&allowAudioStreamCopy=false";
}
mediaSource.TranscodingContainer = streamInfo.Container;
mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol;
// Do this after the above so that StartPositionTicks is set
SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token);
mediaSource.DefaultAudioStreamIndex = streamInfo.AudioStreamIndex;
}
}
// Do this after the above so that StartPositionTicks is set
SetDeviceSpecificSubtitleInfo(streamInfo, mediaSource, auth.Token);
mediaSource.DefaultAudioStreamIndex = streamInfo.AudioStreamIndex;
}
foreach (var attachment in mediaSource.MediaAttachments)

@ -479,7 +479,7 @@ namespace Jellyfin.Api.Helpers
IsAudioDirect = EncodingHelper.IsCopyCodec(state.OutputAudioCodec),
IsVideoDirect = EncodingHelper.IsCopyCodec(state.OutputVideoCodec),
HardwareAccelerationType = hardwareAccelerationType,
TranscodeReasons = state.TranscodeReasons
TranscodeReason = state.TranscodeReason
});
}
}

@ -1799,7 +1799,7 @@ namespace MediaBrowser.Controller.MediaEncoding
return false;
}
return request.EnableAutoStreamCopy;
return true;
}
public bool CanStreamCopyAudio(EncodingJobInfo state, MediaStream audioStream, IEnumerable<string> supportedAudioCodecs)
@ -1856,17 +1856,11 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// Video bitrate must fall within requested value
if (request.AudioBitRate.HasValue)
if (request.AudioBitRate.HasValue
&& audioStream.BitDepth.HasValue
&& audioStream.BitRate.Value > request.AudioBitRate.Value)
{
if (!audioStream.BitRate.HasValue || audioStream.BitRate.Value <= 0)
{
return false;
}
if (audioStream.BitRate.Value > request.AudioBitRate.Value)
{
return false;
}
return false;
}
return request.EnableAutoStreamCopy;

@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.Json.Serialization;
using Jellyfin.Data.Entities;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Drawing;
@ -23,7 +24,7 @@ namespace MediaBrowser.Controller.MediaEncoding
public int? OutputAudioBitrate;
public int? OutputAudioChannels;
private TranscodeReason[] _transcodeReasons = null;
private TranscodeReason? _transcodeReasons = null;
public EncodingJobInfo(TranscodingJobType jobType)
{
@ -34,25 +35,23 @@ namespace MediaBrowser.Controller.MediaEncoding
SupportedSubtitleCodecs = Array.Empty<string>();
}
public TranscodeReason[] TranscodeReasons
public TranscodeReason TranscodeReason
{
get
{
if (_transcodeReasons == null)
if (!_transcodeReasons.HasValue)
{
if (BaseRequest.TranscodeReasons == null)
{
return Array.Empty<TranscodeReason>();
_transcodeReasons = 0;
return 0;
}
_transcodeReasons = BaseRequest.TranscodeReasons
.Split(',')
.Where(i => !string.IsNullOrEmpty(i))
.Select(v => (TranscodeReason)Enum.Parse(typeof(TranscodeReason), v, true))
.ToArray();
_ = Enum.TryParse<TranscodeReason>(BaseRequest.TranscodeReasons, out var reason);
_transcodeReasons = reason;
}
return _transcodeReasons;
return _transcodeReasons.Value;
}
}

@ -27,6 +27,8 @@ namespace MediaBrowser.Model.Dlna
public bool ForceDirectStream { get; set; }
public bool AllowAudioStreamCopy { get; set; }
public Guid ItemId { get; set; }
public MediaSourceInfo[] MediaSources { get; set; }

File diff suppressed because it is too large Load Diff

@ -23,7 +23,6 @@ namespace MediaBrowser.Model.Dlna
AudioCodecs = Array.Empty<string>();
VideoCodecs = Array.Empty<string>();
SubtitleCodecs = Array.Empty<string>();
TranscodeReasons = Array.Empty<TranscodeReason>();
StreamOptions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
@ -103,7 +102,7 @@ namespace MediaBrowser.Model.Dlna
public string PlaySessionId { get; set; }
public TranscodeReason[] TranscodeReasons { get; set; }
public TranscodeReason TranscodeReasons { get; set; }
public Dictionary<string, string> StreamOptions { get; private set; }
@ -799,7 +798,7 @@ namespace MediaBrowser.Model.Dlna
if (!item.IsDirectStream)
{
list.Add(new NameValuePair("TranscodeReasons", string.Join(',', item.TranscodeReasons.Distinct())));
list.Add(new NameValuePair("TranscodeReasons", item.TranscodeReasons.ToString()));
}
return list;

@ -10,5 +10,7 @@ namespace MediaBrowser.Model.Dlna
public int? AudioStreamIndex { get; set; }
public int? SubtitleStreamIndex { get; set; }
public bool AllowVideoStreamCopy { get; set; }
}
}

@ -109,7 +109,7 @@ namespace MediaBrowser.Model.Dto
public int? AnalyzeDurationMs { get; set; }
[JsonIgnore]
public TranscodeReason[] TranscodeReasons { get; set; }
public TranscodeReason TranscodeReasons { get; set; }
public int? DefaultAudioStreamIndex { get; set; }
@ -161,7 +161,7 @@ namespace MediaBrowser.Model.Dto
public MediaStream GetDefaultAudioStream(int? defaultIndex)
{
if (defaultIndex.HasValue)
if (defaultIndex.HasValue && defaultIndex != -1)
{
var val = defaultIndex.Value;

@ -16,6 +16,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: InternalsVisibleTo("Jellyfin.Model.Tests")]
[assembly: InternalsVisibleTo("Jellyfin.Dlna.Tests")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from

@ -1,32 +1,44 @@
#pragma warning disable CS1591
using System;
namespace MediaBrowser.Model.Session
{
[Flags]
public enum TranscodeReason
{
ContainerNotSupported = 0,
VideoCodecNotSupported = 1,
AudioCodecNotSupported = 2,
ContainerBitrateExceedsLimit = 3,
AudioBitrateNotSupported = 4,
AudioChannelsNotSupported = 5,
VideoResolutionNotSupported = 6,
UnknownVideoStreamInfo = 7,
UnknownAudioStreamInfo = 8,
AudioProfileNotSupported = 9,
AudioSampleRateNotSupported = 10,
AnamorphicVideoNotSupported = 11,
InterlacedVideoNotSupported = 12,
SecondaryAudioNotSupported = 13,
RefFramesNotSupported = 14,
VideoBitDepthNotSupported = 15,
VideoBitrateNotSupported = 16,
VideoFramerateNotSupported = 17,
VideoLevelNotSupported = 18,
VideoProfileNotSupported = 19,
AudioBitDepthNotSupported = 20,
SubtitleCodecNotSupported = 21,
DirectPlayError = 22,
AudioIsExternal = 23
// Primary
ContainerNotSupported = 1 << 0,
VideoCodecNotSupported = 1 << 1,
AudioCodecNotSupported = 1 << 2,
SubtitleCodecNotSupported = 1 << 3,
AudioIsExternal = 1 << 4,
SecondaryAudioNotSupported = 1 << 5,
// Video Constraints
VideoProfileNotSupported = 1 << 6,
VideoLevelNotSupported = 1 << 7,
VideoResolutionNotSupported = 1 << 8,
VideoBitDepthNotSupported = 1 << 9,
VideoFramerateNotSupported = 1 << 10,
RefFramesNotSupported = 1 << 11,
AnamorphicVideoNotSupported = 1 << 12,
InterlacedVideoNotSupported = 1 << 13,
// Audio Constraints
AudioChannelsNotSupported = 1 << 14,
AudioProfileNotSupported = 1 << 15,
AudioSampleRateNotSupported = 1 << 16,
AudioBitDepthNotSupported = 1 << 17,
// Bitrate Constraints
ContainerBitrateExceedsLimit = 1 << 18,
VideoBitrateNotSupported = 1 << 19,
AudioBitrateNotSupported = 1 << 20,
// Errors
UnknownVideoStreamInfo = 1 << 21,
UnknownAudioStreamInfo = 1 << 22,
DirectPlayError = 1 << 23,
}
}

@ -1,17 +1,10 @@
#nullable disable
#pragma warning disable CS1591
using System;
namespace MediaBrowser.Model.Session
{
public class TranscodingInfo
{
public TranscodingInfo()
{
TranscodeReasons = Array.Empty<TranscodeReason>();
}
public string AudioCodec { get; set; }
public string VideoCodec { get; set; }
@ -36,6 +29,6 @@ namespace MediaBrowser.Model.Session
public HardwareEncodingType? HardwareAccelerationType { get; set; }
public TranscodeReason[] TranscodeReasons { get; set; }
public TranscodeReason TranscodeReason { get; set; }
}
}

@ -0,0 +1,36 @@
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Jellyfin.Extensions.Json.Converters;
/// <summary>
/// Enum flag to json array converter.
/// </summary>
/// <typeparam name="T">The type of enum.</typeparam>
public class JsonFlagEnumConverter<T> : JsonConverter<T>
where T : struct, Enum
{
private static readonly T[] _enumValues = Enum.GetValues<T>();
/// <inheritdoc />
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
writer.WriteStartArray();
foreach (var enumValue in _enumValues)
{
if (value.HasFlag(enumValue))
{
writer.WriteStringValue(enumValue.ToString());
}
}
writer.WriteEndArray();
}
}

@ -0,0 +1,24 @@
using System;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Jellyfin.Extensions.Json.Converters;
/// <summary>
/// Json flag enum converter factory.
/// </summary>
public class JsonFlagEnumConverterFactory : JsonConverterFactory
{
/// <inheritdoc />
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsEnum && typeToConvert.IsDefined(typeof(FlagsAttribute));
}
/// <inheritdoc />
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return (JsonConverter?)Activator.CreateInstance(typeof(JsonFlagEnumConverter<>).MakeGenericType(typeToConvert));
}
}

@ -36,6 +36,7 @@ namespace Jellyfin.Extensions.Json
new JsonGuidConverter(),
new JsonNullableGuidConverter(),
new JsonVersionConverter(),
new JsonFlagEnumConverterFactory(),
new JsonStringEnumConverter(),
new JsonNullableStructConverterFactory(),
new JsonBoolNumberConverter(),

@ -14,6 +14,12 @@
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>
<ItemGroup>
<None Include="Test Data\**\*.*">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<!-- Code Analyzers -->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.3">

@ -0,0 +1,466 @@
using System;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.Json;
using System.Threading.Tasks;
using Jellyfin.Extensions.Json;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Session;
using Microsoft.Extensions.Logging.Abstractions;
using Moq;
using Xunit;
namespace Jellyfin.MediaBrowser.Model.Tests
{
public class StreamBuilderTests
{
[Theory]
// Chrome
[InlineData("Chrome", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioIsExternal)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
[InlineData("Chrome", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
[InlineData("Chrome", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
// Firefox
[InlineData("Firefox", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioIsExternal)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
[InlineData("Firefox", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
[InlineData("Firefox", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
// Safari
[InlineData("SafariNext", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
[InlineData("SafariNext", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
[InlineData("SafariNext", "mp4-hevc-ac3-aacExt-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
// AndroidPixel
[InlineData("AndroidPixel", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("AndroidPixel", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
// Yatse
[InlineData("Yatse", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("Yatse", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("Yatse", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("Yatse", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
[InlineData("Yatse", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("Yatse", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
// RokuSSPlus
[InlineData("RokuSSPlus", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("RokuSSPlus", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450 should be DirectPlay
[InlineData("RokuSSPlus", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("RokuSSPlus", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-ac3-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
// JellyfinMediaPlayer
[InlineData("JellyfinMediaPlayer", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("JellyfinMediaPlayer", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("JellyfinMediaPlayer", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)] // #6450
// Chrome-NoHLS
[InlineData("Chrome-NoHLS", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Chrome-NoHLS", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Chrome-NoHLS", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Chrome-NoHLS", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioIsExternal)] // #6450
[InlineData("Chrome-NoHLS", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome-NoHLS", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode", "http")]
[InlineData("Chrome-NoHLS", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode", "http")]
[InlineData("Chrome-NoHLS", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome-NoHLS", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome-NoHLS", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
// TranscodeMedia
[InlineData("TranscodeMedia", "mp4-h264-aac-vtt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "HLS.mp4")]
[InlineData("TranscodeMedia", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "HLS.mp4")]
[InlineData("TranscodeMedia", "mp4-h264-ac3-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "HLS.mp4")]
[InlineData("TranscodeMedia", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "HLS.mp4")]
[InlineData("TranscodeMedia", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "HLS.mp4")]
[InlineData("TranscodeMedia", "mkv-av1-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "http")]
[InlineData("TranscodeMedia", "mkv-av1-vorbis-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "http")]
[InlineData("TranscodeMedia", "mkv-vp9-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "http")]
[InlineData("TranscodeMedia", "mkv-vp9-ac3-srt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "DirectStream", "http")]
[InlineData("TranscodeMedia", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.Transcode, TranscodeReason.DirectPlayError, "Remux", "http")]
// DirectMedia
[InlineData("DirectMedia", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")]
[InlineData("DirectMedia", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("DirectMedia", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)]
[InlineData("DirectMedia", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)]
// LowBandwidth
[InlineData("LowBandwidth", "mp4-h264-aac-vtt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mp4-h264-ac3-srt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mkv-vp9-aac-srt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mkv-vp9-ac3-srt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("LowBandwidth", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
// Null
[InlineData("Null", "mp4-h264-aac-vtt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mp4-h264-ac3-aac-srt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mp4-h264-ac3-srt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mp4-hevc-aac-srt-15200k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mp4-hevc-ac3-aac-srt-15200k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mkv-vp9-aac-srt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mkv-vp9-ac3-srt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
[InlineData("Null", "mkv-vp9-vorbis-vtt-2600k", null, TranscodeReason.ContainerBitrateExceedsLimit)]
public async Task BuildVideoItemSimple(string deviceName, string mediaSource, PlayMethod? playMethod, TranscodeReason why = (TranscodeReason)0, string transcodeMode = "DirectStream", string transcodeProtocol = "")
{
var options = await GetVideoOptions(deviceName, mediaSource);
BuildVideoItemSimpleTest(options, playMethod, why, transcodeMode, transcodeProtocol);
}
[Theory]
// Chrome
[InlineData("Chrome", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450 <BUG: this is direct played>
[InlineData("Chrome", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
[InlineData("Chrome", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
[InlineData("Chrome", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Chrome", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
// Firefox
[InlineData("Firefox", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
[InlineData("Firefox", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
[InlineData("Firefox", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Firefox", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
// Safari
[InlineData("SafariNext", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("SafariNext", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
[InlineData("SafariNext", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
[InlineData("SafariNext", "mp4-hevc-ac3-aacExt-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Remux", "HLS.mp4")] // #6450
// AndroidPixel
[InlineData("AndroidPixel", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("AndroidPixel", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
[InlineData("AndroidPixel", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")]
// Yatse
[InlineData("Yatse", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("Yatse", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Yatse", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("Yatse", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)]
[InlineData("Yatse", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("Yatse", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
// RokuSSPlus
[InlineData("RokuSSPlus", "mp4-h264-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("RokuSSPlus", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450 should be DirectPlay
[InlineData("RokuSSPlus", "mp4-h264-ac3-aacDef-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("RokuSSPlus", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-ac3-srt-15200k", PlayMethod.DirectStream, TranscodeReason.AudioCodecNotSupported)] // #6450
// JellyfinMediaPlayer
[InlineData("JellyfinMediaPlayer", "mp4-h264-aac-vtt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-h264-ac3-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-hevc-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")] // #6450
[InlineData("JellyfinMediaPlayer", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.ContainerBitrateExceedsLimit, "Transcode")] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-ac3-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("JellyfinMediaPlayer", "mkv-vp9-vorbis-vtt-2600k", PlayMethod.DirectPlay)] // #6450
public async Task BuildVideoItemWithFirstExplicitStream(string deviceName, string mediaSource, PlayMethod? playMethod, TranscodeReason why = (TranscodeReason)0, string transcodeMode = "DirectStream", string transcodeProtocol = "")
{
var options = await GetVideoOptions(deviceName, mediaSource);
options.AudioStreamIndex = 1;
options.SubtitleStreamIndex = options.MediaSources[0].MediaStreams.Count - 1;
var streamInfo = BuildVideoItemSimpleTest(options, playMethod, why, transcodeMode, transcodeProtocol);
Assert.Equal(streamInfo?.AudioStreamIndex, options.AudioStreamIndex);
Assert.Equal(streamInfo?.SubtitleStreamIndex, options.SubtitleStreamIndex);
}
[Theory]
// Chrome
[InlineData("Chrome", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Chrome", "mp4-h264-ac3-aacExt-srt-2600k", PlayMethod.DirectStream, TranscodeReason.AudioIsExternal)] // #6450
[InlineData("Chrome", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
// Firefox
[InlineData("Firefox", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay)] // #6450
[InlineData("Firefox", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.Transcode, TranscodeReason.VideoCodecNotSupported, "Transcode")]
// Yatse
[InlineData("Yatse", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("Yatse", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
// RokuSSPlus
[InlineData("RokuSSPlus", "mp4-h264-ac3-aac-srt-2600k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
[InlineData("RokuSSPlus", "mp4-hevc-ac3-aac-srt-15200k", PlayMethod.DirectPlay, (TranscodeReason)0, "Remux")] // #6450
public async Task BuildVideoItemWithDirectPlayExplicitStreams(string deviceName, string mediaSource, PlayMethod? playMethod, TranscodeReason why = (TranscodeReason)0, string transcodeMode = "DirectStream", string transcodeProtocol = "")
{
var options = await GetVideoOptions(deviceName, mediaSource);
var streamCount = options.MediaSources[0].MediaStreams.Count;
options.AudioStreamIndex = streamCount - 2;
options.SubtitleStreamIndex = streamCount - 1;
var streamInfo = BuildVideoItemSimpleTest(options, playMethod, why, transcodeMode, transcodeProtocol);
Assert.Equal(streamInfo?.AudioStreamIndex, options.AudioStreamIndex);
Assert.Equal(streamInfo?.SubtitleStreamIndex, options.SubtitleStreamIndex);
}
private StreamInfo? BuildVideoItemSimpleTest(VideoOptions options, PlayMethod? playMethod, TranscodeReason why, string transcodeMode, string transcodeProtocol)
{
if (string.IsNullOrEmpty(transcodeProtocol))
{
transcodeProtocol = playMethod == PlayMethod.DirectStream ? "http" : "HLS.ts";
}
var builder = GetStreamBuilder();
var val = builder.BuildVideoItem(options);
Assert.NotNull(val);
if (playMethod != null)
{
Assert.Equal(playMethod, val.PlayMethod);
}
Assert.Equal(why, val.TranscodeReasons);
var audioStreamIndexInput = options.AudioStreamIndex;
var targetVideoStream = val.TargetVideoStream;
var targetAudioStream = val.TargetAudioStream;
var mediaSource = options.MediaSources.First(source => source.Id == val.MediaSourceId);
Assert.NotNull(mediaSource);
var videoStreams = mediaSource.MediaStreams.Where(stream => stream.Type == MediaStreamType.Video);
var audioStreams = mediaSource.MediaStreams.Where(stream => stream.Type == MediaStreamType.Audio);
// TODO: check AudioStreamIndex vs options.AudioStreamIndex
var inputAudioStream = mediaSource.GetDefaultAudioStream(audioStreamIndexInput ?? mediaSource.DefaultAudioStreamIndex);
var uri = ParseUri(val);
if (playMethod == PlayMethod.DirectPlay)
{
// check expected container
var containers = ContainerProfile.SplitValue(mediaSource.Container);
// TODO: test transcode too
// Assert.Contains(uri.Extension, containers);
// check expected video codec (1)
Assert.Contains(targetVideoStream.Codec, val.TargetVideoCodec);
Assert.Single(val.TargetVideoCodec);
// check expected audio codecs (1)
Assert.Contains(targetAudioStream.Codec, val.TargetAudioCodec);
Assert.Single(val.TargetAudioCodec);
// Assert.Single(val.AudioCodecs);
if (transcodeMode == "DirectStream")
{
Assert.Equal(val.Container, uri.Extension);
}
}
else if (playMethod == PlayMethod.DirectStream || playMethod == PlayMethod.Transcode)
{
Assert.NotNull(val.Container);
Assert.NotEmpty(val.VideoCodecs);
Assert.NotEmpty(val.AudioCodecs);
// check expected container (todo: this could be a test param)
if (transcodeProtocol == "http")
{
// Assert.Equal("webm", val.Container);
Assert.Equal(val.Container, uri.Extension);
Assert.Equal("stream", uri.Filename);
Assert.Equal("http", val.SubProtocol);
}
else if (transcodeProtocol == "HLS.mp4")
{
Assert.Equal("mp4", val.Container);
Assert.Equal("m3u8", uri.Extension);
Assert.Equal("master", uri.Filename);
Assert.Equal("hls", val.SubProtocol);
}
else
{
Assert.Equal("ts", val.Container);
Assert.Equal("m3u8", uri.Extension);
Assert.Equal("master", uri.Filename);
Assert.Equal("hls", val.SubProtocol);
}
// Full transcode
if (transcodeMode == "Transcode")
{
if ((val.TranscodeReasons & (StreamBuilder.ContainerReasons | TranscodeReason.DirectPlayError)) == 0)
{
Assert.All(
videoStreams,
stream => Assert.DoesNotContain(stream.Codec, val.VideoCodecs));
}
// todo: fill out tests here
}
// DirectStream and Remux
else
{
// check expected video codec (1)
Assert.Contains(targetVideoStream.Codec, val.TargetVideoCodec);
Assert.Single(val.TargetVideoCodec);
if (transcodeMode == "DirectStream")
{
if (!targetAudioStream.IsExternal)
{
// check expected audio codecs (1)
Assert.DoesNotContain(targetAudioStream.Codec, val.AudioCodecs);
}
}
else if (transcodeMode == "Remux")
{
// check expected audio codecs (1)
Assert.Contains(targetAudioStream.Codec, val.AudioCodecs);
Assert.Single(val.AudioCodecs);
}
// video details
var videoStream = targetVideoStream;
Assert.False(val.EstimateContentLength);
Assert.Equal(TranscodeSeekInfo.Auto, val.TranscodeSeekInfo);
Assert.Contains(videoStream.Profile?.ToLowerInvariant() ?? string.Empty, val.TargetVideoProfile?.Split(",").Select(s => s.ToLowerInvariant()) ?? Array.Empty<string>());
Assert.Equal(videoStream.Level, val.TargetVideoLevel);
Assert.Equal(videoStream.BitDepth, val.TargetVideoBitDepth);
Assert.InRange(val.VideoBitrate.GetValueOrDefault(), videoStream.BitRate.GetValueOrDefault(), int.MaxValue);
// audio codec not supported
if ((why & TranscodeReason.AudioCodecNotSupported) != 0)
{
// audio stream specified
if (options.AudioStreamIndex >= 0)
{
// TODO:fixme
if (!targetAudioStream.IsExternal)
{
Assert.DoesNotContain(targetAudioStream.Codec, val.AudioCodecs);
}
}
// audio stream not specified
else
{
// TODO:fixme
Assert.All(audioStreams, stream =>
{
if (!stream.IsExternal)
{
Assert.DoesNotContain(stream.Codec, val.AudioCodecs);
}
});
}
}
}
}
else if (playMethod == null)
{
Assert.Null(val.SubProtocol);
Assert.Equal("stream", uri.Filename);
Assert.False(val.EstimateContentLength);
Assert.Equal(TranscodeSeekInfo.Auto, val.TranscodeSeekInfo);
}
return val;
}
private static async ValueTask<T> TestData<T>(string name)
{
var path = Path.Join("Test Data", typeof(T).Name + "-" + name + ".json");
using (var stream = File.OpenRead(path))
{
var value = await JsonSerializer.DeserializeAsync<T>(stream, JsonDefaults.Options);
if (value != null)
{
return value;
}
throw new SerializationException("Invalid test data: " + name);
}
}
private StreamBuilder GetStreamBuilder()
{
var transcodeSupport = new Mock<ITranscoderSupport>();
var logger = new NullLogger<StreamBuilderTests>();
return new StreamBuilder(transcodeSupport.Object, logger);
}
private static async ValueTask<VideoOptions> GetVideoOptions(string deviceProfile, params string[] sources)
{
var mediaSources = sources.Select(src => TestData<MediaSourceInfo>(src))
.Select(val => val.Result)
.ToArray();
var mediaSourceId = mediaSources[0]?.Id;
var dp = await TestData<DeviceProfile>(deviceProfile);
return new VideoOptions()
{
ItemId = new Guid("11D229B7-2D48-4B95-9F9B-49F6AB75E613"),
MediaSourceId = mediaSourceId,
MediaSources = mediaSources,
DeviceId = "test-deviceId",
Profile = dp,
AllowAudioStreamCopy = true,
AllowVideoStreamCopy = true,
};
}
private static (string Path, NameValueCollection Query, string Filename, string Extension) ParseUri(StreamInfo val)
{
var href = val.ToUrl("media:", "ACCESSTOKEN").Split("?", 2);
var path = href[0];
var queryString = href.ElementAtOrDefault(1);
var query = string.IsNullOrEmpty(queryString) ? System.Web.HttpUtility.ParseQueryString(queryString ?? string.Empty) : new NameValueCollection();
var filename = System.IO.Path.GetFileNameWithoutExtension(path);
var extension = System.IO.Path.GetExtension(path);
if (extension.Length > 0)
{
extension = extension.Substring(1);
}
return (path, query, filename, extension);
}
}
}

@ -0,0 +1,332 @@
{
"Name": "Jellyfin Android",
"EnableAlbumArtInDidl": false,
"EnableSingleAlbumArtLimit": false,
"EnableSingleSubtitleLimit": false,
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxAlbumArtWidth": 2147483647,
"MaxAlbumArtHeight": 2147483647,
"MaxStreamingBitrate": 8000000,
"MaxStaticBitrate": 8000000,
"MusicStreamingTranscodingBitrate": 128000,
"TimelineOffsetSeconds": 0,
"RequiresPlainVideoItems": false,
"RequiresPlainFolders": false,
"EnableMSMediaReceiverRegistrar": false,
"IgnoreTranscodeByteRangeRequests": false,
"DirectPlayProfiles": [
{
"Container": "mp4",
"AudioCodec": "mp3,aac,alac,ac3",
"VideoCodec": "h263,mpeg4,h264,hevc,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mp4",
"AudioCodec": "mp3,aac,alac,ac3",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "fmp4",
"AudioCodec": "mp3,aac,ac3,eac3",
"VideoCodec": "h263,mpeg4,h264,hevc,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "fmp4",
"AudioCodec": "mp3,aac,ac3,eac3",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webm",
"AudioCodec": "vorbis,opus",
"VideoCodec": "vp8,vp9,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "webm",
"AudioCodec": "vorbis,opus",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "mkv",
"AudioCodec": "pcm_s8,pcm_s16be,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,pcm_alaw,pcm_mulaw,mp3,aac,vorbis,opus,flac,alac,ac3,eac3,dts,mlp,truehd",
"VideoCodec": "h263,mpeg4,h264,hevc,av1,vp8,vp9,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mkv",
"AudioCodec": "pcm_s8,pcm_s16be,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,pcm_alaw,pcm_mulaw,mp3,aac,vorbis,opus,flac,alac,ac3,eac3,dts,mlp,truehd",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "mp3",
"AudioCodec": "mp3",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "ogg",
"AudioCodec": "vorbis,opus,flac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "wav",
"AudioCodec": "pcm_s8,pcm_s16be,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,pcm_alaw,pcm_mulaw",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "mpegts",
"AudioCodec": "pcm_s8,pcm_s16be,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,pcm_alaw,pcm_mulaw,mp3,aac,ac3,eac3,dts,mlp,truehd",
"VideoCodec": "mpeg4,h264,hevc",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mpegts",
"AudioCodec": "pcm_s8,pcm_s16be,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,pcm_alaw,pcm_mulaw,mp3,aac,ac3,eac3,dts,mlp,truehd",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "flv",
"AudioCodec": "mp3,aac",
"VideoCodec": "mpeg4,h264",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "flv",
"AudioCodec": "mp3,aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "aac",
"AudioCodec": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "flac",
"AudioCodec": "flac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "3gp",
"AudioCodec": "3gpp,aac,flac",
"VideoCodec": "h263,mpeg4,h264,hevc",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "3gp",
"AudioCodec": "3gpp,aac,flac",
"Type": "Audio",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Container": "ts",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "mp1,mp2,mp3,aac,ac3,eac3,dts,mlp,truehd",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mkv",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "pcm_s8,pcm_s16be,pcm_s16le,pcm_s24le,pcm_s32le,pcm_f32le,pcm_alaw,pcm_mulaw,mp1,mp2,mp3,aac,vorbis,opus,flac,alac,ac3,eac3,dts,mlp,truehd",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"ContainerProfiles": [
{
"Type": "Video",
"Container": "mp4",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "mp4",
"$type": "ContainerProfile"
},
{
"Type": "Video",
"Container": "fmp4",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "fmp4",
"$type": "ContainerProfile"
},
{
"Type": "Video",
"Container": "webm",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "webm",
"$type": "ContainerProfile"
},
{
"Type": "Video",
"Container": "mkv",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "mkv",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "mp3",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "ogg",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "wav",
"$type": "ContainerProfile"
},
{
"Type": "Video",
"Container": "mpegts",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "mpegts",
"$type": "ContainerProfile"
},
{
"Type": "Video",
"Container": "flv",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "flv",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "aac",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "flac",
"$type": "ContainerProfile"
},
{
"Type": "Video",
"Container": "3gp",
"$type": "ContainerProfile"
},
{
"Type": "Audio",
"Container": "3gp",
"$type": "ContainerProfile"
}
],
"SubtitleProfiles": [
{
"Format": "srt",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "subrip",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ttml",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "subrip",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ttml",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "vtt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "webvtt",
"Method": "External",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,430 @@
{
"EnableAlbumArtInDidl": false,
"EnableSingleAlbumArtLimit": false,
"EnableSingleSubtitleLimit": false,
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxAlbumArtWidth": 0,
"MaxAlbumArtHeight": 0,
"MaxStreamingBitrate": 120000000,
"MaxStaticBitrate": 100000000,
"MusicStreamingTranscodingBitrate": 384000,
"TimelineOffsetSeconds": 0,
"RequiresPlainVideoItems": false,
"RequiresPlainFolders": false,
"EnableMSMediaReceiverRegistrar": false,
"IgnoreTranscodeByteRangeRequests": false,
"DirectPlayProfiles": [
{
"Container": "webm",
"AudioCodec": "vorbis,opus",
"VideoCodec": "vp8,vp9,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mp4,m4v",
"AudioCodec": "aac,mp3,opus,flac,alac,vorbis",
"VideoCodec": "h264,vp8,vp9,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mov",
"AudioCodec": "aac,mp3,opus,flac,alac,vorbis",
"VideoCodec": "h264",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "opus",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webm",
"AudioCodec": "opus",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4a",
"AudioCodec": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4b",
"AudioCodec": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "flac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4a",
"AudioCodec": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4b",
"AudioCodec": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webma",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webm",
"AudioCodec": "webma",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "wav",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "ogg",
"Type": "Audio",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "opus",
"Type": "Audio",
"AudioCodec": "opus",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "wav",
"Type": "Audio",
"AudioCodec": "wav",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "opus",
"Type": "Audio",
"AudioCodec": "opus",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "wav",
"Type": "Audio",
"AudioCodec": "wav",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp4",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "aac,mp3,opus,flac,alac,vorbis",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "webm",
"Type": "Video",
"VideoCodec": "vp8,vp9,av1,vpx",
"AudioCodec": "vorbis,opus",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp4",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "aac,mp3,opus,flac,alac,vorbis",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"CodecProfiles": [
{
"Type": "VideoAudio",
"Conditions": [
{
"Condition": "Equals",
"Property": "IsSecondaryAudio",
"Value": "false",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "aac",
"$type": "CodecProfile"
},
{
"Type": "VideoAudio",
"Conditions": [
{
"Condition": "Equals",
"Property": "IsSecondaryAudio",
"Value": "false",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"$type": "CodecProfile"
},
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "high|main|baseline|constrained baseline|high 10",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "52",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "h264",
"$type": "CodecProfile"
},
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "main",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "120",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "hevc",
"$type": "CodecProfile"
}
],
"ResponseProfiles": [
{
"Container": "m4v",
"Type": "Video",
"MimeType": "video/mp4",
"$type": "ResponseProfile"
}
],
"SubtitleProfiles": [
{
"Format": "vtt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "External",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,448 @@
{
"EnableAlbumArtInDidl": false,
"EnableSingleAlbumArtLimit": false,
"EnableSingleSubtitleLimit": false,
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxAlbumArtWidth": 0,
"MaxAlbumArtHeight": 0,
"MaxStreamingBitrate": 120000000,
"MaxStaticBitrate": 100000000,
"MusicStreamingTranscodingBitrate": 384000,
"TimelineOffsetSeconds": 0,
"RequiresPlainVideoItems": false,
"RequiresPlainFolders": false,
"EnableMSMediaReceiverRegistrar": false,
"IgnoreTranscodeByteRangeRequests": false,
"DirectPlayProfiles": [
{
"Container": "webm",
"AudioCodec": "vorbis,opus",
"VideoCodec": "vp8,vp9,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mp4,m4v",
"AudioCodec": "aac,mp3,opus,flac,alac,vorbis",
"VideoCodec": "h264,vp8,vp9,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mov",
"AudioCodec": "aac,mp3,opus,flac,alac,vorbis",
"VideoCodec": "h264",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "opus",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webm",
"AudioCodec": "opus",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4a",
"AudioCodec": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4b",
"AudioCodec": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "flac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4a",
"AudioCodec": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4b",
"AudioCodec": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webma",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webm",
"AudioCodec": "webma",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "wav",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "ogg",
"Type": "Audio",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Container": "ts",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 2,
"SegmentLength": 0,
"BreakOnNonKeyFrames": true,
"$type": "TranscodingProfile"
},
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "opus",
"Type": "Audio",
"AudioCodec": "opus",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "wav",
"Type": "Audio",
"AudioCodec": "wav",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "opus",
"Type": "Audio",
"AudioCodec": "opus",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "wav",
"Type": "Audio",
"AudioCodec": "wav",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "ts",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "aac,mp3",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 2,
"SegmentLength": 0,
"BreakOnNonKeyFrames": true,
"$type": "TranscodingProfile"
},
{
"Container": "webm",
"Type": "Video",
"VideoCodec": "vp8,vp9,av1,vpx",
"AudioCodec": "vorbis,opus",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp4",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "aac,mp3,opus,flac,alac,vorbis",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"CodecProfiles": [
{
"Type": "VideoAudio",
"Conditions": [
{
"Condition": "Equals",
"Property": "IsSecondaryAudio",
"Value": "false",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "aac",
"$type": "CodecProfile"
},
{
"Type": "VideoAudio",
"Conditions": [
{
"Condition": "Equals",
"Property": "IsSecondaryAudio",
"Value": "false",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"$type": "CodecProfile"
},
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "high|main|baseline|constrained baseline|high 10",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "52",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "h264",
"$type": "CodecProfile"
},
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "main",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "120",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "hevc",
"$type": "CodecProfile"
}
],
"ResponseProfiles": [
{
"Container": "m4v",
"Type": "Video",
"MimeType": "video/mp4",
"$type": "ResponseProfile"
}
],
"SubtitleProfiles": [
{
"Format": "vtt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "External",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,90 @@
{
"Name": "Jellyfin Media Player",
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxStreamingBitrate": 20000000,
"MaxStaticBitrate": 20000000,
"MusicStreamingTranscodingBitrate": 1280000,
"TimelineOffsetSeconds": 5,
"DirectPlayProfiles": [
{
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Type": "Photo",
"$type": "DirectPlayProfile"
}
],
"SubtitleProfiles": [
{
"Format": "srt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "pgssub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "dvdsub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "pgs",
"Method": "Embed",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,441 @@
{
"EnableAlbumArtInDidl": false,
"EnableSingleAlbumArtLimit": false,
"EnableSingleSubtitleLimit": false,
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxAlbumArtWidth": 0,
"MaxAlbumArtHeight": 0,
"MaxStreamingBitrate": 120000000,
"MaxStaticBitrate": 100000000,
"MusicStreamingTranscodingBitrate": 384000,
"TimelineOffsetSeconds": 0,
"RequiresPlainVideoItems": false,
"RequiresPlainFolders": false,
"EnableMSMediaReceiverRegistrar": false,
"IgnoreTranscodeByteRangeRequests": false,
"DirectPlayProfiles": [
{
"Container": "webm",
"AudioCodec": "vorbis,opus",
"VideoCodec": "vp8,vp9,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mp4,m4v",
"AudioCodec": "aac,mp3,opus,flac,alac,vorbis",
"VideoCodec": "h264,vp8,vp9,av1",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "opus",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webm",
"AudioCodec": "opus",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4a",
"AudioCodec": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4b",
"AudioCodec": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "flac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4a",
"AudioCodec": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4b",
"AudioCodec": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webma",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webm",
"AudioCodec": "webma",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "wav",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "ogg",
"Type": "Audio",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Container": "ts",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 2,
"SegmentLength": 0,
"BreakOnNonKeyFrames": true,
"$type": "TranscodingProfile"
},
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "opus",
"Type": "Audio",
"AudioCodec": "opus",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "wav",
"Type": "Audio",
"AudioCodec": "wav",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "opus",
"Type": "Audio",
"AudioCodec": "opus",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "wav",
"Type": "Audio",
"AudioCodec": "wav",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "ts",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "aac,mp3",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 2,
"SegmentLength": 0,
"BreakOnNonKeyFrames": true,
"$type": "TranscodingProfile"
},
{
"Container": "webm",
"Type": "Video",
"VideoCodec": "vp8,vp9,av1,vpx",
"AudioCodec": "vorbis,opus",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp4",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "aac,mp3,opus,flac,alac,vorbis",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"CodecProfiles": [
{
"Type": "VideoAudio",
"Conditions": [
{
"Condition": "Equals",
"Property": "IsSecondaryAudio",
"Value": "false",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "aac",
"$type": "CodecProfile"
},
{
"Type": "VideoAudio",
"Conditions": [
{
"Condition": "Equals",
"Property": "IsSecondaryAudio",
"Value": "false",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"$type": "CodecProfile"
},
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "high|main|baseline|constrained baseline",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "52",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "h264",
"$type": "CodecProfile"
},
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "main",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "120",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "hevc",
"$type": "CodecProfile"
}
],
"ResponseProfiles": [
{
"Container": "m4v",
"Type": "Video",
"MimeType": "video/mp4",
"$type": "ResponseProfile"
}
],
"SubtitleProfiles": [
{
"Format": "vtt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "External",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,137 @@
{
"Name": "Jellyfin Media Player",
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxStreamingBitrate": 8000000,
"MaxStaticBitrate": 8000000,
"MusicStreamingTranscodingBitrate": 1280000,
"TimelineOffsetSeconds": 5,
"DirectPlayProfiles": [
{
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Type": "Photo",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Type": "Audio",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "ts",
"Type": "Video",
"VideoCodec": "h264,h265,hevc,mpeg4,mpeg2video",
"AudioCodec": "aac,mp3,ac3,opus,flac,vorbis",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "jpeg",
"Type": "Photo",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"SubtitleProfiles": [
{
"Format": "srt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "pgssub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "dvdsub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "pgs",
"Method": "Embed",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,137 @@
{
"Name": "Jellyfin Media Player",
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxStreamingBitrate": 120000,
"MaxStaticBitrate": 100000,
"MusicStreamingTranscodingBitrate": 3840,
"TimelineOffsetSeconds": 5,
"DirectPlayProfiles": [
{
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Type": "Photo",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Type": "Audio",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "ts",
"Type": "Video",
"VideoCodec": "h264,h265,hevc,mpeg4,mpeg2video",
"AudioCodec": "aac,mp3,ac3,opus,flac,vorbis",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "jpeg",
"Type": "Photo",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"SubtitleProfiles": [
{
"Format": "srt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "pgssub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "dvdsub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "pgs",
"Method": "Embed",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,9 @@
{
"Name": "Jellyfin Media Player",
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxStreamingBitrate": 120000,
"MaxStaticBitrate": 100000,
"MusicStreamingTranscodingBitrate": 3840,
"TimelineOffsetSeconds": 5,
"$type": "DeviceProfile"
}

@ -0,0 +1,211 @@
{
"EnableAlbumArtInDidl": false,
"EnableSingleAlbumArtLimit": false,
"EnableSingleSubtitleLimit": false,
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxAlbumArtWidth": 0,
"MaxAlbumArtHeight": 0,
"MaxStreamingBitrate": 120000000,
"MaxStaticBitrate": 100000000,
"MusicStreamingTranscodingBitrate": 192000,
"TimelineOffsetSeconds": 0,
"RequiresPlainVideoItems": false,
"RequiresPlainFolders": false,
"EnableMSMediaReceiverRegistrar": false,
"IgnoreTranscodeByteRangeRequests": false,
"DirectPlayProfiles": [
{
"Container": "mp4,m4v,mov",
"AudioCodec": "mp3,pcm,lpcm,wav,alac,aac",
"VideoCodec": "h264,h265,hevc,mpeg2video",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mkv,webm",
"AudioCodec": "mp3,pcm,lpcm,wav,flac,alac,aac,opus,vorbis",
"VideoCodec": "h264,vp8,h265,hevc,vp9,mpeg2video",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mp3,pcm,lpcm,wav,wma,flac,alac,aac,wmapro",
"Type": "Audio",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": " 2",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "2",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "2",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": " 2",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "ts",
"Type": "Video",
"VideoCodec": "h264,mpeg2video",
"AudioCodec": "aac",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": " 2",
"MinSegments": 1,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp4",
"Type": "Video",
"VideoCodec": "h264,h265,hevc,mpeg2video",
"AudioCodec": "mp3,pcm,lpcm,wav,alac,aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"CodecProfiles": [
{
"Type": "Video",
"Conditions": [
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "high|main|baseline|constrained baseline",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "51",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "h264",
"$type": "CodecProfile"
},
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "main|main 10",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "hevc",
"$type": "CodecProfile"
}
],
"SubtitleProfiles": [
{
"Format": "vtt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ttml",
"Method": "External",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,211 @@
{
"EnableAlbumArtInDidl": false,
"EnableSingleAlbumArtLimit": false,
"EnableSingleSubtitleLimit": false,
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxAlbumArtWidth": 0,
"MaxAlbumArtHeight": 0,
"MaxStreamingBitrate": 120000000,
"MaxStaticBitrate": 100000000,
"MusicStreamingTranscodingBitrate": 192000,
"TimelineOffsetSeconds": 0,
"RequiresPlainVideoItems": false,
"RequiresPlainFolders": false,
"EnableMSMediaReceiverRegistrar": false,
"IgnoreTranscodeByteRangeRequests": false,
"DirectPlayProfiles": [
{
"Container": "mp4,m4v,mov",
"AudioCodec": "mp3,pcm,lpcm,wav,alac,aac",
"VideoCodec": "h264,h265,hevc,mpeg2video",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mkv,webm",
"AudioCodec": "mp3,pcm,lpcm,wav,flac,alac,aac,opus,vorbis",
"VideoCodec": "h264,vp8,h265,hevc,vp9,mpeg2video",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mp3,pcm,lpcm,wav,wma,flac,alac,aac,wmapro",
"Type": "Audio",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": " 2",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "2",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "2",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": " 2",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "ts",
"Type": "Video",
"VideoCodec": "h264,h265,hevc,mpeg2video",
"AudioCodec": "aac",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": " 2",
"MinSegments": 1,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp4",
"Type": "Video",
"VideoCodec": "h264,h265,hevc,mpeg2video",
"AudioCodec": "mp3,pcm,lpcm,wav,alac,aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"CodecProfiles": [
{
"Type": "Video",
"Conditions": [
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "high|main|baseline|constrained baseline",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "51",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "h264",
"$type": "CodecProfile"
},
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "main|main 10",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "hevc",
"$type": "CodecProfile"
}
],
"SubtitleProfiles": [
{
"Format": "vtt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ttml",
"Method": "External",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,357 @@
{
"EnableAlbumArtInDidl": false,
"EnableSingleAlbumArtLimit": false,
"EnableSingleSubtitleLimit": false,
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxAlbumArtWidth": 0,
"MaxAlbumArtHeight": 0,
"MaxStreamingBitrate": 120000000,
"MaxStaticBitrate": 100000000,
"MusicStreamingTranscodingBitrate": 384000,
"TimelineOffsetSeconds": 0,
"RequiresPlainVideoItems": false,
"RequiresPlainFolders": false,
"EnableMSMediaReceiverRegistrar": false,
"IgnoreTranscodeByteRangeRequests": false,
"DirectPlayProfiles": [
{
"Container": "webm",
"AudioCodec": "vorbis",
"VideoCodec": "vp8,vp9",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mp4,m4v",
"AudioCodec": "aac,mp3,ac3,eac3,flac,alac,vorbis",
"VideoCodec": "h264,vp8,vp9",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mov",
"AudioCodec": "aac,mp3,ac3,eac3,flac,alac,vorbis",
"VideoCodec": "h264",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4a",
"AudioCodec": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4b",
"AudioCodec": "aac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "flac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4a",
"AudioCodec": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "m4b",
"AudioCodec": "alac",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webma",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "webm",
"AudioCodec": "webma",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "wav",
"Type": "Audio",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 2,
"SegmentLength": 0,
"BreakOnNonKeyFrames": true,
"$type": "TranscodingProfile"
},
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "wav",
"Type": "Audio",
"AudioCodec": "wav",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "aac",
"Type": "Audio",
"AudioCodec": "aac",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "wav",
"Type": "Audio",
"AudioCodec": "wav",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp4",
"Type": "Video",
"AudioCodec": "aac,ac3,eac3,flac,alac",
"VideoCodec": "hevc,h264",
"Context": "Streaming",
"Protocol": "hls",
"MaxAudioChannels": "2",
"MinSegments": "2",
"BreakOnNonKeyFrames": true
},
{
"Container": "ts",
"Type": "Video",
"AudioCodec": "aac,mp3,ac3,eac3",
"VideoCodec": "h264",
"Context": "Streaming",
"Protocol": "hls",
"MaxAudioChannels": "2",
"MinSegments": "2",
"BreakOnNonKeyFrames": true
},
{
"Container": "webm",
"Type": "Video",
"AudioCodec": "vorbis",
"VideoCodec": "vp8,vpx",
"Context": "Streaming",
"Protocol": "http",
"MaxAudioChannels": "2"
},
{
"Container": "mp4",
"Type": "Video",
"AudioCodec": "aac,mp3,ac3,eac3,flac,alac,vorbis",
"VideoCodec": "h264",
"Context": "Static",
"Protocol": "http"
}
],
"CodecProfiles": [
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "high|main|baseline|constrained baseline",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "52",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "h264",
"$type": "CodecProfile"
},
{
"Type": "Video",
"Conditions": [
{
"Condition": "NotEquals",
"Property": "IsAnamorphic",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "EqualsAny",
"Property": "VideoProfile",
"Value": "main|main 10",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "LessThanEqual",
"Property": "VideoLevel",
"Value": "183",
"IsRequired": false,
"$type": "ProfileCondition"
},
{
"Condition": "NotEquals",
"Property": "IsInterlaced",
"Value": "true",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "hevc",
"$type": "CodecProfile"
}
],
"ResponseProfiles": [
{
"Container": "m4v",
"Type": "Video",
"MimeType": "video/mp4",
"$type": "ResponseProfile"
}
],
"SubtitleProfiles": [
{
"Format": "vtt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "External",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,139 @@
{
"Name": "Jellyfin Media Player",
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxStreamingBitrate": 20000000,
"MaxStaticBitrate": 20000000,
"MusicStreamingTranscodingBitrate": 1280000,
"TimelineOffsetSeconds": 5,
"TranscodingProfiles": [
{
"Type": "Audio",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp4",
"Type": "Video",
"AudioCodec": "aac,flac,alac",
"VideoCodec": "hevc,h264",
"Context": "Streaming",
"Protocol": "hls",
"MaxAudioChannels": "2",
"MinSegments": "2",
"BreakOnNonKeyFrames": true,
"$type": "TranscodingProfile"
},
{
"Container": "ts",
"Type": "Video",
"AudioCodec": "aac,mp3",
"VideoCodec": "h264",
"Context": "Streaming",
"Protocol": "hls",
"MaxAudioChannels": "2",
"MinSegments": "2",
"BreakOnNonKeyFrames": true,
"$type": "TranscodingProfile"
},
{
"Container": "webm",
"Type": "Video",
"AudioCodec": "vorbis",
"VideoCodec": "vp9,vp8,vpx,av1",
"Context": "Streaming",
"Protocol": "http",
"MaxAudioChannels": "2",
"$type": "TranscodingProfile"
},
{
"Container": "jpeg",
"Type": "Photo",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"SubtitleProfiles": [
{
"Format": "srt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "pgssub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "dvdsub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "pgs",
"Method": "Embed",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,189 @@
{
"EnableAlbumArtInDidl": false,
"EnableSingleAlbumArtLimit": false,
"EnableSingleSubtitleLimit": false,
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxAlbumArtWidth": 0,
"MaxAlbumArtHeight": 0,
"MaxStreamingBitrate": 120000000,
"MaxStaticBitrate": 100000000,
"MusicStreamingTranscodingBitrate": 192000,
"TimelineOffsetSeconds": 0,
"RequiresPlainVideoItems": false,
"RequiresPlainFolders": false,
"EnableMSMediaReceiverRegistrar": false,
"IgnoreTranscodeByteRangeRequests": false,
"DirectPlayProfiles": [
{
"Container": "",
"AudioCodec": "aac",
"VideoCodec": "",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "ts,mp4,mka,m4a,mp3,mp2,wav,flac,ogg",
"AudioCodec": "",
"VideoCodec": "",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "",
"AudioCodec": "",
"VideoCodec": "",
"Type": "Photo",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Container": "ts",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "aac",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": true,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"VideoCodec": "",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"VideoCodec": "",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"CodecProfiles": [
{
"Type": "VideoAudio",
"Conditions": [
{
"Condition": "Equals",
"Property": "IsSecondaryAudio",
"Value": "false",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "",
"Container": "",
"$type": "CodecProfile"
}
],
"ResponseProfiles": [
{
"Container": "m4v",
"Type": "Video",
"MimeType": "video/mp4",
"$type": "ResponseProfile"
},
{
"Container": "mov",
"Type": "Video",
"MimeType": "video/webm",
"$type": "ResponseProfile"
}
],
"SubtitleProfiles": [
{
"Format": "vtt",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "subrip",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "dvdsub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "pgs",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "pgssub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "External",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,189 @@
{
"EnableAlbumArtInDidl": false,
"EnableSingleAlbumArtLimit": false,
"EnableSingleSubtitleLimit": false,
"SupportedMediaTypes": "Audio,Photo,Video",
"MaxAlbumArtWidth": 0,
"MaxAlbumArtHeight": 0,
"MaxStreamingBitrate": 120000000,
"MaxStaticBitrate": 100000000,
"MusicStreamingTranscodingBitrate": 192000,
"TimelineOffsetSeconds": 0,
"RequiresPlainVideoItems": false,
"RequiresPlainFolders": false,
"EnableMSMediaReceiverRegistrar": false,
"IgnoreTranscodeByteRangeRequests": false,
"DirectPlayProfiles": [
{
"Container": "",
"AudioCodec": "aac",
"VideoCodec": "",
"Type": "Video",
"$type": "DirectPlayProfile"
},
{
"Container": "ts,mp4,mka,m4a,mp3,mp2,wav,flac,ogg",
"AudioCodec": "",
"VideoCodec": "",
"Type": "Audio",
"$type": "DirectPlayProfile"
},
{
"Container": "",
"AudioCodec": "",
"VideoCodec": "",
"Type": "Photo",
"$type": "DirectPlayProfile"
}
],
"TranscodingProfiles": [
{
"Container": "ts",
"Type": "Video",
"VideoCodec": "h264",
"AudioCodec": "aac",
"Protocol": "hls",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": true,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"VideoCodec": "",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Static",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
},
{
"Container": "mp3",
"Type": "Audio",
"VideoCodec": "",
"AudioCodec": "mp3",
"Protocol": "http",
"EstimateContentLength": false,
"EnableMpegtsM2TsMode": false,
"TranscodeSeekInfo": "Auto",
"CopyTimestamps": false,
"Context": "Streaming",
"EnableSubtitlesInManifest": false,
"MaxAudioChannels": "6",
"MinSegments": 0,
"SegmentLength": 0,
"BreakOnNonKeyFrames": false,
"$type": "TranscodingProfile"
}
],
"CodecProfiles": [
{
"Type": "VideoAudio",
"Conditions": [
{
"Condition": "Equals",
"Property": "IsSecondaryAudio",
"Value": "false",
"IsRequired": false,
"$type": "ProfileCondition"
}
],
"Codec": "",
"Container": "",
"$type": "CodecProfile"
}
],
"ResponseProfiles": [
{
"Container": "m4v",
"Type": "Video",
"MimeType": "video/mp4",
"$type": "ResponseProfile"
},
{
"Container": "mov",
"Type": "Video",
"MimeType": "video/webm",
"$type": "ResponseProfile"
}
],
"SubtitleProfiles": [
{
"Format": "vtt",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ass",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "ssa",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "smi",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "subrip",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "dvdsub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "pgs",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "pgssub",
"Method": "Embed",
"$type": "SubtitleProfile"
},
{
"Format": "srt",
"Method": "External",
"$type": "SubtitleProfile"
},
{
"Format": "sub",
"Method": "External",
"$type": "SubtitleProfile"
}
],
"$type": "DeviceProfile"
}

@ -0,0 +1,73 @@
{
"Id": "a766d122b58e45d9492d17af66748bf5",
"Path": "/Media/MyVideo-720p.mkv",
"Container": "mkv,webm",
"Size": 835317696,
"Name": "MyVideo-1080p",
"ETag": "579a34c6d5dfb23f61539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "av1",
"Language": "eng",
"ColorTransfer": "bt709",
"ColorPrimaries": "bt709",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "1080p AV1 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Main",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": -99
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 1,
"Score": 203
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,72 @@
{
"Id": "a766d122b58e45d9492d17af66748bf5",
"Path": "/Media/MyVideo-720p.mkv",
"Container": "mkv,webm",
"Size": 835317696,
"Name": "MyVideo-1080p",
"ETag": "579a34c6d5dfb23f61539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "av1",
"Language": "eng",
"ColorTransfer": "bt709",
"ColorPrimaries": "bt709",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "1080p AV1 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Main",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": -99
},
{
"Codec": "vorbis",
"CodecTag": "ogg",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Vorbis - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 203
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,73 @@
{
"Id": "a766d122b58e45d9492d17af66748bf5",
"Path": "/Media/MyVideo-720p.mkv",
"Container": "mkv,webm",
"Size": 835317696,
"Name": "MyVideo-1080p",
"ETag": "579a34c6d5dfb23f61539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "vp9",
"Language": "eng",
"ColorTransfer": "bt709",
"ColorPrimaries": "bt709",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "1080p VP9 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Profile 0",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": -99
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 1,
"Score": 203
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,72 @@
{
"Id": "a766d122b58e45d9492d17af66748bf5",
"Path": "/Media/MyVideo-720p.mkv",
"Container": "mkv,webm",
"Size": 835317696,
"Name": "MyVideo-1080p",
"ETag": "579a34c6d5dfb23f61539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "vp9",
"Language": "eng",
"ColorTransfer": "bt709",
"ColorPrimaries": "bt709",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "1080p VP9 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Profile 0",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": -99
},
{
"Codec": "ac3",
"CodecTag": "ac-3",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Dolby Digital - 5.1 - Default",
"ChannelLayout": "5.1",
"BitRate": 384000,
"Channels": 6,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 202
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,73 @@
{
"Id": "a766d122b58e45d9492d17af66748bf5",
"Path": "/Media/MyVideo-720p.mkv",
"Container": "mkv,webm",
"Size": 835317696,
"Name": "MyVideo-1080p",
"ETag": "579a34c6d5dfb23f61539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "vp9",
"Language": "eng",
"ColorTransfer": "bt709",
"ColorPrimaries": "bt709",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "1080p VP9 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Profile 0",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": -99
},
{
"Codec": "vorbis",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Vorbis - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 1,
"Score": 203
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
}
],
"Bitrate": 2590008,
"RequiredHttpHeaders": {},
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,72 @@
{
"Id": "a766d122b58e45d9492d17af66748bf5",
"Path": "/Media/MyVideo-720p.mkv",
"Container": "mkv,webm",
"Size": 835317696,
"Name": "MyVideo-1080p",
"ETag": "579a34c6d5dfb23f61539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "vp9",
"Language": "eng",
"ColorTransfer": "bt709",
"ColorPrimaries": "bt709",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "1080p VP9 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Profile 0",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": -99
},
{
"Codec": "vorbis",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Vorbis - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 1,
"Score": 203
},
{
"Codec": "webvtt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,72 @@
{
"Id": "a766d122b58e45d9492d17af77748bf5",
"Path": "/Media/MyVideo-720p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 835317696,
"Name": "MyVideo-720p",
"ETag": "579a34c6d5dfb21d81539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "h264",
"CodecTag": "avc1",
"Language": "eng",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "720p H264 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "High",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": 41
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 1,
"Score": 203
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,72 @@
{
"Id": "a766d122b58e45d9492d17af77748bf5",
"Path": "/Media/MyVideo-720p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 835317696,
"Name": "MyVideo-720p",
"ETag": "579a34c6d5dfb21d81539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "h264",
"CodecTag": "avc1",
"Language": "eng",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "720p H264 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "High",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": 41
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 1,
"Score": 203
},
{
"Codec": "webvtt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,87 @@
{
"Id": "a766d122b58e45d9492d17af77748bf5",
"Path": "/Media/MyVideo-720p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 835317696,
"Name": "MyVideo-720p",
"ETag": "579a34c6d5dfb21d81539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "h264",
"CodecTag": "avc1",
"Language": "eng",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "720p H264 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "High",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": 41
},
{
"Codec": "ac3",
"CodecTag": "ac-3",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Dolby Digital - 5.1 - Default",
"ChannelLayout": "5.1",
"BitRate": 384000,
"Channels": 6,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 202
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 2,
"Score": 203
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 3,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true,
"Path": "/Media/MyVideo-WEBDL-2160p.default.eng.srt"
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 3
}

@ -0,0 +1,87 @@
{
"Id": "a766d122b58e45d9492d17af77748bf5",
"Path": "/Media/MyVideo-720p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 835317696,
"Name": "MyVideo-720p",
"ETag": "579a34c6d5dfb21d81539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "h264",
"CodecTag": "avc1",
"Language": "eng",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "720p H264 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "High",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": 41
},
{
"Codec": "ac3",
"CodecTag": "ac-3",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Dolby Digital - 5.1 - Default",
"ChannelLayout": "5.1",
"BitRate": 384000,
"Channels": 6,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 202
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 2,
"Score": 203
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 3,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true,
"Path": "/Media/MyVideo-WEBDL-2160p.default.eng.srt"
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 2,
"DefaultSubtitleStreamIndex": 3
}

@ -0,0 +1,89 @@
{
"Id": "a766d122b58e45d9492d17af77748bf5",
"Path": "/Media/MyVideo-720p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 835317696,
"Name": "MyVideo-720p",
"ETag": "579a34c6d5dfb21d81539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "h264",
"CodecTag": "avc1",
"Language": "eng",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "720p H264 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "High",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": 41
},
{
"Codec": "ac3",
"CodecTag": "ac-3",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Dolby Digital - 5.1 - Default",
"ChannelLayout": "5.1",
"BitRate": 384000,
"Channels": 6,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 202
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"IsExternal": true,
"Profile": "LC",
"Index": 2,
"Score": 203,
"Path": "/Media/MyVideo-WEBDL-2160p.default.eng.srt"
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 3,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true,
"Path": "/Media/MyVideo-WEBDL-2160p.default.eng.srt"
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 3
}

@ -0,0 +1,71 @@
{
"Id": "a766d122b58e45d9492d17af77748bf5",
"Path": "/Media/MyVideo-720p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 835317696,
"Name": "MyVideo-720p",
"ETag": "579a34c6d5dfb21d81539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "h264",
"CodecTag": "avc1",
"Language": "eng",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "720p H264 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "High",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": 41
},
{
"Codec": "ac3",
"CodecTag": "ac-3",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Dolby Digital - 5.1 - Default",
"ChannelLayout": "5.1",
"BitRate": 384000,
"Channels": 6,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 202
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
}
],
"Bitrate": 2590008,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,75 @@
{
"Id": "f6eab7118618ab26e61e495a1853481a",
"Path": "/Media/MyVideo-WEBDL-2160p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 6521110016,
"Name": "MyVideo WEBDL-2160p",
"ETag": "a2fb84b618ba2467fe377543f879e9bf",
"RunTimeTicks": 34318510080,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "hevc",
"CodecTag": "hev1",
"Language": "eng",
"ColorSpace": "bt2020nc",
"ColorTransfer": "smpte2084",
"ColorPrimaries": "bt2020",
"TimeBase": "1/16000",
"VideoRange": "HDR",
"DisplayTitle": "4K HEVC HDR",
"BitRate": 14715079,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 2160,
"Width": 3840,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Main 10",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p10le",
"Level": 150
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 1,
"Score": 203
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true,
"Path": "/Media/MyVideo-WEBDL-2160p.default.eng.srt"
}
],
"Bitrate": 15201382,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,89 @@
{
"Id": "f6eab7118618ab26e61e495a1853481a",
"Path": "/Media/MyVideo-WEBDL-2160p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 6521110016,
"Name": "MyVideo WEBDL-2160p",
"ETag": "a2fb84b618ba2467fe377543f879e9bf",
"RunTimeTicks": 34318510080,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "hevc",
"CodecTag": "hev1",
"Language": "eng",
"ColorSpace": "bt2020nc",
"ColorTransfer": "smpte2084",
"ColorPrimaries": "bt2020",
"TimeBase": "1/16000",
"VideoRange": "HDR",
"DisplayTitle": "4K HEVC HDR",
"BitRate": 14715079,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 2160,
"Width": 3840,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Main 10",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p10le",
"Level": 150
},
{
"Codec": "ac3",
"CodecTag": "ac-3",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Dolby Digital - 5.1 - Default",
"ChannelLayout": "5.1",
"BitRate": 384000,
"Channels": 6,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 202
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 2,
"Score": 203
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 3,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true,
"Path": "/Media/MyVideo-WEBDL-2160p.default.eng.srt"
}
],
"Bitrate": 15201382,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 3
}

@ -0,0 +1,91 @@
{
"Id": "f6eab7118618ab26e61e495a1853481a",
"Path": "/Media/MyVideo-WEBDL-2160p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 6521110016,
"Name": "MyVideo WEBDL-2160p",
"ETag": "a2fb84b618ba2467fe377543f879e9bf",
"RunTimeTicks": 34318510080,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "hevc",
"CodecTag": "hev1",
"Language": "eng",
"ColorSpace": "bt2020nc",
"ColorTransfer": "smpte2084",
"ColorPrimaries": "bt2020",
"TimeBase": "1/16000",
"VideoRange": "HDR",
"DisplayTitle": "4K HEVC HDR",
"BitRate": 14715079,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 2160,
"Width": 3840,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Main 10",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p10le",
"Level": 150
},
{
"Codec": "ac3",
"CodecTag": "ac-3",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Dolby Digital - 5.1 - Default",
"ChannelLayout": "5.1",
"BitRate": 384000,
"Channels": 6,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 202
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"IsExternal": true,
"Profile": "LC",
"Index": 2,
"Score": 203,
"Path": "/Media/MyVideo-WEBDL-2160p.eng.m4a"
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 3,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true,
"Path": "/Media/MyVideo-WEBDL-2160p.default.eng.srt"
}
],
"Bitrate": 15201382,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 3
}

@ -0,0 +1,74 @@
{
"Id": "f6eab7118618ab26e61e495a1853481a",
"Path": "/Media/MyVideo-WEBDL-2160p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 6521110016,
"Name": "MyVideo WEBDL-2160p",
"ETag": "a2fb84b618ba2467fe377543f879e9bf",
"RunTimeTicks": 34318510080,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "hevc",
"CodecTag": "hev1",
"Language": "eng",
"ColorSpace": "bt2020nc",
"ColorTransfer": "smpte2084",
"ColorPrimaries": "bt2020",
"TimeBase": "1/16000",
"VideoRange": "HDR",
"DisplayTitle": "4K HEVC HDR",
"BitRate": 14715079,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 2160,
"Width": 3840,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "Main 10",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p10le",
"Level": 150
},
{
"Codec": "ac3",
"CodecTag": "ac-3",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Dolby Digital - 5.1 - Default",
"ChannelLayout": "5.1",
"BitRate": 384000,
"Channels": 6,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 202
},
{
"Codec": "srt",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 2,
"Score": 6421,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true,
"Path": "/Media/MyVideo-WEBDL-2160p.default.eng.srt"
}
],
"Bitrate": 15201382,
"DefaultAudioStreamIndex": 1,
"DefaultSubtitleStreamIndex": 2
}

@ -0,0 +1,102 @@
{
"Id": "a766d122b58e45d9492d17af77748bf5",
"Path": "/Media/MyVideo-720p.mp4",
"Container": "mov,mp4,m4a,3gp,3g2,mj2",
"Size": 835317696,
"Name": "MyVideo-720p",
"ETag": "579a34c6d5dfb21d81539a51220b6a23",
"RunTimeTicks": 25801230336,
"SupportsTranscoding": true,
"SupportsDirectStream": true,
"SupportsDirectPlay": true,
"SupportsProbing": true,
"MediaStreams": [
{
"Codec": "h264",
"CodecTag": "avc1",
"Language": "eng",
"TimeBase": "1/11988",
"VideoRange": "SDR",
"DisplayTitle": "720p H264 SDR",
"NalLengthSize": "0",
"BitRate": 2032876,
"BitDepth": 8,
"RefFrames": 1,
"IsDefault": true,
"Height": 720,
"Width": 1280,
"AverageFrameRate": 23.976,
"RealFrameRate": 23.976,
"Profile": "High",
"Type": 1,
"AspectRatio": "16:9",
"PixelFormat": "yuv420p",
"Level": 41
},
{
"Codec": "ac3",
"CodecTag": "ac-3",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - Dolby Digital - 5.1 - Default",
"ChannelLayout": "5.1",
"BitRate": 384000,
"Channels": 6,
"SampleRate": 48000,
"IsDefault": true,
"Index": 1,
"Score": 202
},
{
"Codec": "aac",
"CodecTag": "mp4a",
"Language": "eng",
"TimeBase": "1/48000",
"DisplayTitle": "En - AAC - Stereo - Default",
"ChannelLayout": "stereo",
"BitRate": 164741,
"Channels": 2,
"SampleRate": 48000,
"IsDefault": true,
"Profile": "LC",
"Index": 2,
"Score": 203
},
{
"Codec": "mov_text",
"CodecTag": "tx3g",
"Language": "eng",
"TimeBase": "1/1000000",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"BitRate": 92,
"IsDefault": true,
"Type": 2,
"Index": 3,
"Score": 6421,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true
},
{
"Codec": "srt",
"Language": "eng",
"localizedUndefined": "Undefined",
"localizedDefault": "Default",
"localizedForced": "Forced",
"DisplayTitle": "En - Default",
"IsDefault": true,
"Type": 2,
"Index": 4,
"Score": 6422,
"IsExternal": true,
"IsTextSubtitleStream": true,
"SupportsExternalStream": true,
"Path": "/Media/MyVideo-WEBDL-2160p.default.eng.srt"
}
],
"Bitrate": 2590008,
"RequiredHttpHeaders": {},
"DefaultSubtitleStreamIndex": 1
}

@ -0,0 +1,28 @@
using System.Text.Json;
using Jellyfin.Extensions.Json.Converters;
using MediaBrowser.Model.Session;
using Xunit;
namespace Jellyfin.Extensions.Tests.Json.Converters;
public class JsonFlagEnumTests
{
private readonly JsonSerializerOptions _jsonOptions = new()
{
Converters =
{
new JsonFlagEnumConverter<TranscodeReason>()
}
};
[Theory]
[InlineData(TranscodeReason.AudioIsExternal | TranscodeReason.ContainerNotSupported, "[\"ContainerNotSupported\",\"AudioIsExternal\"]")]
[InlineData(TranscodeReason.AudioIsExternal | TranscodeReason.ContainerNotSupported | TranscodeReason.VideoBitDepthNotSupported, "[\"ContainerNotSupported\",\"AudioIsExternal\",\"VideoBitDepthNotSupported\"]")]
[InlineData((TranscodeReason)0, "[]")]
public void Serialize_Transcode_Reason(TranscodeReason transcodeReason, string output)
{
var result = JsonSerializer.Serialize(transcodeReason, _jsonOptions);
Assert.Equal(output, result);
}
}
Loading…
Cancel
Save