diff options
| author | Tim Hobbs <jesus.tesh@gmail.com> | 2014-04-06 11:01:26 -0700 |
|---|---|---|
| committer | Tim Hobbs <jesus.tesh@gmail.com> | 2014-04-06 11:01:26 -0700 |
| commit | 631bba1d3cbcd2e8dc9c84c23d89b910dc8e0113 (patch) | |
| tree | 3ff1455a7dbf551e5752b3c88f9adb3bc9554644 /MediaBrowser.Api/Playback/BaseStreamingService.cs | |
| parent | 0f88830fd98173815da097c54e5d8d5281dbffd5 (diff) | |
| parent | c60103df64104459883f1244363cc9cd39187545 (diff) | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'MediaBrowser.Api/Playback/BaseStreamingService.cs')
| -rw-r--r-- | MediaBrowser.Api/Playback/BaseStreamingService.cs | 127 |
1 files changed, 91 insertions, 36 deletions
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 8b05625cb..f57927f87 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1,5 +1,4 @@ -using System.Text; -using MediaBrowser.Common.Extensions; +using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dlna; @@ -22,6 +21,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -827,7 +827,7 @@ namespace MediaBrowser.Api.Playback } if (string.Equals(codec, "wmv", StringComparison.OrdinalIgnoreCase)) { - return "msmpeg4"; + return "wmv2"; } if (string.Equals(codec, "theora", StringComparison.OrdinalIgnoreCase)) { @@ -937,8 +937,6 @@ namespace MediaBrowser.Api.Playback ApiEntryPoint.Instance.OnTranscodeFailedToStart(outputPath, TranscodingJobType); - state.LogFileStream.Dispose(); - throw; } @@ -1096,23 +1094,12 @@ namespace MediaBrowser.Api.Playback /// </summary> /// <param name="process">The process.</param> /// <param name="state">The state.</param> - protected async void OnFfMpegProcessExited(Process process, StreamState state) + protected void OnFfMpegProcessExited(Process process, StreamState state) { - if (state.IsoMount != null) - { - state.IsoMount.Dispose(); - state.IsoMount = null; - } - - if (state.StandardInputCancellationTokenSource != null) - { - state.StandardInputCancellationTokenSource.Cancel(); - } + state.Dispose(); var outputFilePath = GetOutputFilePath(state); - state.LogFileStream.Dispose(); - try { Logger.Info("FFMpeg exited with code {0} for {1}", process.ExitCode, outputFilePath); @@ -1121,18 +1108,6 @@ namespace MediaBrowser.Api.Playback { Logger.Info("FFMpeg exited with an error for {0}", outputFilePath); } - - if (!string.IsNullOrEmpty(state.LiveTvStreamId)) - { - try - { - await LiveTvManager.CloseLiveStream(state.LiveTvStreamId, CancellationToken.None).ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error closing live tv stream", ex); - } - } } protected double? GetFramerateParam(StreamState state) @@ -1357,7 +1332,7 @@ namespace MediaBrowser.Api.Playback request.AudioCodec = InferAudioCodec(url); } - var state = new StreamState + var state = new StreamState(LiveTvManager, Logger) { Request = request, RequestedUrl = url @@ -1515,6 +1490,14 @@ namespace MediaBrowser.Api.Playback } } + if (state.AudioStream != null) + { + //if (CanStreamCopyAudio(request, state.AudioStream)) + //{ + // request.AudioCodec = "copy"; + //} + } + return state; } @@ -1538,7 +1521,7 @@ 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)) + if (!string.IsNullOrEmpty(request.Profile) && !string.Equals(request.Profile, videoStream.Profile, StringComparison.OrdinalIgnoreCase)) { return false; } @@ -1599,12 +1582,50 @@ namespace MediaBrowser.Api.Playback return false; } } - return false; } return SupportsAutomaticVideoStreamCopy; } + private bool CanStreamCopyAudio(StreamRequest request, MediaStream audioStream) + { + // Source and target codecs must match + if (string.IsNullOrEmpty(request.AudioCodec) || !string.Equals(request.AudioCodec, audioStream.Codec, StringComparison.OrdinalIgnoreCase)) + { + return false; + } + + // Video bitrate must fall within requested value + if (request.AudioBitRate.HasValue) + { + if (!audioStream.BitRate.HasValue || audioStream.BitRate.Value > request.AudioBitRate.Value) + { + return false; + } + } + + // Channels must fall within requested value + var channels = request.AudioChannels ?? request.MaxAudioChannels; + if (channels.HasValue) + { + if (!audioStream.Channels.HasValue || audioStream.Channels.Value > channels.Value) + { + return false; + } + } + + // Sample rate must fall within requested value + if (request.AudioSampleRate.HasValue) + { + if (!audioStream.SampleRate.HasValue || audioStream.SampleRate.Value > request.AudioSampleRate.Value) + { + return false; + } + } + + return SupportsAutomaticVideoStreamCopy; + } + protected virtual bool SupportsAutomaticVideoStreamCopy { get @@ -1623,7 +1644,7 @@ namespace MediaBrowser.Api.Playback } var profile = string.IsNullOrWhiteSpace(state.Request.DeviceProfileId) ? - null : + DlnaManager.GetProfile(headers) : DlnaManager.GetProfile(state.Request.DeviceProfileId); if (profile == null) @@ -1708,7 +1729,10 @@ namespace MediaBrowser.Api.Playback // Byte-based seeking only possible when not transcoding orgOp += isStaticallyStreamed || state.TranscodeSeekInfo == TranscodeSeekInfo.Bytes ? "1" : "0"; - AddTimeSeekResponseHeaders(state, responseHeaders); + if (!isStaticallyStreamed) + { + AddTimeSeekResponseHeaders(state, responseHeaders); + } } else { @@ -1719,7 +1743,21 @@ namespace MediaBrowser.Api.Playback // 0 = native, 1 = transcoded var orgCi = isStaticallyStreamed ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; - const string dlnaflags = ";DLNA.ORG_FLAGS=01500000000000000000000000000000"; + var flagValue = DlnaFlags.DLNA_ORG_FLAG_STREAMING_TRANSFER_MODE | + DlnaFlags.DLNA_ORG_FLAG_BACKGROUND_TRANSFERT_MODE | + DlnaFlags.DLNA_ORG_FLAG_DLNA_V15; + + if (isStaticallyStreamed) + { + flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_BYTE_BASED_SEEK; + } + else if (state.RunTimeTicks.HasValue) + { + flagValue = flagValue | DlnaFlags.DLNA_ORG_FLAG_TIME_BASED_SEEK; + } + + var dlnaflags = string.Format(";DLNA.ORG_FLAGS={0}000000000000000000000000", + Enum.Format(typeof(DlnaFlags), flagValue, "x")); if (!string.IsNullOrWhiteSpace(state.OrgPn)) { @@ -1769,6 +1807,23 @@ namespace MediaBrowser.Api.Playback } } + [Flags] + private enum DlnaFlags + { + DLNA_ORG_FLAG_SENDER_PACED = (1 << 31), + DLNA_ORG_FLAG_TIME_BASED_SEEK = (1 << 30), + DLNA_ORG_FLAG_BYTE_BASED_SEEK = (1 << 29), + DLNA_ORG_FLAG_PLAY_CONTAINER = (1 << 28), + DLNA_ORG_FLAG_S0_INCREASE = (1 << 27), + DLNA_ORG_FLAG_SN_INCREASE = (1 << 26), + DLNA_ORG_FLAG_RTSP_PAUSE = (1 << 25), + DLNA_ORG_FLAG_STREAMING_TRANSFER_MODE = (1 << 24), + DLNA_ORG_FLAG_INTERACTIVE_TRANSFERT_MODE = (1 << 23), + DLNA_ORG_FLAG_BACKGROUND_TRANSFERT_MODE = (1 << 22), + DLNA_ORG_FLAG_CONNECTION_STALL = (1 << 21), + DLNA_ORG_FLAG_DLNA_V15 = (1 << 20), + }; + private void AddTimeSeekResponseHeaders(StreamState state, IDictionary<string, string> responseHeaders) { var runtimeSeconds = TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds.ToString(UsCulture); |
