diff options
Diffstat (limited to 'MediaBrowser.Api')
7 files changed, 170 insertions, 112 deletions
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs index 98cc8ddda..b530a1e8b 100644 --- a/MediaBrowser.Api/LiveTv/LiveTvService.cs +++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs @@ -1,11 +1,11 @@ -using System.Globalization; -using MediaBrowser.Controller.Library; +using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.LiveTv; using MediaBrowser.Model.Querying; using ServiceStack; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -27,6 +27,20 @@ namespace MediaBrowser.Api.LiveTv [ApiMember(Name = "UserId", Description = "Optional filter by user and attach user data.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] public string UserId { get; set; } + + /// <summary> + /// Skips over a given number of items within the results. Use for paging. + /// </summary> + /// <value>The start index.</value> + [ApiMember(Name = "StartIndex", Description = "Optional. The record index to start at. All items with a lower index will be dropped from the results.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? StartIndex { get; set; } + + /// <summary> + /// The maximum number of items to return + /// </summary> + /// <value>The limit.</value> + [ApiMember(Name = "Limit", Description = "Optional. The maximum number of records to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] + public int? Limit { get; set; } } [Route("/LiveTv/Channels/{Id}", "GET")] @@ -116,26 +130,26 @@ namespace MediaBrowser.Api.LiveTv public string SeriesTimerId { get; set; } } - [Route("/LiveTv/Programs", "GET")] + [Route("/LiveTv/Programs", "GET,POST")] [Api(Description = "Gets available live tv epgs..")] public class GetPrograms : IReturn<QueryResult<ProgramInfoDto>> { - [ApiMember(Name = "ChannelIds", Description = "The channels to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + [ApiMember(Name = "ChannelIds", Description = "The channels to return guide information for.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string ChannelIds { get; set; } - [ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")] + [ApiMember(Name = "UserId", Description = "Optional filter by user id.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string UserId { get; set; } - [ApiMember(Name = "MinStartDate", Description = "Optional. The minimum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + [ApiMember(Name = "MinStartDate", Description = "Optional. The minimum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string MinStartDate { get; set; } - [ApiMember(Name = "MaxStartDate", Description = "Optional. The maximum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + [ApiMember(Name = "MaxStartDate", Description = "Optional. The maximum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string MaxStartDate { get; set; } - [ApiMember(Name = "MinEndDate", Description = "Optional. The minimum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + [ApiMember(Name = "MinEndDate", Description = "Optional. The minimum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string MinEndDate { get; set; } - [ApiMember(Name = "MaxEndDate", Description = "Optional. The maximum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "POST")] + [ApiMember(Name = "MaxEndDate", Description = "Optional. The maximum premiere date. Format = ISO", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET,POST")] public string MaxEndDate { get; set; } } @@ -260,7 +274,9 @@ namespace MediaBrowser.Api.LiveTv var result = _liveTvManager.GetChannels(new ChannelQuery { ChannelType = request.Type, - UserId = request.UserId + UserId = request.UserId, + StartIndex = request.StartIndex, + Limit = request.Limit }, CancellationToken.None).Result; @@ -309,6 +325,11 @@ namespace MediaBrowser.Api.LiveTv return ToOptimizedResult(result); } + public object Post(GetPrograms request) + { + return Get(request); + } + public object Get(GetRecordings request) { var result = _liveTvManager.GetRecordings(new RecordingQuery diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index dc34fca77..c400da5bf 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -253,25 +253,44 @@ namespace MediaBrowser.Api.Playback return returnFirstIfNoIndex ? streams.FirstOrDefault() : null; } + protected EncodingQuality GetQualitySetting() + { + var quality = ServerConfigurationManager.Configuration.MediaEncodingQuality; + + if (quality == EncodingQuality.Auto) + { + var cpuCount = Environment.ProcessorCount; + + if (cpuCount >= 4) + { + return EncodingQuality.HighQuality; + } + + return EncodingQuality.HighSpeed; + } + + return quality; + } + /// <summary> /// Gets the number of threads. /// </summary> /// <returns>System.Int32.</returns> /// <exception cref="System.Exception">Unrecognized MediaEncodingQuality value.</exception> - protected int GetNumberOfThreads() + protected int GetNumberOfThreads(bool isWebm) { - var quality = ServerConfigurationManager.Configuration.MediaEncodingQuality; + // Webm: http://www.webmproject.org/docs/encoder-parameters/ + // The decoder will usually automatically use an appropriate number of threads according to how many cores are available but it can only use multiple threads + // for the coefficient data if the encoder selected --token-parts > 0 at encode time. - switch (quality) + switch (GetQualitySetting()) { - case EncodingQuality.Auto: - return 0; case EncodingQuality.HighSpeed: return 2; case EncodingQuality.HighQuality: - return 2; + return isWebm ? Math.Min(3, Environment.ProcessorCount - 1) : 2; case EncodingQuality.MaxQuality: - return 0; + return isWebm ? Math.Max(2, Environment.ProcessorCount - 1) : 0; default: throw new Exception("Unrecognized MediaEncodingQuality value."); } @@ -285,30 +304,74 @@ namespace MediaBrowser.Api.Playback /// <returns>System.String.</returns> protected string GetVideoQualityParam(StreamState state, string videoCodec) { - var args = string.Empty; - // webm if (videoCodec.Equals("libvpx", StringComparison.OrdinalIgnoreCase)) { - args = "-speed 16 -quality good -profile:v 0 -slices 8"; + // http://www.webmproject.org/docs/encoder-parameters/ + return "-speed 16 -quality good -profile:v 0 -slices 8"; } // asf/wmv - else if (videoCodec.Equals("wmv2", StringComparison.OrdinalIgnoreCase)) + if (videoCodec.Equals("wmv2", StringComparison.OrdinalIgnoreCase)) + { + return "-g 100 -qmax 15"; + } + + if (videoCodec.Equals("libx264", StringComparison.OrdinalIgnoreCase)) + { + return "-preset superfast"; + } + + if (videoCodec.Equals("mpeg4", StringComparison.OrdinalIgnoreCase)) { - args = "-g 100 -qmax 15"; + return "-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -bf 2"; } - else if (videoCodec.Equals("libx264", StringComparison.OrdinalIgnoreCase)) + return string.Empty; + } + + protected string GetAudioFilterParam(StreamState state, bool isHls) + { + var volParam = string.Empty; + var audioSampleRate = string.Empty; + + var channels = GetNumAudioChannelsParam(state.Request, state.AudioStream); + + // Boost volume to 200% when downsampling from 6ch to 2ch + if (channels.HasValue && channels.Value <= 2 && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5) { - args = "-preset superfast"; + volParam = ",volume=2.000000"; } - else if (videoCodec.Equals("mpeg4", StringComparison.OrdinalIgnoreCase)) + + if (state.Request.AudioSampleRate.HasValue) { - args = "-mbd rd -flags +mv4+aic -trellis 2 -cmp 2 -subcmp 2 -bf 2"; + audioSampleRate = state.Request.AudioSampleRate.Value + ":"; } - return args.Trim(); + var adelay = isHls ? "adelay=1," : string.Empty; + + var pts = string.Empty; + + if (state.SubtitleStream != null) + { + if (state.SubtitleStream.Codec.IndexOf("srt", StringComparison.OrdinalIgnoreCase) != -1 || + state.SubtitleStream.Codec.IndexOf("subrip", StringComparison.OrdinalIgnoreCase) != -1 || + string.Equals(state.SubtitleStream.Codec, "ass", StringComparison.OrdinalIgnoreCase) || + string.Equals(state.SubtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase)) + { + var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds; + + pts = string.Format(",asetpts=PTS-{0}/TB", + Math.Round(seconds).ToString(UsCulture)); + } + } + + return string.Format("-af \"{0}aresample={1}async=1{2}{3}\"", + + adelay, + audioSampleRate, + volParam, + pts); } /// <summary> @@ -323,6 +386,7 @@ namespace MediaBrowser.Api.Playback // http://sonnati.wordpress.com/2012/10/19/ffmpeg-the-swiss-army-knife-of-internet-streaming-part-vi/ var assSubtitleParam = string.Empty; + var copyTsParam = string.Empty; var request = state.VideoRequest; @@ -333,7 +397,8 @@ namespace MediaBrowser.Api.Playback string.Equals(state.SubtitleStream.Codec, "ass", StringComparison.OrdinalIgnoreCase) || string.Equals(state.SubtitleStream.Codec, "ssa", StringComparison.OrdinalIgnoreCase)) { - assSubtitleParam = GetTextSubtitleParam(state, request.StartTimeTicks, performTextSubtitleConversion); + assSubtitleParam = GetTextSubtitleParam(state, performTextSubtitleConversion); + copyTsParam = " -copyts"; } } @@ -343,7 +408,7 @@ namespace MediaBrowser.Api.Playback var widthParam = request.Width.Value.ToString(UsCulture); var heightParam = request.Height.Value.ToString(UsCulture); - return string.Format(" -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", widthParam, heightParam, assSubtitleParam); + return string.Format("{3} -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", widthParam, heightParam, assSubtitleParam, copyTsParam); } var isH264Output = outputVideoCodec.Equals("libx264", StringComparison.OrdinalIgnoreCase); @@ -354,8 +419,8 @@ namespace MediaBrowser.Api.Playback var widthParam = request.Width.Value.ToString(UsCulture); return isH264Output ? - string.Format(" -vf \"scale={0}:trunc(ow/a/2)*2{1}\"", widthParam, assSubtitleParam) : - string.Format(" -vf \"scale={0}:-1{1}\"", widthParam, assSubtitleParam); + string.Format("{2} -vf \"scale={0}:trunc(ow/a/2)*2{1}\"", widthParam, assSubtitleParam, copyTsParam) : + string.Format("{2} -vf \"scale={0}:-1{1}\"", widthParam, assSubtitleParam, copyTsParam); } // If a fixed height was requested @@ -364,8 +429,8 @@ namespace MediaBrowser.Api.Playback var heightParam = request.Height.Value.ToString(UsCulture); return isH264Output ? - string.Format(" -vf \"scale=trunc(oh*a*2)/2:{0}{1}\"", heightParam, assSubtitleParam) : - string.Format(" -vf \"scale=-1:{0}{1}\"", heightParam, assSubtitleParam); + string.Format("{2} -vf \"scale=trunc(oh*a*2)/2:{0}{1}\"", heightParam, assSubtitleParam, copyTsParam) : + string.Format("{2} -vf \"scale=-1:{0}{1}\"", heightParam, assSubtitleParam, copyTsParam); } // If a max width was requested @@ -374,8 +439,8 @@ namespace MediaBrowser.Api.Playback var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture); return isH264Output ? - string.Format(" -vf \"scale=min(iw\\,{0}):trunc(ow/a/2)*2{1}\"", maxWidthParam, assSubtitleParam) : - string.Format(" -vf \"scale=min(iw\\,{0}):-1{1}\"", maxWidthParam, assSubtitleParam); + string.Format("{2} -vf \"scale=min(iw\\,{0}):trunc(ow/a/2)*2{1}\"", maxWidthParam, assSubtitleParam, copyTsParam) : + string.Format("{2} -vf \"scale=min(iw\\,{0}):-1{1}\"", maxWidthParam, assSubtitleParam, copyTsParam); } // If a max height was requested @@ -384,8 +449,8 @@ namespace MediaBrowser.Api.Playback var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture); return isH264Output ? - string.Format(" -vf \"scale=trunc(oh*a*2)/2:min(ih\\,{0}){1}\"", maxHeightParam, assSubtitleParam) : - string.Format(" -vf \"scale=-1:min(ih\\,{0}){1}\"", maxHeightParam, assSubtitleParam); + string.Format("{2} -vf \"scale=trunc(oh*a*2)/2:min(ih\\,{0}){1}\"", maxHeightParam, assSubtitleParam, copyTsParam) : + string.Format("{2} -vf \"scale=-1:min(ih\\,{0}){1}\"", maxHeightParam, assSubtitleParam, copyTsParam); } if (state.VideoStream == null) @@ -408,45 +473,45 @@ namespace MediaBrowser.Api.Playback var widthParam = outputSize.Width.ToString(UsCulture); var heightParam = outputSize.Height.ToString(UsCulture); - return string.Format(" -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", widthParam, heightParam, assSubtitleParam); + return string.Format("{3} -vf \"scale=trunc({0}/2)*2:trunc({1}/2)*2{2}\"", widthParam, heightParam, assSubtitleParam, copyTsParam); } // Otherwise use -vf scale since ffmpeg will ensure internally that the aspect ratio is preserved - return string.Format(" -vf \"scale={0}:-1{1}\"", Convert.ToInt32(outputSize.Width), assSubtitleParam); + return string.Format("{2} -vf \"scale={0}:-1{1}\"", Convert.ToInt32(outputSize.Width), assSubtitleParam, copyTsParam); } /// <summary> /// Gets the text subtitle param. /// </summary> /// <param name="state">The state.</param> - /// <param name="startTimeTicks">The start time ticks.</param> /// <param name="performConversion">if set to <c>true</c> [perform conversion].</param> /// <returns>System.String.</returns> - protected string GetTextSubtitleParam(StreamState state, long? startTimeTicks, bool performConversion) + protected string GetTextSubtitleParam(StreamState state, bool performConversion) { - var path = state.SubtitleStream.IsExternal ? GetConvertedAssPath(state.MediaPath, state.SubtitleStream, startTimeTicks, performConversion) : - GetExtractedAssPath(state, startTimeTicks, performConversion); + var path = state.SubtitleStream.IsExternal ? GetConvertedAssPath(state.MediaPath, state.SubtitleStream, performConversion) : + GetExtractedAssPath(state, performConversion); if (string.IsNullOrEmpty(path)) { return string.Empty; } - return string.Format(",ass='{0}'", path.Replace('\\', '/').Replace(":/", "\\:/")); + var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds; + + return string.Format(",ass='{0}',setpts=PTS -{1}/TB", + path.Replace('\\', '/').Replace(":/", "\\:/"), + Math.Round(seconds).ToString(UsCulture)); } /// <summary> /// Gets the extracted ass path. /// </summary> /// <param name="state">The state.</param> - /// <param name="startTimeTicks">The start time ticks.</param> /// <param name="performConversion">if set to <c>true</c> [perform conversion].</param> /// <returns>System.String.</returns> - private string GetExtractedAssPath(StreamState state, long? startTimeTicks, bool performConversion) + private string GetExtractedAssPath(StreamState state, bool performConversion) { - var offset = TimeSpan.FromTicks(startTimeTicks ?? 0); - - var path = FFMpegManager.Instance.GetSubtitleCachePath(state.MediaPath, state.SubtitleStream, offset, ".ass"); + var path = FFMpegManager.Instance.GetSubtitleCachePath(state.MediaPath, state.SubtitleStream, ".ass"); if (performConversion) { @@ -460,7 +525,7 @@ namespace MediaBrowser.Api.Playback Directory.CreateDirectory(parentPath); - var task = MediaEncoder.ExtractTextSubtitle(inputPath, type, state.SubtitleStream.Index, offset, path, CancellationToken.None); + var task = MediaEncoder.ExtractTextSubtitle(inputPath, type, state.SubtitleStream.Index, path, CancellationToken.None); Task.WaitAll(task); } @@ -478,14 +543,11 @@ namespace MediaBrowser.Api.Playback /// </summary> /// <param name="mediaPath">The media path.</param> /// <param name="subtitleStream">The subtitle stream.</param> - /// <param name="startTimeTicks">The start time ticks.</param> /// <param name="performConversion">if set to <c>true</c> [perform conversion].</param> /// <returns>System.String.</returns> - private string GetConvertedAssPath(string mediaPath, MediaStream subtitleStream, long? startTimeTicks, bool performConversion) + private string GetConvertedAssPath(string mediaPath, MediaStream subtitleStream, bool performConversion) { - var offset = TimeSpan.FromTicks(startTimeTicks ?? 0); - - var path = FFMpegManager.Instance.GetSubtitleCachePath(mediaPath, subtitleStream, offset, ".ass"); + var path = FFMpegManager.Instance.GetSubtitleCachePath(mediaPath, subtitleStream, ".ass"); if (performConversion) { @@ -495,7 +557,7 @@ namespace MediaBrowser.Api.Playback Directory.CreateDirectory(parentPath); - var task = MediaEncoder.ConvertTextSubtitleToAss(subtitleStream.Path, path, subtitleStream.Language, offset, CancellationToken.None); + var task = MediaEncoder.ConvertTextSubtitleToAss(subtitleStream.Path, path, subtitleStream.Language, CancellationToken.None); Task.WaitAll(task); } @@ -534,9 +596,9 @@ 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, + 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, outputSizeParam, videoSizeParam); } diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs index 9abedde4b..9c42c7729 100644 --- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs @@ -113,7 +113,7 @@ namespace MediaBrowser.Api.Playback.Hls if (isPlaylistNewlyCreated) { var minimumSegmentCount = 3; - var quality = ServerConfigurationManager.Configuration.MediaEncodingQuality; + var quality = GetQualitySetting(); if (quality == EncodingQuality.HighSpeed || quality == EncodingQuality.HighQuality) { @@ -267,9 +267,9 @@ namespace MediaBrowser.Api.Playback.Hls var itsOffset = itsOffsetMs == 0 ? string.Empty : string.Format("-itsoffset {0} ", TimeSpan.FromMilliseconds(itsOffsetMs).TotalSeconds); - var threads = GetNumberOfThreads(); + var threads = GetNumberOfThreads(false); - var args = string.Format("{0}{1} {2} {3} -i {4}{5} -threads {6} {7} {8} -sc_threshold 0 {9} -hls_time 10 -start_number 0 -hls_list_size 1440 \"{10}\"", + var args = string.Format("{0}{1} {2} {3} -i {4}{5} -map_metadata -1 -threads {6} {7} {8} -sc_threshold 0 {9} -hls_time 10 -start_number 0 -hls_list_size 1440 \"{10}\"", itsOffset, probeSize, GetUserAgentParam(state.MediaPath), diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs index 583082500..8fbb42f24 100644 --- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs @@ -80,21 +80,7 @@ namespace MediaBrowser.Api.Playback.Hls args += " -ab " + bitrate.Value.ToString(UsCulture); } - var volParam = string.Empty; - var audioSampleRate = string.Empty; - - // Boost volume to 200% when downsampling from 6ch to 2ch - if (channels.HasValue && channels.Value <= 2 && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5) - { - volParam = ",volume=2.000000"; - } - - if (state.Request.AudioSampleRate.HasValue) - { - audioSampleRate = state.Request.AudioSampleRate.Value + ":"; - } - - args += string.Format(" -af \"adelay=1,aresample={0}async=1{1}\"", audioSampleRate, volParam); + args += " " + GetAudioFilterParam(state, true); return args; } diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs index baf7f48fe..050c06627 100644 --- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs +++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs @@ -102,7 +102,7 @@ namespace MediaBrowser.Api.Playback.Progressive const string vn = " -vn"; - var threads = GetNumberOfThreads(); + var threads = GetNumberOfThreads(false); return string.Format("{0} -i {1}{2} -threads {3}{4} {5} -id3v2_version 3 -write_id3v1 1 \"{6}\"", GetFastSeekCommandLineParameter(request), diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index e367801d2..440632825 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Common.IO; +using System; +using MediaBrowser.Common.IO; using MediaBrowser.Common.MediaInfo; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; @@ -106,6 +107,7 @@ namespace MediaBrowser.Api.Playback.Progressive var transferMode = GetHeader("transferMode.dlna.org"); responseHeaders["transferMode.dlna.org"] = string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode; + responseHeaders["realTimeInfo.dlna.org"] = "DLNA.ORG_TLAG=*"; var contentFeatures = string.Empty; var extension = GetOutputFileExtension(state); @@ -118,22 +120,22 @@ namespace MediaBrowser.Api.Playback.Progressive const string dlnaflags = ";DLNA.ORG_FLAGS=01500000000000000000000000000000"; - //if (string.Equals(extension, ".mp3", StringComparison.OrdinalIgnoreCase)) - //{ - // contentFeatures = "DLNA.ORG_PN=MP3"; - //} - //else if (string.Equals(extension, ".aac", StringComparison.OrdinalIgnoreCase)) - //{ - // contentFeatures = "DLNA.ORG_PN=AAC_ISO"; - //} - //else if (string.Equals(extension, ".wma", StringComparison.OrdinalIgnoreCase)) - //{ - // contentFeatures = "DLNA.ORG_PN=WMABASE"; - //} - //else if (string.Equals(extension, ".avi", StringComparison.OrdinalIgnoreCase)) - //{ - // contentFeatures = "DLNA.ORG_PN=AVI"; - //} + if (string.Equals(extension, ".mp3", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=MP3"; + } + else if (string.Equals(extension, ".aac", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=AAC_ISO"; + } + else if (string.Equals(extension, ".wma", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=WMABASE"; + } + else if (string.Equals(extension, ".avi", StringComparison.OrdinalIgnoreCase)) + { + contentFeatures = "DLNA.ORG_PN=AVI"; + } //else if (string.Equals(extension, ".mp4", StringComparison.OrdinalIgnoreCase)) //{ // contentFeatures = "DLNA.ORG_PN=MPEG4_P2_SP_AAC"; diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index cdc8e2ffb..c3ec02a59 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -104,9 +104,9 @@ namespace MediaBrowser.Api.Playback.Progressive format = " -f mp4 -movflags frag_keyframe+empty_moov"; } - var threads = string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase) ? 2 : GetNumberOfThreads(); + var threads = GetNumberOfThreads(string.Equals(videoCodec, "libvpx", StringComparison.OrdinalIgnoreCase)); - return string.Format("{0} {1} {2} -i {3}{4}{5} {6} {7} -threads {8} {9}{10} \"{11}\"", + return string.Format("{0} {1} {2} -i {3}{4}{5} {6} {7} -map_metadata -1 -threads {8} {9}{10} \"{11}\"", probeSize, GetUserAgentParam(state.MediaPath), GetFastSeekCommandLineParameter(state.Request), @@ -170,6 +170,7 @@ namespace MediaBrowser.Api.Playback.Progressive if (bitrate.HasValue) { qualityParam += string.Format(" -b:v {0}", bitrate.Value.ToString(UsCulture)); + //qualityParam += string.Format(" -maxrate {0} -bufsize {1}", bitrate.Value.ToString(UsCulture), (bitrate.Value * 2).ToString(UsCulture)); } if (!string.IsNullOrEmpty(qualityParam)) @@ -238,21 +239,7 @@ namespace MediaBrowser.Api.Playback.Progressive args += " -ab " + bitrate.Value.ToString(UsCulture); } - var volParam = string.Empty; - var AudioSampleRate = string.Empty; - - // Boost volume to 200% when downsampling from 6ch to 2ch - if (channels.HasValue && channels.Value <= 2 && state.AudioStream.Channels.HasValue && state.AudioStream.Channels.Value > 5) - { - volParam = ",volume=2.000000"; - } - - if (state.Request.AudioSampleRate.HasValue) - { - AudioSampleRate = state.Request.AudioSampleRate.Value + ":"; - } - - args += string.Format(" -af \"aresample={0}async=1{1}\"", AudioSampleRate, volParam); + args += " " + GetAudioFilterParam(state, true); return args; } |
