diff options
Diffstat (limited to 'MediaBrowser.Api/Playback')
7 files changed, 87 insertions, 46 deletions
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 31679aad3..41d785a34 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -8,12 +8,12 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dlna; -using MediaBrowser.Model.Drawing; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Extensions; using MediaBrowser.Model.IO; using MediaBrowser.Model.MediaInfo; +using MediaBrowser.Model.Serialization; using System; using System.Collections.Generic; using System.Diagnostics; @@ -23,7 +23,6 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; -using MediaBrowser.Model.Serialization; namespace MediaBrowser.Api.Playback { @@ -690,7 +689,7 @@ namespace MediaBrowser.Api.Playback // TODO: Perhaps also use original_size=1920x800 ?? return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB", - subtitlePath.Replace("'", "\\'").Replace('\\', '/').Replace(":/", "\\:/"), + subtitlePath.Replace('\\', '/').Replace("'", "\\'").Replace(":/", "\\:/"), charsetParam, seconds.ToString(UsCulture)); } @@ -698,7 +697,7 @@ namespace MediaBrowser.Api.Playback var mediaPath = state.MediaPath ?? string.Empty; return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB", - mediaPath.Replace("'", "\\'").Replace('\\', '/').Replace(":/", "\\:/"), + mediaPath.Replace('\\', '/').Replace("'", "\\'").Replace(":/", "\\:/"), state.InternalSubtitleStreamOffset.ToString(UsCulture), seconds.ToString(UsCulture)); } @@ -773,6 +772,11 @@ namespace MediaBrowser.Api.Playback ? null : audioStream.Channels; + if (inputChannels <= 0) + { + inputChannels = null; + } + var codec = outputAudioCodec ?? string.Empty; if (codec.IndexOf("wma", StringComparison.OrdinalIgnoreCase) != -1) @@ -813,11 +817,11 @@ namespace MediaBrowser.Api.Playback } /// <summary> - /// Gets the name of the output audio codec + /// Gets the audio encoder. /// </summary> /// <param name="request">The request.</param> /// <returns>System.String.</returns> - private string GetAudioCodec(StreamRequest request) + protected string GetAudioEncoder(StreamRequest request) { var codec = request.AudioCodec; @@ -846,7 +850,7 @@ namespace MediaBrowser.Api.Playback /// </summary> /// <param name="request">The request.</param> /// <returns>System.String.</returns> - private string GetVideoCodec(VideoStreamRequest request) + protected string GetVideoEncoder(VideoStreamRequest request) { var codec = request.VideoCodec; @@ -1665,13 +1669,13 @@ namespace MediaBrowser.Api.Playback state.OutputAudioBitrate = GetAudioBitrateParam(state.Request, state.AudioStream); state.OutputAudioSampleRate = request.AudioSampleRate; - state.OutputAudioCodec = GetAudioCodec(state.Request); + state.OutputAudioCodec = state.Request.AudioCodec; state.OutputAudioChannels = GetNumAudioChannelsParam(state.Request, state.AudioStream, state.OutputAudioCodec); if (videoRequest != null) { - state.OutputVideoCodec = GetVideoCodec(videoRequest); + state.OutputVideoCodec = state.VideoRequest.VideoCodec; state.OutputVideoBitrate = GetVideoBitrateParamValue(state.VideoRequest, state.VideoStream); if (state.OutputVideoBitrate.HasValue) @@ -1768,6 +1772,12 @@ namespace MediaBrowser.Api.Playback state.InputAudioSync = "1"; } + if (string.Equals(mediaSource.Container, "wma", StringComparison.OrdinalIgnoreCase)) + { + // Seeing some stuttering when transcoding wma to audio-only HLS + state.InputAudioSync = "1"; + } + var mediaStreams = mediaSource.MediaStreams; if (videoRequest != null) @@ -2061,15 +2071,18 @@ namespace MediaBrowser.Api.Playback state.MimeType = mediaProfile.MimeType; } - var transcodingProfile = state.VideoRequest == null ? - profile.GetAudioTranscodingProfile(state.OutputContainer, audioCodec) : - profile.GetVideoTranscodingProfile(state.OutputContainer, audioCodec, videoCodec); - - if (transcodingProfile != null) + if (!state.Request.Static) { - state.EstimateContentLength = transcodingProfile.EstimateContentLength; - state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode; - state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo; + var transcodingProfile = state.VideoRequest == null ? + profile.GetAudioTranscodingProfile(state.OutputContainer, audioCodec) : + profile.GetVideoTranscodingProfile(state.OutputContainer, audioCodec, videoCodec); + + if (transcodingProfile != null) + { + state.EstimateContentLength = transcodingProfile.EstimateContentLength; + state.EnableMpegtsM2TsMode = transcodingProfile.EnableMpegtsM2TsMode; + state.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo; + } } } @@ -2088,6 +2101,15 @@ namespace MediaBrowser.Api.Playback responseHeaders["transferMode.dlna.org"] = string.IsNullOrEmpty(transferMode) ? "Streaming" : transferMode; responseHeaders["realTimeInfo.dlna.org"] = "DLNA.ORG_TLAG=*"; + if (string.Equals(GetHeader("getMediaInfo.sec"), "1", StringComparison.OrdinalIgnoreCase)) + { + if (state.RunTimeTicks.HasValue) + { + var ms = TimeSpan.FromTicks(state.RunTimeTicks.Value).TotalMilliseconds; + responseHeaders["MediaInfo.sec"] = string.Format("SEC_Duration={0};", Convert.ToInt32(ms).ToString(CultureInfo.InvariantCulture)); + } + } + if (state.RunTimeTicks.HasValue && !isStaticallyStreamed && profile != null) { AddTimeSeekResponseHeaders(state, responseHeaders); diff --git a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs index 1a90dbb53..47eb38b2d 100644 --- a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs +++ b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs @@ -378,9 +378,9 @@ namespace MediaBrowser.Api.Playback.Dash protected override string GetAudioArguments(StreamState state) { - var codec = state.OutputAudioCodec; + var codec = GetAudioEncoder(state.Request); - if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase)) { return "-codec:a:0 copy"; } @@ -408,7 +408,7 @@ namespace MediaBrowser.Api.Playback.Dash protected override string GetVideoArguments(StreamState state) { - var codec = state.OutputVideoCodec; + var codec = GetVideoEncoder(state.VideoRequest); var args = "-codec:v:0 " + codec; diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 6ca5c57f3..ab57e561f 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -295,6 +295,10 @@ namespace MediaBrowser.Api.Playback.Hls } } } + catch (DirectoryNotFoundException) + { + + } catch (FileNotFoundException) { @@ -446,22 +450,29 @@ namespace MediaBrowser.Api.Playback.Hls while (!cancellationToken.IsCancellationRequested) { - using (var fileStream = GetPlaylistFileStream(playlistPath)) + try { - using (var reader = new StreamReader(fileStream)) + using (var fileStream = GetPlaylistFileStream(playlistPath)) { - while (!reader.EndOfStream) + using (var reader = new StreamReader(fileStream)) { - var text = await reader.ReadLineAsync().ConfigureAwait(false); - - // If it appears in the playlist, it's done - if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1) + while (!reader.EndOfStream) { - return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); + var text = await reader.ReadLineAsync().ConfigureAwait(false); + + // If it appears in the playlist, it's done + if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1) + { + return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); + } } } } } + catch (IOException) + { + // May get an error if the file is locked + } await Task.Delay(100, cancellationToken).ConfigureAwait(false); } @@ -775,9 +786,19 @@ namespace MediaBrowser.Api.Playback.Hls protected override string GetAudioArguments(StreamState state) { + var codec = GetAudioEncoder(state.Request); + if (!state.IsOutputVideo) { + if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase)) + { + return "-acodec copy"; + } + var audioTranscodeParams = new List<string>(); + + audioTranscodeParams.Add("-acodec " + codec); + if (state.OutputAudioBitrate.HasValue) { audioTranscodeParams.Add("-ab " + state.OutputAudioBitrate.Value.ToString(UsCulture)); @@ -797,8 +818,6 @@ namespace MediaBrowser.Api.Playback.Hls return string.Join(" ", audioTranscodeParams.ToArray()); } - var codec = state.OutputAudioCodec; - if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase)) { return "-codec:a:0 copy"; @@ -832,7 +851,7 @@ namespace MediaBrowser.Api.Playback.Hls return string.Empty; } - var codec = state.OutputVideoCodec; + var codec = GetVideoEncoder(state.VideoRequest); var args = "-codec:v:0 " + codec; @@ -879,7 +898,7 @@ namespace MediaBrowser.Api.Playback.Hls if (!EnableSplitTranscoding(state)) { - args += " -copyts"; + //args += " -copyts"; } return args; @@ -910,11 +929,11 @@ namespace MediaBrowser.Api.Playback.Hls //toTimeParam = " -to " + MediaEncoder.GetTimeParameter(endTime); toTimeParam = " -t " + MediaEncoder.GetTimeParameter(TimeSpan.FromSeconds(durationSeconds).Ticks); } + } - if (state.IsOutputVideo && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && (state.Request.StartTimeTicks ?? 0) > 0) - { - timestampOffsetParam = " -output_ts_offset " + MediaEncoder.GetTimeParameter(state.Request.StartTimeTicks ?? 0).ToString(CultureInfo.InvariantCulture); - } + if (state.IsOutputVideo && !string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase) && (state.Request.StartTimeTicks ?? 0) > 0) + { + timestampOffsetParam = " -output_ts_offset " + MediaEncoder.GetTimeParameter(state.Request.StartTimeTicks ?? 0).ToString(CultureInfo.InvariantCulture); } var mapArgs = state.IsOutputVideo ? GetMapArgs(state) : string.Empty; @@ -959,6 +978,7 @@ namespace MediaBrowser.Api.Playback.Hls private bool EnableSplitTranscoding(StreamState state) { + return false; if (string.Equals(Request.QueryString["EnableSplitTranscoding"], "false", StringComparison.OrdinalIgnoreCase)) { return false; diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs index f21be190f..d8e3423fc 100644 --- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs @@ -48,9 +48,9 @@ namespace MediaBrowser.Api.Playback.Hls /// <returns>System.String.</returns> protected override string GetAudioArguments(StreamState state) { - var codec = state.OutputAudioCodec; + var codec = GetAudioEncoder(state.Request); - if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase)) { return "-codec:a:0 copy"; } @@ -83,7 +83,7 @@ namespace MediaBrowser.Api.Playback.Hls /// <returns>System.String.</returns> protected override string GetVideoArguments(StreamState state) { - var codec = state.OutputVideoCodec; + var codec = GetVideoEncoder(state.VideoRequest); var args = "-codec:v:0 " + codec; diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs index 72d4961cd..0b7b50134 100644 --- a/MediaBrowser.Api/Playback/MediaInfoService.cs +++ b/MediaBrowser.Api/Playback/MediaInfoService.cs @@ -46,7 +46,7 @@ namespace MediaBrowser.Api.Playback } [Route("/Playback/BitrateTest", "GET")] - public class GetBitrateTestBytes : IReturn<PlaybackInfoResponse> + public class GetBitrateTestBytes { [ApiMember(Name = "Size", Description = "Size", IsRequired = true, DataType = "int", ParameterType = "query", Verb = "GET")] public long Size { get; set; } diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 041b4ea41..910ac18e7 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -1,12 +1,10 @@ -using System.Globalization; -using MediaBrowser.Common.IO; +using MediaBrowser.Common.IO; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Devices; using MediaBrowser.Controller.Dlna; using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Library; -using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Net; using MediaBrowser.Model.IO; @@ -15,6 +13,7 @@ using MediaBrowser.Model.Serialization; using ServiceStack.Web; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Threading; using System.Threading.Tasks; diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs index 283f9671f..ebd72b2ce 100644 --- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs +++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs @@ -89,7 +89,7 @@ namespace MediaBrowser.Api.Playback.Progressive protected override string GetCommandLineArguments(string outputPath, StreamState state, bool isEncoding) { // Get the output codec name - var videoCodec = state.OutputVideoCodec; + var videoCodec = GetVideoEncoder(state.VideoRequest); var format = string.Empty; var keyFrame = string.Empty; @@ -183,11 +183,11 @@ namespace MediaBrowser.Api.Playback.Progressive } // Get the output codec name - var codec = state.OutputAudioCodec; + var codec = GetAudioEncoder(state.Request); var args = "-codec:a:0 " + codec; - if (codec.Equals("copy", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(codec, "copy", StringComparison.OrdinalIgnoreCase)) { return args; } |
