aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api/Playback/BaseStreamingService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Api/Playback/BaseStreamingService.cs')
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs375
1 files changed, 242 insertions, 133 deletions
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index f1b84875d..0858a0347 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1,4 +1,4 @@
-using System.Net.WebSockets;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Channels;
@@ -14,7 +14,6 @@ using MediaBrowser.Model.Drawing;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
-using MediaBrowser.Model.LiveTv;
using MediaBrowser.Model.MediaInfo;
using System;
using System.Collections.Generic;
@@ -120,13 +119,14 @@ namespace MediaBrowser.Api.Playback
/// <returns>System.String.</returns>
private string GetOutputFilePath(StreamState state)
{
- var folder = ServerConfigurationManager.ApplicationPaths.TranscodingTempPath;
-
+ var folder = Path.Combine(ServerConfigurationManager.ApplicationPaths.TranscodingTempPath, EncodingContext.Streaming.ToString().ToLower());
+
var outputFileExtension = GetOutputFileExtension(state);
var data = GetCommandLineArguments("dummy\\dummy", "dummyTranscodingId", state, false);
data += "-" + (state.Request.DeviceId ?? string.Empty);
+ data += "-" + (state.Request.ClientTime ?? string.Empty);
return Path.Combine(folder, data.GetMD5().ToString("N") + (outputFileExtension ?? string.Empty).ToLower());
}
@@ -203,6 +203,10 @@ namespace MediaBrowser.Api.Playback
{
args += " -map -0:s";
}
+ else if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
+ {
+ args += " -map 1:0 -sn";
+ }
return args;
}
@@ -246,7 +250,7 @@ namespace MediaBrowser.Api.Playback
protected EncodingQuality GetQualitySetting()
{
- var quality = ServerConfigurationManager.Configuration.MediaEncodingQuality;
+ var quality = ApiEntryPoint.Instance.GetEncodingOptions().EncodingQuality;
if (quality == EncodingQuality.Auto)
{
@@ -267,9 +271,14 @@ namespace MediaBrowser.Api.Playback
/// Gets the number of threads.
/// </summary>
/// <returns>System.Int32.</returns>
- /// <exception cref="System.Exception">Unrecognized MediaEncodingQuality value.</exception>
protected int GetNumberOfThreads(StreamState state, bool isWebm)
{
+ if (isWebm)
+ {
+ // Recommended per docs
+ return Math.Max(Environment.ProcessorCount - 1, 2);
+ }
+
// Use more when this is true. -re will keep cpu usage under control
if (state.ReadInputAtNativeFramerate)
{
@@ -298,6 +307,21 @@ namespace MediaBrowser.Api.Playback
}
}
+ protected string H264Encoder
+ {
+ get
+ {
+ var lib = ApiEntryPoint.Instance.GetEncodingOptions().H264Encoder;
+
+ if (!string.IsNullOrWhiteSpace(lib))
+ {
+ return lib;
+ }
+
+ return "libx264";
+ }
+ }
+
/// <summary>
/// Gets the video bitrate to specify on the command line
/// </summary>
@@ -314,7 +338,7 @@ namespace MediaBrowser.Api.Playback
var qualitySetting = GetQualitySetting();
- if (string.Equals(videoCodec, "libx264", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(videoCodec, H264Encoder, StringComparison.OrdinalIgnoreCase))
{
switch (qualitySetting)
{
@@ -438,7 +462,7 @@ namespace MediaBrowser.Api.Playback
{
if (state.AudioStream != null && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5)
{
- volParam = ",volume=" + ServerConfigurationManager.Configuration.DownMixAudioBoost.ToString(UsCulture);
+ volParam = ",volume=" + ApiEntryPoint.Instance.GetEncodingOptions().DownMixAudioBoost.ToString(UsCulture);
}
}
@@ -647,9 +671,18 @@ namespace MediaBrowser.Api.Playback
videoSizeParam = string.Format(",scale={0}:{1}", state.VideoStream.Width.Value.ToString(UsCulture), state.VideoStream.Height.Value.ToString(UsCulture));
}
- return string.Format(" -filter_complex \"[0:{0}]format=yuva444p{3},lut=u=128:v=128:y=gammaval(.3)[sub] ; [0:{1}] [sub] overlay{2}\"",
- state.SubtitleStream.Index,
- state.VideoStream.Index,
+ var mapPrefix = state.SubtitleStream.IsExternal ?
+ 1 :
+ 0;
+
+ var subtitleStreamIndex = state.SubtitleStream.IsExternal
+ ? 0
+ : state.SubtitleStream.Index;
+
+ return string.Format(" -filter_complex \"[{0}:{1}]format=yuva444p{4},lut=u=128:v=128:y=gammaval(.3)[sub] ; [0:{2}] [sub] overlay{3}\"",
+ mapPrefix.ToString(UsCulture),
+ subtitleStreamIndex.ToString(UsCulture),
+ state.VideoStream.Index.ToString(UsCulture),
outputSizeParam,
videoSizeParam);
}
@@ -696,7 +729,8 @@ namespace MediaBrowser.Api.Playback
return Math.Min(request.MaxAudioChannels.Value, audioStream.Channels.Value);
}
- return request.MaxAudioChannels.Value;
+ // If we don't have any media info then limit it to 5 to prevent encoding errors due to asking for too many channels
+ return Math.Min(request.MaxAudioChannels.Value, 5);
}
return request.AudioChannels;
@@ -709,8 +743,10 @@ namespace MediaBrowser.Api.Playback
/// <returns><c>true</c> if the specified stream is H264; otherwise, <c>false</c>.</returns>
protected bool IsH264(MediaStream stream)
{
- return stream.Codec.IndexOf("264", StringComparison.OrdinalIgnoreCase) != -1 ||
- stream.Codec.IndexOf("avc", StringComparison.OrdinalIgnoreCase) != -1;
+ var codec = stream.Codec ?? string.Empty;
+
+ return codec.IndexOf("264", StringComparison.OrdinalIgnoreCase) != -1 ||
+ codec.IndexOf("avc", StringComparison.OrdinalIgnoreCase) != -1;
}
/// <summary>
@@ -755,7 +791,7 @@ namespace MediaBrowser.Api.Playback
{
if (string.Equals(codec, "h264", StringComparison.OrdinalIgnoreCase))
{
- return "libx264";
+ return H264Encoder;
}
if (string.Equals(codec, "vpx", StringComparison.OrdinalIgnoreCase))
{
@@ -778,24 +814,9 @@ namespace MediaBrowser.Api.Playback
private bool SupportsThrottleWithStream
{
- // TODO: These checks are a hack.
- // They should go through the IHttpServer interface or IServerManager to find out this information
-
get
{
-#if __MonoCS__
- return true;
-#endif
-
- try
- {
- new ClientWebSocket();
- return true;
- }
- catch
- {
- return false;
- }
+ return false;
}
}
@@ -807,6 +828,21 @@ namespace MediaBrowser.Api.Playback
/// <returns>System.String.</returns>
protected string GetInputArgument(string transcodingJobId, StreamState state)
{
+ var arg = "-i " + GetInputPathArgument(transcodingJobId, state);
+
+ if (state.SubtitleStream != null)
+ {
+ if (state.SubtitleStream.IsExternal && !state.SubtitleStream.IsTextSubtitleStream)
+ {
+ arg += " -i " + state.SubtitleStream.Path;
+ }
+ }
+
+ return arg;
+ }
+
+ private string GetInputPathArgument(string transcodingJobId, StreamState state)
+ {
if (state.InputProtocol == MediaProtocol.File &&
state.RunTimeTicks.HasValue &&
state.VideoType == VideoType.VideoFile &&
@@ -857,20 +893,12 @@ namespace MediaBrowser.Api.Playback
state.LiveTvStreamId = streamInfo.Id;
- if (!string.IsNullOrEmpty(streamInfo.Path))
- {
- state.MediaPath = streamInfo.Path;
- state.InputProtocol = MediaProtocol.File;
+ state.MediaPath = streamInfo.Path;
+ state.InputProtocol = streamInfo.Protocol;
- await Task.Delay(1500, cancellationTokenSource.Token).ConfigureAwait(false);
- }
- else if (!string.IsNullOrEmpty(streamInfo.Url))
- {
- state.MediaPath = streamInfo.Url;
- state.InputProtocol = MediaProtocol.Http;
- }
+ await Task.Delay(1500, cancellationTokenSource.Token).ConfigureAwait(false);
- AttachMediaStreamInfo(state, streamInfo.MediaStreams, state.VideoRequest, state.RequestedUrl);
+ AttachMediaStreamInfo(state, streamInfo, state.VideoRequest, state.RequestedUrl);
checkCodecs = true;
}
@@ -881,20 +909,12 @@ namespace MediaBrowser.Api.Playback
state.LiveTvStreamId = streamInfo.Id;
- if (!string.IsNullOrEmpty(streamInfo.Path))
- {
- state.MediaPath = streamInfo.Path;
- state.InputProtocol = MediaProtocol.File;
+ state.MediaPath = streamInfo.Path;
+ state.InputProtocol = streamInfo.Protocol;
- await Task.Delay(1500, cancellationTokenSource.Token).ConfigureAwait(false);
- }
- else if (!string.IsNullOrEmpty(streamInfo.Url))
- {
- state.MediaPath = streamInfo.Url;
- state.InputProtocol = MediaProtocol.Http;
- }
+ await Task.Delay(1500, cancellationTokenSource.Token).ConfigureAwait(false);
- AttachMediaStreamInfo(state, streamInfo.MediaStreams, state.VideoRequest, state.RequestedUrl);
+ AttachMediaStreamInfo(state, streamInfo, state.VideoRequest, state.RequestedUrl);
checkCodecs = true;
}
@@ -921,15 +941,13 @@ namespace MediaBrowser.Api.Playback
/// <param name="state">The state.</param>
/// <param name="outputPath">The output path.</param>
/// <param name="cancellationTokenSource">The cancellation token source.</param>
+ /// <param name="workingDirectory">The working directory.</param>
/// <returns>Task.</returns>
- /// <exception cref="System.InvalidOperationException">ffmpeg was not found at + MediaEncoder.EncoderPath</exception>
- protected async Task<TranscodingJob> StartFfMpeg(StreamState state, string outputPath, CancellationTokenSource cancellationTokenSource)
+ protected async Task<TranscodingJob> StartFfMpeg(StreamState state,
+ string outputPath,
+ CancellationTokenSource cancellationTokenSource,
+ string workingDirectory = null)
{
- if (!File.Exists(MediaEncoder.EncoderPath))
- {
- throw new InvalidOperationException("ffmpeg was not found at " + MediaEncoder.EncoderPath);
- }
-
Directory.CreateDirectory(Path.GetDirectoryName(outputPath));
await AcquireResources(state, cancellationTokenSource).ConfigureAwait(false);
@@ -937,7 +955,7 @@ namespace MediaBrowser.Api.Playback
var transcodingId = Guid.NewGuid().ToString("N");
var commandLineArgs = GetCommandLineArguments(outputPath, transcodingId, state, true);
- if (ServerConfigurationManager.Configuration.EnableDebugEncodingLogging)
+ if (ApiEntryPoint.Instance.GetEncodingOptions().EnableDebugLogging)
{
commandLineArgs = "-loglevel debug " + commandLineArgs;
}
@@ -955,7 +973,6 @@ namespace MediaBrowser.Api.Playback
RedirectStandardInput = true,
FileName = MediaEncoder.EncoderPath,
- WorkingDirectory = Path.GetDirectoryName(MediaEncoder.EncoderPath),
Arguments = commandLineArgs,
WindowStyle = ProcessWindowStyle.Hidden,
@@ -965,6 +982,11 @@ namespace MediaBrowser.Api.Playback
EnableRaisingEvents = true
};
+ if (!string.IsNullOrWhiteSpace(workingDirectory))
+ {
+ process.StartInfo.WorkingDirectory = workingDirectory;
+ }
+
var transcodingJob = ApiEntryPoint.Instance.OnTranscodeBeginning(outputPath,
transcodingId,
TranscodingJobType,
@@ -1007,11 +1029,21 @@ namespace MediaBrowser.Api.Playback
StartStreamingLog(transcodingJob, state, process.StandardError.BaseStream, state.LogFileStream);
// Wait for the file to exist before proceeeding
- while (!File.Exists(outputPath))
+ while (!File.Exists(outputPath) && !transcodingJob.HasExited)
{
await Task.Delay(100, cancellationTokenSource.Token).ConfigureAwait(false);
}
+ if (state.IsInputVideo && transcodingJob.Type == TranscodingJobType.Progressive)
+ {
+ await Task.Delay(1000, cancellationTokenSource.Token).ConfigureAwait(false);
+
+ if (state.ReadInputAtNativeFramerate)
+ {
+ await Task.Delay(1500, cancellationTokenSource.Token).ConfigureAwait(false);
+ }
+ }
+
return transcodingJob;
}
@@ -1101,7 +1133,7 @@ namespace MediaBrowser.Api.Playback
if (scale.HasValue)
{
long val;
-
+
if (long.TryParse(size, NumberStyles.Any, UsCulture, out val))
{
bytesTranscoded = val * scale.Value;
@@ -1390,6 +1422,38 @@ namespace MediaBrowser.Api.Playback
videoRequest.Level = val;
}
}
+ else if (i == 16)
+ {
+ request.ClientTime = val;
+ }
+ else if (i == 17)
+ {
+ if (videoRequest != null)
+ {
+ videoRequest.MaxRefFrames = int.Parse(val, UsCulture);
+ }
+ }
+ else if (i == 18)
+ {
+ if (videoRequest != null)
+ {
+ videoRequest.MaxVideoBitDepth = int.Parse(val, UsCulture);
+ }
+ }
+ else if (i == 19)
+ {
+ if (videoRequest != null)
+ {
+ videoRequest.Profile = val;
+ }
+ }
+ else if (i == 20)
+ {
+ if (videoRequest != null)
+ {
+ videoRequest.Cabac = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
+ }
+ }
}
}
@@ -1525,23 +1589,14 @@ namespace MediaBrowser.Api.Playback
state.MediaPath = mediaUrl;
state.InputProtocol = MediaProtocol.Http;
}
- else
- {
- // No media info, so this is probably needed
- state.DeInterlace = true;
- }
-
- if (recording.RecordingInfo.Status == RecordingStatus.InProgress)
- {
- state.ReadInputAtNativeFramerate = true;
- }
state.RunTimeTicks = recording.RunTimeTicks;
-
+ state.DeInterlace = true;
state.OutputAudioSync = "1000";
state.InputVideoSync = "-1";
state.InputAudioSync = "1";
state.InputContainer = recording.Container;
+ state.ReadInputAtNativeFramerate = source.ReadAtNativeFramerate;
}
else if (item is LiveTvChannel)
{
@@ -1551,11 +1606,7 @@ namespace MediaBrowser.Api.Playback
state.IsInputVideo = string.Equals(channel.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase);
mediaStreams = new List<MediaStream>();
- state.ReadInputAtNativeFramerate = true;
- state.OutputAudioSync = "1000";
state.DeInterlace = true;
- state.InputVideoSync = "-1";
- state.InputAudioSync = "1";
// Just to prevent this from being null and causing other methods to fail
state.MediaPath = string.Empty;
@@ -1570,6 +1621,7 @@ namespace MediaBrowser.Api.Playback
state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders;
state.InputBitrate = mediaSource.Bitrate;
state.InputFileSize = mediaSource.Size;
+ state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
mediaStreams = mediaSource.MediaStreams;
}
else
@@ -1586,8 +1638,11 @@ namespace MediaBrowser.Api.Playback
state.InputContainer = mediaSource.Container;
state.InputFileSize = mediaSource.Size;
state.InputBitrate = mediaSource.Bitrate;
+ state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
+
+ var video = item as Video;
- if (item is Video)
+ if (video != null)
{
state.IsInputVideo = true;
@@ -1609,30 +1664,17 @@ namespace MediaBrowser.Api.Playback
state.RunTimeTicks = mediaSource.RunTimeTicks;
}
- // If it's a wtv and we don't have media info, we will probably need to deinterlace
- if (string.Equals(state.InputContainer, "wtv", StringComparison.OrdinalIgnoreCase) &&
- mediaStreams.Count == 0)
- {
- state.DeInterlace = true;
- }
-
- if (state.InputProtocol == MediaProtocol.Rtmp)
- {
- state.ReadInputAtNativeFramerate = true;
- }
-
var videoRequest = request as VideoStreamRequest;
AttachMediaStreamInfo(state, mediaStreams, videoRequest, url);
- state.SegmentLength = state.ReadInputAtNativeFramerate ? 5 : 7;
- state.HlsListSize = state.ReadInputAtNativeFramerate ? 100 : 1440;
-
var container = Path.GetExtension(state.RequestedUrl);
if (string.IsNullOrEmpty(container))
{
- container = request.Static ? state.InputContainer : Path.GetExtension(GetOutputFilePath(state));
+ container = request.Static ?
+ state.InputContainer :
+ (Path.GetExtension(GetOutputFilePath(state)) ?? string.Empty).TrimStart('.');
}
state.OutputContainer = (container ?? string.Empty).TrimStart('.');
@@ -1648,6 +1690,17 @@ namespace MediaBrowser.Api.Playback
{
state.OutputVideoCodec = GetVideoCodec(videoRequest);
state.OutputVideoBitrate = GetVideoBitrateParamValue(state.VideoRequest, state.VideoStream);
+
+ if (state.OutputVideoBitrate.HasValue)
+ {
+ var resolution = ResolutionNormalizer.Normalize(state.OutputVideoBitrate.Value,
+ state.OutputVideoCodec,
+ videoRequest.MaxWidth,
+ videoRequest.MaxHeight);
+
+ videoRequest.MaxWidth = resolution.MaxWidth;
+ videoRequest.MaxHeight = resolution.MaxHeight;
+ }
}
ApplyDeviceProfileSettings(state);
@@ -1659,7 +1712,7 @@ namespace MediaBrowser.Api.Playback
state.OutputVideoCodec = "copy";
}
- if (state.AudioStream != null && CanStreamCopyAudio(request, state.AudioStream, state.SupportedAudioCodecs))
+ if (state.AudioStream != null && CanStreamCopyAudio(videoRequest, state.AudioStream, state.SupportedAudioCodecs))
{
state.OutputAudioCodec = "copy";
}
@@ -1671,6 +1724,31 @@ namespace MediaBrowser.Api.Playback
}
private void AttachMediaStreamInfo(StreamState state,
+ ChannelMediaInfo mediaInfo,
+ VideoStreamRequest videoRequest,
+ string requestedUrl)
+ {
+ var mediaSource = mediaInfo.ToMediaSource();
+
+ state.InputProtocol = mediaSource.Protocol;
+ state.MediaPath = mediaSource.Path;
+ state.RunTimeTicks = mediaSource.RunTimeTicks;
+ state.RemoteHttpHeaders = mediaSource.RequiredHttpHeaders;
+ state.InputBitrate = mediaSource.Bitrate;
+ state.InputFileSize = mediaSource.Size;
+ state.ReadInputAtNativeFramerate = mediaSource.ReadAtNativeFramerate;
+
+ if (state.ReadInputAtNativeFramerate)
+ {
+ state.OutputAudioSync = "1000";
+ state.InputVideoSync = "-1";
+ state.InputAudioSync = "1";
+ }
+
+ AttachMediaStreamInfo(state, mediaSource.MediaStreams, videoRequest, requestedUrl);
+ }
+
+ private void AttachMediaStreamInfo(StreamState state,
List<MediaStream> mediaStreams,
VideoStreamRequest videoRequest,
string requestedUrl)
@@ -1710,7 +1788,7 @@ namespace MediaBrowser.Api.Playback
string mediaSourceId,
CancellationToken cancellationToken)
{
- var channelMediaSources = await ChannelManager.GetChannelItemMediaSources(id, cancellationToken)
+ var channelMediaSources = await ChannelManager.GetChannelItemMediaSources(id, true, cancellationToken)
.ConfigureAwait(false);
var list = channelMediaSources.ToList();
@@ -1752,9 +1830,23 @@ namespace MediaBrowser.Api.Playback
}
// If client is requesting a specific video profile, it must match the source
- if (!string.IsNullOrEmpty(request.Profile) && !string.Equals(request.Profile, videoStream.Profile, StringComparison.OrdinalIgnoreCase))
+ if (!string.IsNullOrEmpty(request.Profile))
{
- return false;
+ if (string.IsNullOrEmpty(videoStream.Profile))
+ {
+ return false;
+ }
+
+ if (!string.Equals(request.Profile, videoStream.Profile, StringComparison.OrdinalIgnoreCase))
+ {
+ var currentScore = GetVideoProfileScore(videoStream.Profile);
+ var requestedScore = GetVideoProfileScore(request.Profile);
+
+ if (currentScore == -1 || currentScore > requestedScore)
+ {
+ return false;
+ }
+ }
}
// Video width must fall within requested value
@@ -1796,6 +1888,22 @@ namespace MediaBrowser.Api.Playback
}
}
+ if (request.MaxVideoBitDepth.HasValue)
+ {
+ if (videoStream.BitDepth.HasValue && videoStream.BitDepth.Value > request.MaxVideoBitDepth.Value)
+ {
+ return false;
+ }
+ }
+
+ if (request.MaxRefFrames.HasValue)
+ {
+ if (videoStream.RefFrames.HasValue && videoStream.RefFrames.Value > request.MaxRefFrames.Value)
+ {
+ return false;
+ }
+ }
+
// If a specific level was requested, the source must match or be less than
if (!string.IsNullOrEmpty(request.Level))
{
@@ -1815,10 +1923,34 @@ namespace MediaBrowser.Api.Playback
}
}
+ if (request.Cabac.HasValue && request.Cabac.Value)
+ {
+ if (videoStream.IsCabac.HasValue && !videoStream.IsCabac.Value)
+ {
+ return false;
+ }
+ }
+
return request.EnableAutoStreamCopy;
}
- private bool CanStreamCopyAudio(StreamRequest request, MediaStream audioStream, List<string> supportedAudioCodecs)
+ private int GetVideoProfileScore(string profile)
+ {
+ var list = new List<string>
+ {
+ "Constrained Baseline",
+ "Baseline",
+ "Extended",
+ "Main",
+ "High",
+ "Progressive High",
+ "Constrained High"
+ };
+
+ return Array.FindIndex(list.ToArray(), t => string.Equals(t, profile, StringComparison.OrdinalIgnoreCase));
+ }
+
+ private bool CanStreamCopyAudio(VideoStreamRequest request, MediaStream audioStream, List<string> supportedAudioCodecs)
{
// Source and target codecs must match
if (string.IsNullOrEmpty(audioStream.Codec) || !supportedAudioCodecs.Contains(audioStream.Codec, StringComparer.OrdinalIgnoreCase))
@@ -1866,7 +1998,7 @@ namespace MediaBrowser.Api.Playback
}
}
- return true;
+ return request.EnableAutoStreamCopy;
}
private void ApplyDeviceProfileSettings(StreamState state)
@@ -1890,19 +2022,9 @@ namespace MediaBrowser.Api.Playback
return;
}
- var audioCodec = state.OutputAudioCodec;
+ var audioCodec = state.ActualOutputAudioCodec;
- if (string.Equals(audioCodec, "copy", StringComparison.OrdinalIgnoreCase) && state.AudioStream != null)
- {
- audioCodec = state.AudioStream.Codec;
- }
-
- var videoCodec = state.OutputVideoCodec;
-
- if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase) && state.VideoStream != null)
- {
- videoCodec = state.VideoStream.Codec;
- }
+ var videoCodec = state.ActualOutputVideoCodec;
var mediaProfile = state.VideoRequest == null ?
profile.GetAudioMediaProfile(state.OutputContainer, audioCodec, state.OutputAudioChannels, state.OutputAudioBitrate) :
@@ -1921,6 +2043,7 @@ namespace MediaBrowser.Api.Playback
state.TargetPacketLength,
state.TargetTimestamp,
state.IsTargetAnamorphic,
+ state.IsTargetCabac,
state.TargetRefFrames);
if (mediaProfile != null)
@@ -1937,11 +2060,6 @@ namespace MediaBrowser.Api.Playback
state.EstimateContentLength = transcodingProfile.EstimateContentLength;
state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode;
state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
-
- if (state.VideoRequest != null && string.IsNullOrWhiteSpace(state.VideoRequest.Profile))
- {
- state.VideoRequest.Profile = transcodingProfile.VideoProfile;
- }
}
}
@@ -1970,12 +2088,7 @@ namespace MediaBrowser.Api.Playback
profile = DlnaManager.GetDefaultProfile();
}
- var audioCodec = state.OutputAudioCodec;
-
- if (string.Equals(audioCodec, "copy", StringComparison.OrdinalIgnoreCase) && state.AudioStream != null)
- {
- audioCodec = state.AudioStream.Codec;
- }
+ var audioCodec = state.ActualOutputAudioCodec;
if (state.VideoRequest == null)
{
@@ -1993,12 +2106,7 @@ namespace MediaBrowser.Api.Playback
}
else
{
- var videoCodec = state.OutputVideoCodec;
-
- if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase) && state.VideoStream != null)
- {
- videoCodec = state.VideoStream.Codec;
- }
+ var videoCodec = state.ActualOutputVideoCodec;
responseHeaders["contentFeatures.dlna.org"] = new ContentFeatureBuilder(profile)
.BuildVideoHeader(
@@ -2020,6 +2128,7 @@ namespace MediaBrowser.Api.Playback
state.TargetPacketLength,
state.TranscodeSeekInfo,
state.IsTargetAnamorphic,
+ state.IsTargetCabac,
state.TargetRefFrames
).FirstOrDefault() ?? string.Empty;