diff options
27 files changed, 189 insertions, 333 deletions
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs index 71d66664b..d2369c410 100644 --- a/MediaBrowser.Api/Playback/BaseStreamingService.cs +++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs @@ -1,16 +1,12 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Common.IO; -using MediaBrowser.Common.Net; using MediaBrowser.Controller.Channels; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Dlna; -using MediaBrowser.Controller.Dto; using MediaBrowser.Controller.Entities; -using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Drawing; @@ -19,6 +15,7 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Library; using MediaBrowser.Model.LiveTv; +using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; using System.Diagnostics; @@ -639,16 +636,16 @@ namespace MediaBrowser.Api.Playback /// <summary> /// Gets the probe size argument. /// </summary> - /// <param name="isVideo">if set to <c>true</c> [is video].</param> - /// <param name="videoType">Type of the video.</param> - /// <param name="isoType">Type of the iso.</param> + /// <param name="state">The state.</param> /// <returns>System.String.</returns> - private string GetProbeSizeArgument(bool isVideo, VideoType? videoType, IsoType? isoType) + private string GetProbeSizeArgument(StreamState state) { - var type = !isVideo ? MediaEncoderHelpers.GetInputType(null, null) : - MediaEncoderHelpers.GetInputType(videoType, isoType); + if (state.PlayableStreamFileNames.Count > 0) + { + return MediaEncoder.GetProbeSizeArgument(state.PlayableStreamFileNames.ToArray(), state.InputProtocol); + } - return MediaEncoder.GetProbeSizeArgument(type); + return MediaEncoder.GetProbeSizeArgument(new[] { state.MediaPath }, state.InputProtocol); } /// <summary> @@ -765,7 +762,7 @@ namespace MediaBrowser.Api.Playback /// <returns>System.String.</returns> protected string GetInputArgument(StreamState state) { - var type = state.IsRemote ? InputType.Url : InputType.File; + var protocol = state.InputProtocol; var inputPath = new[] { state.MediaPath }; @@ -773,11 +770,11 @@ namespace MediaBrowser.Api.Playback { if (!(state.VideoType == VideoType.Iso && state.IsoMount == null)) { - inputPath = MediaEncoderHelpers.GetInputArgument(state.MediaPath, state.IsRemote, state.VideoType, state.IsoType, state.IsoMount, state.PlayableStreamFileNames, out type); + inputPath = MediaEncoderHelpers.GetInputArgument(state.MediaPath, state.InputProtocol, state.IsoMount, state.PlayableStreamFileNames); } } - return MediaEncoder.GetInputArgument(inputPath, type); + return MediaEncoder.GetInputArgument(inputPath, protocol); } /// <summary> @@ -885,7 +882,7 @@ namespace MediaBrowser.Api.Playback } // This is arbitrary, but add a little buffer time when internet streaming - if (state.IsRemote) + if (state.InputProtocol != MediaProtocol.File) { await Task.Delay(3000, cancellationTokenSource.Token).ConfigureAwait(false); } @@ -1063,11 +1060,6 @@ namespace MediaBrowser.Api.Playback state.RemoteHttpHeaders.TryGetValue("User-Agent", out useragent); - if (string.IsNullOrWhiteSpace(useragent)) - { - useragent = GetUserAgent(state.MediaPath); - } - if (!string.IsNullOrWhiteSpace(useragent)) { return "-user-agent \"" + useragent + "\""; @@ -1077,26 +1069,6 @@ namespace MediaBrowser.Api.Playback } /// <summary> - /// Gets the user agent. - /// </summary> - /// <param name="path">The path.</param> - /// <returns>System.String.</returns> - protected string GetUserAgent(string path) - { - if (string.IsNullOrEmpty(path)) - { - throw new ArgumentNullException("path"); - - } - if (path.IndexOf("apple.com", StringComparison.OrdinalIgnoreCase) != -1) - { - return "QuickTime/7.7.4"; - } - - return string.Empty; - } - - /// <summary> /// Processes the exited. /// </summary> /// <param name="process">The process.</param> @@ -1388,12 +1360,12 @@ namespace MediaBrowser.Api.Playback if (!string.IsNullOrEmpty(path)) { state.MediaPath = path; - state.IsRemote = false; + state.InputProtocol = MediaProtocol.File; } else if (!string.IsNullOrEmpty(mediaUrl)) { state.MediaPath = mediaUrl; - state.IsRemote = true; + state.InputProtocol = MediaProtocol.Http; } state.RunTimeTicks = recording.RunTimeTicks; @@ -1425,14 +1397,14 @@ namespace MediaBrowser.Api.Playback if (!string.IsNullOrEmpty(streamInfo.Path)) { state.MediaPath = streamInfo.Path; - state.IsRemote = false; + state.InputProtocol = MediaProtocol.File; await Task.Delay(1000, cancellationToken).ConfigureAwait(false); } else if (!string.IsNullOrEmpty(streamInfo.Url)) { state.MediaPath = streamInfo.Url; - state.IsRemote = true; + state.InputProtocol = MediaProtocol.Http; } state.ReadInputAtNativeFramerate = true; @@ -1445,7 +1417,7 @@ namespace MediaBrowser.Api.Playback { var source = await GetChannelMediaInfo(request.Id, request.MediaSourceId, cancellationToken).ConfigureAwait(false); state.IsInputVideo = string.Equals(item.MediaType, MediaType.Video, StringComparison.OrdinalIgnoreCase); - state.IsRemote = source.LocationType == LocationType.Remote; + state.InputProtocol = source.Protocol; state.MediaPath = source.Path; state.RunTimeTicks = item.RunTimeTicks; state.RemoteHttpHeaders = source.RequiredHttpHeaders; @@ -1461,7 +1433,7 @@ namespace MediaBrowser.Api.Playback mediaStreams = mediaSource.MediaStreams; state.MediaPath = mediaSource.Path; - state.IsRemote = mediaSource.LocationType == LocationType.Remote; + state.InputProtocol = mediaSource.Protocol; state.InputContainer = mediaSource.Container; if (item is Video) @@ -1921,18 +1893,15 @@ namespace MediaBrowser.Api.Playback { var inputModifier = string.Empty; - var probeSize = GetProbeSizeArgument(state.IsInputVideo, state.VideoType, state.IsoType); + var probeSize = GetProbeSizeArgument(state); inputModifier += " " + probeSize; inputModifier = inputModifier.Trim(); - if (state.IsRemote) - { - var userAgentParam = GetUserAgentParam(state); + var userAgentParam = GetUserAgentParam(state); - if (!string.IsNullOrWhiteSpace(userAgentParam)) - { - inputModifier += " " + userAgentParam; - } + if (!string.IsNullOrWhiteSpace(userAgentParam)) + { + inputModifier += " " + userAgentParam; } inputModifier = inputModifier.Trim(); diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs index 1e71c7c0d..79cf4170b 100644 --- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs +++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs @@ -8,6 +8,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.LiveTv; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.IO; +using MediaBrowser.Model.MediaInfo; using ServiceStack.Web; using System; using System.Collections.Generic; @@ -118,13 +119,13 @@ namespace MediaBrowser.Api.Playback.Progressive var responseHeaders = new Dictionary<string, string>(); // Static remote stream - if (request.Static && state.IsRemote) + if (request.Static && state.InputProtocol == MediaProtocol.Http) { AddDlnaHeaders(state, responseHeaders, true); try { - return GetStaticRemoteStreamResult(state.MediaPath, responseHeaders, isHeadRequest).Result; + return GetStaticRemoteStreamResult(state, responseHeaders, isHeadRequest).Result; } finally { @@ -132,6 +133,11 @@ namespace MediaBrowser.Api.Playback.Progressive } } + if (request.Static && state.InputProtocol != MediaProtocol.File) + { + throw new ArgumentException(string.Format("Input protocol {0} cannot be streamed statically.", state.InputProtocol)); + } + var outputPath = state.OutputFilePath; var outputPathExists = File.Exists(outputPath); @@ -186,16 +192,19 @@ namespace MediaBrowser.Api.Playback.Progressive /// <summary> /// Gets the static remote stream result. /// </summary> - /// <param name="mediaPath">The media path.</param> + /// <param name="state">The state.</param> /// <param name="responseHeaders">The response headers.</param> /// <param name="isHeadRequest">if set to <c>true</c> [is head request].</param> /// <returns>Task{System.Object}.</returns> - private async Task<object> GetStaticRemoteStreamResult(string mediaPath, Dictionary<string, string> responseHeaders, bool isHeadRequest) + private async Task<object> GetStaticRemoteStreamResult(StreamState state, Dictionary<string, string> responseHeaders, bool isHeadRequest) { + string useragent = null; + state.RemoteHttpHeaders.TryGetValue("User-Agent", out useragent); + var options = new HttpRequestOptions { - Url = mediaPath, - UserAgent = GetUserAgent(mediaPath), + Url = state.MediaPath, + UserAgent = useragent, BufferContent = false }; diff --git a/MediaBrowser.Api/Playback/StreamState.cs b/MediaBrowser.Api/Playback/StreamState.cs index aa3170173..8a9de6edc 100644 --- a/MediaBrowser.Api/Playback/StreamState.cs +++ b/MediaBrowser.Api/Playback/StreamState.cs @@ -2,6 +2,7 @@ using MediaBrowser.Controller.LiveTv; using MediaBrowser.Model.Dlna; using MediaBrowser.Model.Drawing; +using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; @@ -50,7 +51,7 @@ namespace MediaBrowser.Api.Playback public string MediaPath { get; set; } - public bool IsRemote { get; set; } + public MediaProtocol InputProtocol { get; set; } public bool IsInputVideo { get; set; } diff --git a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs b/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs index 2e2f1912a..e8369f573 100644 --- a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs +++ b/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs @@ -1,4 +1,5 @@ -using System; +using MediaBrowser.Model.MediaInfo; +using System; using System.Collections.Generic; namespace MediaBrowser.Controller.Channels @@ -20,16 +21,18 @@ namespace MediaBrowser.Controller.Channels public int? AudioChannels { get; set; } public int? AudioSampleRate { get; set; } - public bool IsRemote { get; set; } - public string VideoProfile { get; set; } public float? VideoLevel { get; set; } public float? Framerate { get; set; } + public MediaProtocol Protocol { get; set; } + public ChannelMediaInfo() { RequiredHttpHeaders = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); - IsRemote = true; + + // This is most common + Protocol = MediaProtocol.Http; } } }
\ No newline at end of file diff --git a/MediaBrowser.Controller/Dto/IDtoService.cs b/MediaBrowser.Controller/Dto/IDtoService.cs index b2081fe6b..0482e140b 100644 --- a/MediaBrowser.Controller/Dto/IDtoService.cs +++ b/MediaBrowser.Controller/Dto/IDtoService.cs @@ -68,13 +68,6 @@ namespace MediaBrowser.Controller.Dto ChapterInfoDto GetChapterInfoDto(ChapterInfo chapterInfo, BaseItem item); /// <summary> - /// Gets the media sources. - /// </summary> - /// <param name="item">The item.</param> - /// <returns>List{MediaSourceInfo}.</returns> - List<MediaSourceInfo> GetMediaSources(BaseItem item); - - /// <summary> /// Gets the item by name dto. /// </summary> /// <param name="item">The item.</param> diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs index e14563ea4..bd407f91b 100644 --- a/MediaBrowser.Controller/Entities/Audio/Audio.cs +++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs @@ -3,6 +3,7 @@ using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Dto; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; using System.Linq; @@ -191,7 +192,7 @@ namespace MediaBrowser.Controller.Entities.Audio var info = new MediaSourceInfo { Id = i.Id.ToString("N"), - LocationType = locationType, + Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File, MediaStreams = ItemRepository.GetMediaStreams(new MediaStreamQuery { ItemId = i.Id }).ToList(), Name = i.Name, Path = enablePathSubstituion ? GetMappedPath(i.Path, locationType) : i.Path, diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs index 3df3f7440..61404949e 100644 --- a/MediaBrowser.Controller/Entities/Video.cs +++ b/MediaBrowser.Controller/Entities/Video.cs @@ -549,7 +549,7 @@ namespace MediaBrowser.Controller.Entities { Id = i.Id.ToString("N"), IsoType = i.IsoType, - LocationType = locationType, + Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File, MediaStreams = mediaStreams, Name = GetMediaSourceName(i, mediaStreams), Path = enablePathSubstitution ? GetMappedPath(i.Path, locationType) : i.Path, diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs index 5b78b6789..3c1c9f442 100644 --- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs +++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs @@ -6,7 +6,7 @@ using System.Linq; namespace MediaBrowser.Controller.LiveTv { - public class LiveTvChannel : BaseItem, IItemByName + public class LiveTvChannel : BaseItem, IItemByName, IHasMediaSources { /// <summary> /// Gets the user data key. @@ -114,5 +114,10 @@ namespace MediaBrowser.Controller.LiveTv { return new List<BaseItem>(); } + + public IEnumerable<Model.Dto.MediaSourceInfo> GetMediaSources(bool enablePathSubstitution) + { + throw new System.NotImplementedException(); + } } } diff --git a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs index 0de119ae5..f7e8554d1 100644 --- a/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs +++ b/MediaBrowser.Controller/MediaEncoding/IMediaEncoder.cs @@ -1,4 +1,5 @@ using MediaBrowser.Model.Entities; +using MediaBrowser.Model.MediaInfo; using System; using System.IO; using System.Threading; @@ -35,59 +36,37 @@ namespace MediaBrowser.Controller.MediaEncoding /// Extracts the video image. /// </summary> /// <param name="inputFiles">The input files.</param> - /// <param name="type">The type.</param> + /// <param name="protocol">The protocol.</param> /// <param name="threedFormat">The threed format.</param> /// <param name="offset">The offset.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task{Stream}.</returns> - Task<Stream> ExtractVideoImage(string[] inputFiles, InputType type, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken); + Task<Stream> ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken); /// <summary> /// Gets the media info. /// </summary> /// <param name="inputFiles">The input files.</param> - /// <param name="type">The type.</param> + /// <param name="protocol">The protocol.</param> /// <param name="isAudio">if set to <c>true</c> [is audio].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - Task<InternalMediaInfoResult> GetMediaInfo(string[] inputFiles, InputType type, bool isAudio, CancellationToken cancellationToken); + Task<InternalMediaInfoResult> GetMediaInfo(string[] inputFiles, MediaProtocol protocol, bool isAudio, CancellationToken cancellationToken); /// <summary> /// Gets the probe size argument. /// </summary> - /// <param name="type">The type.</param> + /// <param name="inputFiles">The input files.</param> + /// <param name="protocol">The protocol.</param> /// <returns>System.String.</returns> - string GetProbeSizeArgument(InputType type); + string GetProbeSizeArgument(string[] inputFiles, MediaProtocol protocol); /// <summary> /// Gets the input argument. /// </summary> /// <param name="inputFiles">The input files.</param> - /// <param name="type">The type.</param> + /// <param name="protocol">The protocol.</param> /// <returns>System.String.</returns> - string GetInputArgument(string[] inputFiles, InputType type); - } - - /// <summary> - /// Enum InputType - /// </summary> - public enum InputType - { - /// <summary> - /// The file - /// </summary> - File, - /// <summary> - /// The bluray - /// </summary> - Bluray, - /// <summary> - /// The DVD - /// </summary> - Dvd, - /// <summary> - /// The URL - /// </summary> - Url + string GetInputArgument(string[] inputFiles, MediaProtocol protocol); } } diff --git a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs index 6a37626b7..37dd06da9 100644 --- a/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs +++ b/MediaBrowser.Controller/MediaEncoding/MediaEncoderHelpers.cs @@ -1,5 +1,6 @@ using MediaBrowser.Model.Entities; using MediaBrowser.Model.IO; +using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; using System.Globalization; @@ -17,56 +18,22 @@ namespace MediaBrowser.Controller.MediaEncoding /// Gets the input argument. /// </summary> /// <param name="videoPath">The video path.</param> - /// <param name="isRemote">if set to <c>true</c> [is remote].</param> - /// <param name="videoType">Type of the video.</param> - /// <param name="isoType">Type of the iso.</param> + /// <param name="protocol">The protocol.</param> /// <param name="isoMount">The iso mount.</param> /// <param name="playableStreamFileNames">The playable stream file names.</param> - /// <param name="type">The type.</param> /// <returns>System.String[][].</returns> - public static string[] GetInputArgument(string videoPath, bool isRemote, VideoType videoType, IsoType? isoType, IIsoMount isoMount, IEnumerable<string> playableStreamFileNames, out InputType type) + public static string[] GetInputArgument(string videoPath, MediaProtocol protocol, IIsoMount isoMount, List<string> playableStreamFileNames) { - var inputPath = isoMount == null ? new[] { videoPath } : new[] { isoMount.MountedPath }; - - type = InputType.File; - - switch (videoType) + if (playableStreamFileNames.Count > 0) { - case VideoType.BluRay: - type = InputType.Bluray; - inputPath = GetPlayableStreamFiles(inputPath[0], playableStreamFileNames).ToArray(); - break; - case VideoType.Dvd: - type = InputType.Dvd; - inputPath = GetPlayableStreamFiles(inputPath[0], playableStreamFileNames).ToArray(); - break; - case VideoType.Iso: - if (isoType.HasValue) - { - switch (isoType.Value) - { - case IsoType.BluRay: - type = InputType.Bluray; - inputPath = GetPlayableStreamFiles(inputPath[0], playableStreamFileNames).ToArray(); - break; - case IsoType.Dvd: - type = InputType.Dvd; - inputPath = GetPlayableStreamFiles(inputPath[0], playableStreamFileNames).ToArray(); - break; - } - } - break; - case VideoType.VideoFile: - { - if (isRemote) - { - type = InputType.Url; - } - break; - } + if (isoMount == null) + { + return GetPlayableStreamFiles(videoPath, playableStreamFileNames).ToArray(); + } + return GetPlayableStreamFiles(isoMount.MountedPath, playableStreamFileNames).ToArray(); } - return inputPath; + return new[] {videoPath}; } public static List<string> GetPlayableStreamFiles(string rootPath, IEnumerable<string> filenames) @@ -80,46 +47,6 @@ namespace MediaBrowser.Controller.MediaEncoding .ToList(); } - /// <summary> - /// Gets the type of the input. - /// </summary> - /// <param name="videoType">Type of the video.</param> - /// <param name="isoType">Type of the iso.</param> - /// <returns>InputType.</returns> - public static InputType GetInputType(VideoType? videoType, IsoType? isoType) - { - var type = InputType.File; - - if (videoType.HasValue) - { - switch (videoType.Value) - { - case VideoType.BluRay: - type = InputType.Bluray; - break; - case VideoType.Dvd: - type = InputType.Dvd; - break; - case VideoType.Iso: - if (isoType.HasValue) - { - switch (isoType.Value) - { - case IsoType.BluRay: - type = InputType.Bluray; - break; - case IsoType.Dvd: - type = InputType.Dvd; - break; - } - } - break; - } - } - - return type; - } - public static MediaInfo GetMediaInfo(InternalMediaInfoResult data) { var internalStreams = data.streams ?? new MediaStreamInfo[] { }; diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs index 9bd2e9270..bf4daf786 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingUtils.cs @@ -1,22 +1,27 @@ using MediaBrowser.Controller.MediaEncoding; -using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.MediaInfo; using System; using System.Collections.Generic; -using System.Globalization; using System.Linq; namespace MediaBrowser.MediaEncoding.Encoder { public static class EncodingUtils { - private static readonly CultureInfo UsCulture = new CultureInfo("en-US"); - - public static string GetInputArgument(List<string> inputFiles, bool isRemote) + public static string GetInputArgument(List<string> inputFiles, MediaProtocol protocol) { - if (isRemote) + if (protocol == MediaProtocol.Http) { - return GetHttpInputArgument(inputFiles); + var url = inputFiles.First(); + + return string.Format("\"{0}\"", url); + } + if (protocol == MediaProtocol.Rtmp) + { + var url = inputFiles.First(); + + return string.Format("\"{0}\"", url); } return GetConcatInputArgument(inputFiles); @@ -52,35 +57,6 @@ namespace MediaBrowser.MediaEncoding.Encoder return string.Format("file:\"{0}\"", path); } - /// <summary> - /// Gets the HTTP input argument. - /// </summary> - /// <param name="inputFiles">The input files.</param> - /// <returns>System.String.</returns> - private static string GetHttpInputArgument(IEnumerable<string> inputFiles) - { - var url = inputFiles.First(); - - return string.Format("\"{0}\"", url); - } - - private static string GetFastSeekValue(EncodingOptions options) - { - var time = options.StartTimeTicks; - - if (time.HasValue) - { - var seconds = TimeSpan.FromTicks(time.Value).TotalSeconds; - - if (seconds > 0) - { - return string.Format("-ss {0}", seconds.ToString(UsCulture)); - } - } - - return string.Empty; - } - public static string GetProbeSizeArgument(bool isDvd) { return isDvd ? "-probesize 1G -analyzeduration 200M" : string.Empty; diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index d532d100f..6cb7e8ce3 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -3,6 +3,7 @@ using MediaBrowser.Common.IO; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Serialization; using System; using System.Collections.Concurrent; @@ -102,37 +103,38 @@ namespace MediaBrowser.MediaEncoding.Encoder /// Gets the media info. /// </summary> /// <param name="inputFiles">The input files.</param> - /// <param name="type">The type.</param> + /// <param name="protocol">The protocol.</param> /// <param name="isAudio">if set to <c>true</c> [is audio].</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> - public Task<InternalMediaInfoResult> GetMediaInfo(string[] inputFiles, InputType type, bool isAudio, + public Task<InternalMediaInfoResult> GetMediaInfo(string[] inputFiles, MediaProtocol protocol, bool isAudio, CancellationToken cancellationToken) { - return GetMediaInfoInternal(GetInputArgument(inputFiles, type), !isAudio, - GetProbeSizeArgument(type), cancellationToken); + return GetMediaInfoInternal(GetInputArgument(inputFiles, protocol), !isAudio, + GetProbeSizeArgument(inputFiles, protocol), cancellationToken); } /// <summary> /// Gets the input argument. /// </summary> /// <param name="inputFiles">The input files.</param> - /// <param name="type">The type.</param> + /// <param name="protocol">The protocol.</param> /// <returns>System.String.</returns> /// <exception cref="System.ArgumentException">Unrecognized InputType</exception> - public string GetInputArgument(string[] inputFiles, InputType type) + public string GetInputArgument(string[] inputFiles, MediaProtocol protocol) { - return EncodingUtils.GetInputArgument(inputFiles.ToList(), type == InputType.Url); + return EncodingUtils.GetInputArgument(inputFiles.ToList(), protocol); } /// <summary> /// Gets the probe size argument. /// </summary> - /// <param name="type">The type.</param> + /// <param name="inputFiles">The input files.</param> + /// <param name="protocol">The protocol.</param> /// <returns>System.String.</returns> - public string GetProbeSizeArgument(InputType type) + public string GetProbeSizeArgument(string[] inputFiles, MediaProtocol protocol) { - return EncodingUtils.GetProbeSizeArgument(type == InputType.Dvd); + return EncodingUtils.GetProbeSizeArgument(inputFiles.Length > 0); } /// <summary> @@ -287,27 +289,27 @@ namespace MediaBrowser.MediaEncoding.Encoder public Task<Stream> ExtractAudioImage(string path, CancellationToken cancellationToken) { - return ExtractImage(new[] { path }, InputType.File, true, null, null, cancellationToken); + return ExtractImage(new[] { path }, MediaProtocol.File, true, null, null, cancellationToken); } - public Task<Stream> ExtractVideoImage(string[] inputFiles, InputType type, Video3DFormat? threedFormat, + public Task<Stream> ExtractVideoImage(string[] inputFiles, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { - return ExtractImage(inputFiles, type, false, threedFormat, offset, cancellationToken); + return ExtractImage(inputFiles, protocol, false, threedFormat, offset, cancellationToken); } - private async Task<Stream> ExtractImage(string[] inputFiles, InputType type, bool isAudio, + private async Task<Stream> ExtractImage(string[] inputFiles, MediaProtocol protocol, bool isAudio, Video3DFormat? threedFormat, TimeSpan? offset, CancellationToken cancellationToken) { var resourcePool = isAudio ? _audioImageResourcePool : _videoImageResourcePool; - var inputArgument = GetInputArgument(inputFiles, type); + var inputArgument = GetInputArgument(inputFiles, protocol); if (!isAudio) { try { - return await ExtractImageInternal(inputArgument, type, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, true, resourcePool, cancellationToken).ConfigureAwait(false); } catch { @@ -315,10 +317,10 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - return await ExtractImageInternal(inputArgument, type, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); + return await ExtractImageInternal(inputArgument, protocol, threedFormat, offset, false, resourcePool, cancellationToken).ConfigureAwait(false); } - private async Task<Stream> ExtractImageInternal(string inputPath, InputType type, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) + private async Task<Stream> ExtractImageInternal(string inputPath, MediaProtocol protocol, Video3DFormat? threedFormat, TimeSpan? offset, bool useIFrame, SemaphoreSlim resourcePool, CancellationToken cancellationToken) { if (string.IsNullOrEmpty(inputPath)) { @@ -357,7 +359,7 @@ namespace MediaBrowser.MediaEncoding.Encoder var args = useIFrame ? string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, "-", vf) : string.Format("-i {0} -threads 0 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf); - var probeSize = GetProbeSizeArgument(type); + var probeSize = GetProbeSizeArgument(new[] { inputPath }, protocol); if (!string.IsNullOrEmpty(probeSize)) { diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 5d066ee65..154541316 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -127,26 +127,19 @@ namespace MediaBrowser.MediaEncoding.Subtitles var subtitleStream = mediaSource.MediaStreams .First(i => i.Type == MediaStreamType.Subtitle && i.Index == subtitleStreamIndex); - var inputType = mediaSource.LocationType == LocationType.Remote ? InputType.Url : InputType.File; var inputFiles = new[] { mediaSource.Path }; if (mediaSource.VideoType.HasValue) { - if (mediaSource.VideoType.Value == VideoType.BluRay) + if (mediaSource.VideoType.Value == VideoType.BluRay || + mediaSource.VideoType.Value == VideoType.Dvd) { - inputType = InputType.Bluray; - var mediaSourceItem = (Video)_libraryManager.GetItemById(new Guid(mediaSourceId)); - inputFiles = mediaSourceItem.GetPlayableStreamFiles().ToArray(); - } - else if (mediaSource.VideoType.Value == VideoType.Dvd) - { - inputType = InputType.Dvd; var mediaSourceItem = (Video)_libraryManager.GetItemById(new Guid(mediaSourceId)); inputFiles = mediaSourceItem.GetPlayableStreamFiles().ToArray(); } } - var fileInfo = await GetReadableFile(mediaSource.Path, inputFiles, inputType, subtitleStream, cancellationToken).ConfigureAwait(false); + var fileInfo = await GetReadableFile(mediaSource.Path, inputFiles, mediaSource.Protocol, subtitleStream, cancellationToken).ConfigureAwait(false); var stream = await GetSubtitleStream(fileInfo.Item1, subtitleStream.Language).ConfigureAwait(false); @@ -180,7 +173,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles private async Task<Tuple<string, string>> GetReadableFile(string mediaPath, string[] inputFiles, - InputType type, + MediaProtocol protocol, MediaStream subtitleStream, CancellationToken cancellationToken) { @@ -189,7 +182,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles // Extract var outputPath = GetSubtitleCachePath(mediaPath, subtitleStream.Index, ".ass"); - await ExtractTextSubtitle(inputFiles, type, subtitleStream.Index, false, outputPath, cancellationToken) + await ExtractTextSubtitle(inputFiles, protocol, subtitleStream.Index, false, outputPath, cancellationToken) .ConfigureAwait(false); return new Tuple<string, string>(outputPath, "ass"); @@ -451,14 +444,14 @@ namespace MediaBrowser.MediaEncoding.Subtitles /// Extracts the text subtitle. /// </summary> /// <param name="inputFiles">The input files.</param> - /// <param name="type">The type.</param> + /// <param name="protocol">The protocol.</param> /// <param name="subtitleStreamIndex">Index of the subtitle stream.</param> /// <param name="copySubtitleStream">if set to true, copy stream instead of converting.</param> /// <param name="outputPath">The output path.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>Task.</returns> /// <exception cref="System.ArgumentException">Must use inputPath list overload</exception> - private async Task ExtractTextSubtitle(string[] inputFiles, InputType type, int subtitleStreamIndex, + private async Task ExtractTextSubtitle(string[] inputFiles, MediaProtocol protocol, int subtitleStreamIndex, bool copySubtitleStream, string outputPath, CancellationToken cancellationToken) { var semaphore = GetLock(outputPath); @@ -469,7 +462,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { if (!File.Exists(outputPath)) { - await ExtractTextSubtitleInternal(_mediaEncoder.GetInputArgument(inputFiles, type), subtitleStreamIndex, + await ExtractTextSubtitleInternal(_mediaEncoder.GetInputArgument(inputFiles, protocol), subtitleStreamIndex, copySubtitleStream, outputPath, cancellationToken).ConfigureAwait(false); } } diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs index d7e756b43..cf5518db0 100644 --- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs +++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs @@ -8,6 +8,7 @@ namespace MediaBrowser.Model.Dto { public class MediaSourceInfo { + public MediaProtocol Protocol { get; set; } public string Id { get; set; } public string Path { get; set; } @@ -17,8 +18,6 @@ namespace MediaBrowser.Model.Dto public string Container { get; set; } public long? Size { get; set; } - public LocationType LocationType { get; set; } - public string Name { get; set; } public long? RunTimeTicks { get; set; } diff --git a/MediaBrowser.Model/MediaInfo/Container.cs b/MediaBrowser.Model/MediaInfo/Container.cs index 3762edf9f..89ce9864c 100644 --- a/MediaBrowser.Model/MediaInfo/Container.cs +++ b/MediaBrowser.Model/MediaInfo/Container.cs @@ -6,4 +6,11 @@ namespace MediaBrowser.Model.MediaInfo public const string MP4 = "mp4"; public const string MKV = "mkv"; } + + public enum MediaProtocol + { + File = 0, + Http = 1, + Rtmp = 2 + } } diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs index f63422345..3a701f60c 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeAudioInfo.cs @@ -6,6 +6,7 @@ using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Entities; +using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Serialization; using System; using System.Collections.Generic; @@ -73,10 +74,9 @@ namespace MediaBrowser.Providers.MediaInfo { } - const InputType type = InputType.File; var inputPath = new[] { item.Path }; - var result = await _mediaEncoder.GetMediaInfo(inputPath, type, false, cancellationToken).ConfigureAwait(false); + var result = await _mediaEncoder.GetMediaInfo(inputPath, MediaProtocol.File, false, cancellationToken).ConfigureAwait(false); Directory.CreateDirectory(Path.GetDirectoryName(cachePath)); _json.SerializeToFile(result, cachePath); diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs index 6f888097b..65faae327 100644 --- a/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs +++ b/MediaBrowser.Providers/MediaInfo/FFProbeVideoInfo.cs @@ -126,7 +126,7 @@ namespace MediaBrowser.Providers.MediaInfo private const string SchemaVersion = "1"; - private async Task<InternalMediaInfoResult> GetMediaInfo(BaseItem item, + private async Task<InternalMediaInfoResult> GetMediaInfo(Video item, IIsoMount isoMount, CancellationToken cancellationToken) { @@ -149,17 +149,13 @@ namespace MediaBrowser.Providers.MediaInfo { } - var type = InputType.File; - var inputPath = isoMount == null ? new[] { item.Path } : new[] { isoMount.MountedPath }; + var protocol = item.LocationType == LocationType.Remote + ? MediaProtocol.Http + : MediaProtocol.File; - var video = item as Video; + var inputPath = MediaEncoderHelpers.GetInputArgument(item.Path, protocol, isoMount, item.PlayableStreamFileNames); - if (video != null) - { - inputPath = MediaEncoderHelpers.GetInputArgument(video.Path, video.LocationType == LocationType.Remote, video.VideoType, video.IsoType, isoMount, video.PlayableStreamFileNames, out type); - } - - var result = await _mediaEncoder.GetMediaInfo(inputPath, type, false, cancellationToken).ConfigureAwait(false); + var result = await _mediaEncoder.GetMediaInfo(inputPath, protocol, false, cancellationToken).ConfigureAwait(false); Directory.CreateDirectory(Path.GetDirectoryName(cachePath)); _json.SerializeToFile(result, cachePath); diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs index 70daa3f51..a2ec897a1 100644 --- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Providers.MediaInfo { @@ -89,11 +90,13 @@ namespace MediaBrowser.Providers.MediaInfo ? TimeSpan.FromTicks(Convert.ToInt64(item.RunTimeTicks.Value * .1)) : TimeSpan.FromSeconds(10); - InputType type; + var protocol = item.LocationType == LocationType.Remote + ? MediaProtocol.Http + : MediaProtocol.File; - var inputPath = MediaEncoderHelpers.GetInputArgument(item.Path, item.LocationType == LocationType.Remote, item.VideoType, item.IsoType, isoMount, item.PlayableStreamFileNames, out type); + var inputPath = MediaEncoderHelpers.GetInputArgument(item.Path, protocol, isoMount, item.PlayableStreamFileNames); - var stream = await _mediaEncoder.ExtractVideoImage(inputPath, type, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false); + var stream = await _mediaEncoder.ExtractVideoImage(inputPath, protocol, item.Video3DFormat, imageOffset, cancellationToken).ConfigureAwait(false); return new DynamicImageResponse { diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs index fdc5cfd22..43de6080f 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs @@ -8,8 +8,8 @@ using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Channels; using MediaBrowser.Model.Dto; -using MediaBrowser.Model.Entities; using MediaBrowser.Model.Logging; +using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Querying; using System; using System.Collections.Generic; @@ -182,7 +182,7 @@ namespace MediaBrowser.Server.Implementations.Channels var list = sources.ToList(); - var cachedVersions = list.Where(i => i.LocationType == LocationType.FileSystem).ToList(); + var cachedVersions = list.Where(i => i.Protocol == MediaProtocol.File).ToList(); if (cachedVersions.Count > 0) { @@ -190,7 +190,12 @@ namespace MediaBrowser.Server.Implementations.Channels return; } - var source = list.First(); + var source = list.FirstOrDefault(i => i.Protocol == MediaProtocol.Http); + + if (source == null) + { + return; + } var options = new HttpRequestOptions { diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs index ad775b576..59e4e695d 100644 --- a/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs +++ b/MediaBrowser.Server.Implementations/Channels/ChannelManager.cs @@ -280,7 +280,7 @@ namespace MediaBrowser.Server.Implementations.Channels MediaStreams = GetMediaStreams(info).ToList(), Container = info.Container, - LocationType = info.IsRemote ? LocationType.Remote : LocationType.FileSystem, + Protocol = info.Protocol, Path = info.Path, RequiredHttpHeaders = info.RequiredHttpHeaders, RunTimeTicks = item.RunTimeTicks, @@ -555,17 +555,18 @@ namespace MediaBrowser.Server.Implementations.Channels return GetChannelItemEntity(i.Item2, channelProvider, channel, token); }); - IEnumerable<BaseItem> internalItems = await Task.WhenAll(itemTasks).ConfigureAwait(false); + var internalItems = await Task.WhenAll(itemTasks).ConfigureAwait(false); - internalItems = ApplyFilters(internalItems, query.Filters, user); + internalItems = ApplyFilters(internalItems, query.Filters, user).ToArray(); + await RefreshIfNeeded(internalItems, cancellationToken).ConfigureAwait(false); if (query.StartIndex.HasValue) { - internalItems = internalItems.Skip(query.StartIndex.Value); + internalItems = internalItems.Skip(query.StartIndex.Value).ToArray(); } if (query.Limit.HasValue) { - internalItems = internalItems.Take(query.Limit.Value); + internalItems = internalItems.Take(query.Limit.Value).ToArray(); } var returnItemArray = internalItems.Select(i => _dtoService.GetBaseItemDto(i, query.Fields, user)) @@ -658,6 +659,7 @@ namespace MediaBrowser.Server.Implementations.Channels }); var internalItems = await Task.WhenAll(itemTasks).ConfigureAwait(false); + await RefreshIfNeeded(internalItems, cancellationToken).ConfigureAwait(false); var returnItemArray = internalItems.Select(i => _dtoService.GetBaseItemDto(i, query.Fields, user)) .ToArray(); diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs index 6a0723c52..c7c93057d 100644 --- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs +++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs @@ -1111,7 +1111,7 @@ namespace MediaBrowser.Server.Implementations.Dto if (tvChannel != null) { - dto.MediaSources = GetMediaSources(tvChannel); + dto.MediaSources = tvChannel.GetMediaSources(true).ToList(); } var channelItem = item as IChannelItem; @@ -1123,43 +1123,6 @@ namespace MediaBrowser.Server.Implementations.Dto } } - public List<MediaSourceInfo> GetMediaSources(BaseItem item) - { - var video = item as Video; - - if (video != null) - { - return video.GetMediaSources(true).ToList(); - } - - var audio = item as Audio; - - if (audio != null) - { - return audio.GetMediaSources(true).ToList(); - } - - var result = new List<MediaSourceInfo> - { - new MediaSourceInfo - { - Id = item.Id.ToString("N"), - LocationType = item.LocationType, - Name = item.Name, - Path = GetMappedPath(item), - MediaStreams = _itemRepo.GetMediaStreams(new MediaStreamQuery - { - ItemId = item.Id - - }).ToList(), - - RunTimeTicks = item.RunTimeTicks - } - }; - - return result; - } - private string GetMappedPath(IHasMetadata item) { var path = item.Path; diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs index 249d7f3a7..412b2e7bd 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs @@ -222,7 +222,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv RunTimeTicks = (info.EndDate - info.StartDate).Ticks, OriginalAirDate = info.OriginalAirDate, - MediaSources = _dtoService.GetMediaSources((BaseItem)recording) + MediaSources = recording.GetMediaSources(true).ToList() }; dto.MediaStreams = dto.MediaSources.SelectMany(i => i.MediaStreams).ToList(); @@ -317,7 +317,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv Id = info.Id.ToString("N"), MediaType = info.MediaType, ExternalId = info.ExternalId, - MediaSources = _dtoService.GetMediaSources(info) + MediaSources = info.GetMediaSources(true).ToList() }; if (user != null) diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json index d4c31a61e..8e698095f 100644 --- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json +++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json @@ -148,5 +148,27 @@ "LabelChapterDownloaders": "Chapter downloaders:", "LabelChapterDownloadersHelp": "Enable and rank your preferred chapter downloaders in order of priority. Lower priority downloaders will only be used to fill in missing information.", "HeaderFavoriteAlbums": "Favorite Albums", - "HeaderLatestChannelMedia": "Latest Channel Items" + "HeaderLatestChannelMedia": "Latest Channel Items", + "ButtonOrganizeFile": "Organize File", + "ButtonDeleteFile": "Delete File", + "HeaderOrganizeFile": "Organize File", + "HeaderDeleteFile": "Delete File", + "StatusSkipped": "Skipped", + "StatusFailed": "Failed", + "StatusSuccess": "Success", + "MessageFileWillBeDeleted": "The following file will be deleted:", + "MessageSureYouWishToProceed": "Are you sure you wish to proceed?", + "MessageDuplicatesWillBeDeleted": "In addition the following dupliates will be deleted:", + "MessageFollowingFileWillBeMovedFrom": "The following file will be moved from:", + "MessageDestinationTo": "to:", + "HeaderSelectWatchFolder": "Select Watch Folder", + "HeaderSelectWatchFolderHelp": "Browse or enter the path to your watch folder. The folder must be writeable.", + "OrganizePatternResult": "Result: {0}", + "HeaderRestart": "Restart", + "HeaderShutdown": "Shutdown", + "MessageConfirmRestart": "Are you sure you wish to restart Media Browser Server?", + "MessageConfirmShutdown": "Are you sure you wish to shutdown Media Browser Server?", + "ButtonUpdateNow": "Update Now", + "NewVersionOfSomethingAvailable": "A new version of {0} is available!", + "VersionXIsAvailableForDownload": "Version {0} is now available for download." }
\ No newline at end of file diff --git a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs index 1f2db0dcf..056a526f6 100644 --- a/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs +++ b/MediaBrowser.Server.Implementations/MediaEncoder/EncodingManager.cs @@ -14,6 +14,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using MediaBrowser.Model.MediaInfo; namespace MediaBrowser.Server.Implementations.MediaEncoder { @@ -133,15 +134,15 @@ namespace MediaBrowser.Server.Implementations.MediaEncoder // Add some time for the first chapter to make sure we don't end up with a black image var time = chapter.StartPositionTicks == 0 ? TimeSpan.FromTicks(Math.Min(FirstChapterTicks, video.RunTimeTicks ?? 0)) : TimeSpan.FromTicks(chapter.StartPositionTicks); - InputType type; + var protocol = MediaProtocol.File; - var inputPath = MediaEncoderHelpers.GetInputArgument(video.Path, false, video.VideoType, video.IsoType, null, video.PlayableStreamFileNames, out type); + var inputPath = MediaEncoderHelpers.GetInputArgument(video.Path, protocol, null, video.PlayableStreamFileNames); try { Directory.CreateDirectory(Path.GetDirectoryName(path)); - using (var stream = await _encoder.ExtractVideoImage(inputPath, type, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false)) + using (var stream = await _encoder.ExtractVideoImage(inputPath, protocol, video.Video3DFormat, time, cancellationToken).ConfigureAwait(false)) { using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true)) { diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec index 68434ab1d..b751d0963 100644 --- a/Nuget/MediaBrowser.Common.Internal.nuspec +++ b/Nuget/MediaBrowser.Common.Internal.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common.Internal</id> - <version>3.0.405</version> + <version>3.0.406</version> <title>MediaBrowser.Common.Internal</title> <authors>Luke</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description> <copyright>Copyright © Media Browser 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.405" /> + <dependency id="MediaBrowser.Common" version="3.0.406" /> <dependency id="NLog" version="2.1.0" /> <dependency id="SimpleInjector" version="2.5.0" /> <dependency id="sharpcompress" version="0.10.2" /> diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec index 5f2bae74d..83314256e 100644 --- a/Nuget/MediaBrowser.Common.nuspec +++ b/Nuget/MediaBrowser.Common.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> <metadata> <id>MediaBrowser.Common</id> - <version>3.0.405</version> + <version>3.0.406</version> <title>MediaBrowser.Common</title> <authors>Media Browser Team</authors> <owners>ebr,Luke,scottisafool</owners> diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec index 91dfb4d7a..f95c7c735 100644 --- a/Nuget/MediaBrowser.Server.Core.nuspec +++ b/Nuget/MediaBrowser.Server.Core.nuspec @@ -2,7 +2,7 @@ <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>MediaBrowser.Server.Core</id> - <version>3.0.405</version> + <version>3.0.406</version> <title>Media Browser.Server.Core</title> <authors>Media Browser Team</authors> <owners>ebr,Luke,scottisafool</owners> @@ -12,7 +12,7 @@ <description>Contains core components required to build plugins for Media Browser Server.</description> <copyright>Copyright © Media Browser 2013</copyright> <dependencies> - <dependency id="MediaBrowser.Common" version="3.0.405" /> + <dependency id="MediaBrowser.Common" version="3.0.406" /> </dependencies> </metadata> <files> |
