diff options
| author | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-04-01 18:23:07 -0400 |
|---|---|---|
| committer | Luke Pulverenti <luke.pulverenti@gmail.com> | 2014-04-01 18:23:07 -0400 |
| commit | 21308be83fd8678dc1030c6493762f09828b1d2d (patch) | |
| tree | 874a75ab8b6ecbe7565edbb42fd56d8c2f800614 /MediaBrowser.Api/Playback/BaseStreamingService.cs | |
| parent | 4afe2c3f731562efbe42147d1bcbdc0a7542cfeb (diff) | |
Add latest translations
Diffstat (limited to 'MediaBrowser.Api/Playback/BaseStreamingService.cs')
| -rw-r--r-- | MediaBrowser.Api/Playback/BaseStreamingService.cs | 111 |
1 files changed, 95 insertions, 16 deletions
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 6c406a11c..418a9c9ba 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -9,6 +9,7 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Configuration; +using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; @@ -247,6 +248,11 @@ namespace MediaBrowser.Api.Playback } } + if (type == MediaStreamType.Video) + { + streams = streams.Where(i => !string.Equals(i.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase)).ToList(); + } + if (returnFirstIfNoIndex && type == MediaStreamType.Audio) { return streams.FirstOrDefault(i => i.Channels.HasValue && i.Channels.Value > 0) ?? @@ -1018,7 +1024,7 @@ namespace MediaBrowser.Api.Playback return string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture)); } - + return string.Format(" -maxrate {0} -bufsize {1}", bitrate.Value.ToString(UsCulture), (bitrate.Value * 2).ToString(UsCulture)); @@ -1257,6 +1263,69 @@ namespace MediaBrowser.Api.Playback } /// <summary> + /// Parses the dlna headers. + /// </summary> + /// <param name="request">The request.</param> + private void ParseDlnaHeaders(StreamRequest request) + { + if (!request.StartTimeTicks.HasValue) + { + var timeSeek = GetHeader("TimeSeekRange.dlna.org"); + + request.StartTimeTicks = ParseTimeSeekHeader(timeSeek); + } + } + + /// <summary> + /// Parses the time seek header. + /// </summary> + private long? ParseTimeSeekHeader(string value) + { + if (string.IsNullOrWhiteSpace(value)) + { + return null; + } + + if (value.IndexOf("npt=", StringComparison.OrdinalIgnoreCase) != 0) + { + throw new ArgumentException("Invalid timeseek header"); + } + value = value.Substring(4).Split(new[] { '-' }, 2)[0]; + + if (value.IndexOf(':') == -1) + { + // Parses npt times in the format of '417.33' + double seconds; + if (double.TryParse(value, NumberStyles.Any, UsCulture, out seconds)) + { + return TimeSpan.FromSeconds(seconds).Ticks; + } + + throw new ArgumentException("Invalid timeseek header"); + } + + // Parses npt times in the format of '10:19:25.7' + var tokens = value.Split(new[] { ':' }, 3); + double secondsSum = 0; + var timeFactor = 3600; + + foreach (var time in tokens) + { + double digit; + if (double.TryParse(time, NumberStyles.Any, UsCulture, out digit)) + { + secondsSum += (digit * timeFactor); + } + else + { + throw new ArgumentException("Invalid timeseek header"); + } + timeFactor /= 60; + } + return TimeSpan.FromSeconds(secondsSum).Ticks; + } + + /// <summary> /// Gets the state. /// </summary> /// <param name="request">The request.</param> @@ -1264,6 +1333,8 @@ namespace MediaBrowser.Api.Playback /// <returns>StreamState.</returns> protected async Task<StreamState> GetState(StreamRequest request, CancellationToken cancellationToken) { + ParseDlnaHeaders(request); + if (!string.IsNullOrWhiteSpace(request.Params)) { ParseParams(request); @@ -1509,8 +1580,6 @@ namespace MediaBrowser.Api.Playback /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> protected void AddDlnaHeaders(StreamState state, IDictionary<string, string> responseHeaders, bool isStaticallyStreamed) { - var timeSeek = GetHeader("TimeSeekRange.dlna.org"); - var transferMode = GetHeader("transferMode.dlna.org"); responseHeaders["transferMode.dlna.org"] = string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode; responseHeaders["realTimeInfo.dlna.org"] = "DLNA.ORG_TLAG=*"; @@ -1521,11 +1590,21 @@ namespace MediaBrowser.Api.Playback // first bit means Time based seek supported, second byte range seek supported (not sure about the order now), so 01 = only byte seek, 10 = time based, 11 = both, 00 = none var orgOp = ";DLNA.ORG_OP="; - // Time-based seeking currently only possible when transcoding - orgOp += isStaticallyStreamed ? "0" : "1"; + if (state.RunTimeTicks.HasValue) + { + // Time-based seeking currently only possible when transcoding + orgOp += isStaticallyStreamed ? "0" : "1"; + + // Byte-based seeking only possible when not transcoding + orgOp += isStaticallyStreamed || state.TranscodeSeekInfo == TranscodeSeekInfo.Bytes ? "1" : "0"; - // Byte-based seeking only possible when not transcoding - orgOp += isStaticallyStreamed || state.TranscodeSeekInfo == TranscodeSeekInfo.Bytes ? "1" : "0"; + AddTimeSeekResponseHeaders(state, responseHeaders); + } + else + { + // No seeking is available if we don't know the content runtime + orgOp += "00"; + } // 0 = native, 1 = transcoded var orgCi = isStaticallyStreamed ? ";DLNA.ORG_CI=0" : ";DLNA.ORG_CI=1"; @@ -1568,15 +1647,6 @@ namespace MediaBrowser.Api.Playback { contentFeatures = "DLNA.ORG_PN=MPEG_PS_PAL"; } - //else if (string.Equals(extension, ".wmv", StringComparison.OrdinalIgnoreCase)) - //{ - // contentFeatures = "DLNA.ORG_PN=WMVHIGH_BASE"; - //} - //else if (string.Equals(extension, ".asf", StringComparison.OrdinalIgnoreCase)) - //{ - // // ?? - // contentFeatures = "DLNA.ORG_PN=WMVHIGH_BASE"; - //} if (!string.IsNullOrEmpty(contentFeatures)) { @@ -1589,6 +1659,15 @@ namespace MediaBrowser.Api.Playback } } + private void AddTimeSeekResponseHeaders(StreamState state, IDictionary<string, string> responseHeaders) + { + var runtimeSeconds = TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalSeconds.ToString(UsCulture); + var startSeconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds.ToString(UsCulture); + + responseHeaders["TimeSeekRange.dlna.org"] = string.Format("npt={0}-{1}/{1}", startSeconds, runtimeSeconds); + responseHeaders["X-AvailableSeekRange"] = string.Format("1 npt={0}-{1}", startSeconds, runtimeSeconds); + } + /// <summary> /// Enforces the resolution limit. /// </summary> |
