diff options
| author | Luke <luke.pulverenti@gmail.com> | 2015-10-26 18:50:19 -0400 |
|---|---|---|
| committer | Luke <luke.pulverenti@gmail.com> | 2015-10-26 18:50:19 -0400 |
| commit | 35778ebc02e5931142a1fe31a256b7488a07c5c2 (patch) | |
| tree | ced0290be8820f5e507b51ca4c5165212b1879d1 /MediaBrowser.MediaEncoding | |
| parent | c0dc8d055bfd4d2f58591083beb9e9128357aad6 (diff) | |
| parent | 8d77308593c3b16b733b0109323770d9dfe7e166 (diff) | |
Merge pull request #1222 from MediaBrowser/dev
3.0.5768.7
Diffstat (limited to 'MediaBrowser.MediaEncoding')
12 files changed, 227 insertions, 86 deletions
diff --git a/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs b/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs index 17470d206..1ddb73d11 100644 --- a/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs +++ b/MediaBrowser.MediaEncoding/Configuration/EncodingConfigurationFactory.cs @@ -2,26 +2,38 @@ using MediaBrowser.Model.Configuration; using System.Collections.Generic; using System.IO; +using CommonIO; +using MediaBrowser.Common.IO; namespace MediaBrowser.MediaEncoding.Configuration { public class EncodingConfigurationFactory : IConfigurationFactory { + private readonly IFileSystem _fileSystem; + + public EncodingConfigurationFactory(IFileSystem fileSystem) + { + _fileSystem = fileSystem; + } + public IEnumerable<ConfigurationStore> GetConfigurations() { return new[] { - new EncodingConfigurationStore() + new EncodingConfigurationStore(_fileSystem) }; } } public class EncodingConfigurationStore : ConfigurationStore, IValidatingConfiguration { - public EncodingConfigurationStore() + private readonly IFileSystem _fileSystem; + + public EncodingConfigurationStore(IFileSystem fileSystem) { ConfigurationType = typeof(EncodingOptions); Key = "encoding"; + _fileSystem = fileSystem; } public void Validate(object oldConfig, object newConfig) @@ -35,7 +47,7 @@ namespace MediaBrowser.MediaEncoding.Configuration && !string.Equals(oldEncodingConfig.TranscodingTempPath ?? string.Empty, newPath)) { // Validate - if (!Directory.Exists(newPath)) + if (!_fileSystem.DirectoryExists(newPath)) { throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath)); } diff --git a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs index e9204ef5b..b488741d1 100644 --- a/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/AudioEncoder.cs @@ -9,6 +9,7 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using System; using System.Collections.Generic; +using CommonIO; namespace MediaBrowser.MediaEncoding.Encoder { diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs index 181f147b4..912110c04 100644 --- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs @@ -19,6 +19,7 @@ using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; +using CommonIO; namespace MediaBrowser.MediaEncoding.Encoder { @@ -65,7 +66,7 @@ namespace MediaBrowser.MediaEncoding.Encoder .CreateJob(options, IsVideoEncoder, progress, cancellationToken).ConfigureAwait(false); encodingJob.OutputFilePath = GetOutputFilePath(encodingJob); - Directory.CreateDirectory(Path.GetDirectoryName(encodingJob.OutputFilePath)); + FileSystem.CreateDirectory(Path.GetDirectoryName(encodingJob.OutputFilePath)); encodingJob.ReadInputAtNativeFramerate = options.ReadInputAtNativeFramerate; @@ -112,7 +113,7 @@ namespace MediaBrowser.MediaEncoding.Encoder Logger.Info(commandLineLogMessage); var logFilePath = Path.Combine(ConfigurationManager.CommonApplicationPaths.LogDirectoryPath, "transcode-" + Guid.NewGuid() + ".txt"); - Directory.CreateDirectory(Path.GetDirectoryName(logFilePath)); + FileSystem.CreateDirectory(Path.GetDirectoryName(logFilePath)); // FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory. encodingJob.LogFileStream = FileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true); @@ -144,7 +145,7 @@ namespace MediaBrowser.MediaEncoding.Encoder new JobLogger(Logger).StartStreamingLog(encodingJob, process.StandardError.BaseStream, encodingJob.LogFileStream); // Wait for the file to exist before proceeeding - while (!File.Exists(encodingJob.OutputFilePath) && !encodingJob.HasExited) + while (!FileSystem.FileExists(encodingJob.OutputFilePath) && !encodingJob.HasExited) { await Task.Delay(100, cancellationToken).ConfigureAwait(false); } @@ -342,9 +343,55 @@ namespace MediaBrowser.MediaEncoding.Encoder inputModifier += " -re"; } + var videoDecoder = GetVideoDecoder(job); + if (!string.IsNullOrWhiteSpace(videoDecoder)) + { + inputModifier += " " + videoDecoder; + } + return inputModifier; } + /// <summary> + /// Gets the name of the output video codec + /// </summary> + /// <param name="state">The state.</param> + /// <returns>System.String.</returns> + protected string GetVideoDecoder(EncodingJob state) + { + if (string.Equals(GetEncodingOptions().HardwareVideoDecoder, "qsv", StringComparison.OrdinalIgnoreCase)) + { + if (state.VideoStream != null && !string.IsNullOrWhiteSpace(state.VideoStream.Codec)) + { + switch (state.MediaSource.VideoStream.Codec.ToLower()) + { + case "avc": + case "h264": + if (MediaEncoder.SupportsDecoder("h264_qsv")) + { + return "-c:v h264_qsv "; + } + break; + case "mpeg2video": + if (MediaEncoder.SupportsDecoder("mpeg2_qsv")) + { + return "-c:v mpeg2_qsv "; + } + break; + case "vc1": + if (MediaEncoder.SupportsDecoder("vc1_qsv")) + { + return "-c:v vc1_qsv "; + } + break; + } + } + } + + // leave blank so ffmpeg will decide + return null; + } + private string GetUserAgentParam(EncodingJob job) { string useragent = null; @@ -422,7 +469,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { if (!(job.VideoType == VideoType.Iso && job.IsoMount == null)) { - inputPath = MediaEncoderHelpers.GetInputArgument(job.MediaPath, job.InputProtocol, job.IsoMount, job.PlayableStreamFileNames); + inputPath = MediaEncoderHelpers.GetInputArgument(FileSystem, job.MediaPath, job.InputProtocol, job.IsoMount, job.PlayableStreamFileNames); } } @@ -436,7 +483,7 @@ namespace MediaBrowser.MediaEncoding.Encoder state.IsoMount = await IsoManager.Mount(state.MediaPath, cancellationToken).ConfigureAwait(false); } - if (state.MediaSource.RequiresOpening) + if (state.MediaSource.RequiresOpening && string.IsNullOrWhiteSpace(state.LiveStreamId)) { var liveStreamResponse = await MediaSourceManager.OpenLiveStream(new LiveStreamRequest { diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs index 806910d89..07626db33 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJob.cs @@ -56,7 +56,7 @@ namespace MediaBrowser.MediaEncoding.Encoder public bool EnableMpegtsM2TsMode { get; set; } public TranscodeSeekInfo TranscodeSeekInfo { get; set; } public long? EncodingDurationTicks { get; set; } - public string LiveTvStreamId { get; set; } + public string LiveStreamId { get; set; } public long? RunTimeTicks; public string ItemType { get; set; } @@ -368,6 +368,17 @@ namespace MediaBrowser.MediaEncoding.Encoder } } + public string TargetVideoCodecTag + { + get + { + var stream = VideoStream; + return !Options.Static + ? null + : stream == null ? null : stream.CodecTag; + } + } + public bool? IsTargetAnamorphic { get diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs index 476d9166b..692fe2b6a 100644 --- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs +++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs @@ -326,26 +326,36 @@ namespace MediaBrowser.MediaEncoding.Encoder /// <returns>System.Nullable{System.Int32}.</returns> private int? GetNumAudioChannelsParam(EncodingJobOptions request, MediaStream audioStream, string outputAudioCodec) { - if (audioStream != null) + var inputChannels = audioStream == null + ? null + : audioStream.Channels; + + if (inputChannels <= 0) { - var codec = outputAudioCodec ?? string.Empty; + inputChannels = null; + } - if (audioStream.Channels > 2 && codec.IndexOf("wma", StringComparison.OrdinalIgnoreCase) != -1) - { - // wmav2 currently only supports two channel output - return 2; - } + var codec = outputAudioCodec ?? string.Empty; + + if (codec.IndexOf("wma", StringComparison.OrdinalIgnoreCase) != -1) + { + // wmav2 currently only supports two channel output + return Math.Min(2, inputChannels ?? 2); } if (request.MaxAudioChannels.HasValue) { - if (audioStream != null && audioStream.Channels.HasValue) + if (inputChannels.HasValue) { - return Math.Min(request.MaxAudioChannels.Value, audioStream.Channels.Value); + return Math.Min(request.MaxAudioChannels.Value, inputChannels.Value); } + var channelLimit = codec.IndexOf("mp3", StringComparison.OrdinalIgnoreCase) != -1 + ? 2 + : 6; + // If we don't have any media info then limit it to 5 to prevent encoding errors due to asking for too many channels - return Math.Min(request.MaxAudioChannels.Value, 5); + return Math.Min(request.MaxAudioChannels.Value, channelLimit); } return request.AudioChannels; @@ -519,6 +529,11 @@ namespace MediaBrowser.MediaEncoding.Encoder return false; } + if (videoStream.IsAnamorphic ?? false) + { + return false; + } + // Can't stream copy if we're burning in subtitles if (request.SubtitleStreamIndex.HasValue) { @@ -735,7 +750,8 @@ namespace MediaBrowser.MediaEncoding.Encoder state.IsTargetCabac, state.TargetRefFrames, state.TargetVideoStreamCount, - state.TargetAudioStreamCount); + state.TargetAudioStreamCount, + state.TargetVideoCodecTag); if (mediaProfile != null) { diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs index 4fcc71f97..c8361ea04 100644 --- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs @@ -22,6 +22,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using CommonIO; namespace MediaBrowser.MediaEncoding.Encoder { @@ -97,6 +98,22 @@ namespace MediaBrowser.MediaEncoding.Encoder FFMpegPath = ffMpegPath; } + public void SetAvailableEncoders(List<string> list) + { + + } + + private List<string> _decoders = new List<string>(); + public void SetAvailableDecoders(List<string> list) + { + _decoders = list.ToList(); + } + + public bool SupportsDecoder(string decoder) + { + return _decoders.Contains(decoder, StringComparer.OrdinalIgnoreCase); + } + /// <summary> /// Gets the encoder path. /// </summary> @@ -116,7 +133,7 @@ namespace MediaBrowser.MediaEncoding.Encoder { var extractChapters = request.MediaType == DlnaProfileType.Video && request.ExtractChapters; - var inputFiles = MediaEncoderHelpers.GetInputArgument(request.InputPath, request.Protocol, request.MountedIso, request.PlayableStreamFileNames); + var inputFiles = MediaEncoderHelpers.GetInputArgument(FileSystem, request.InputPath, request.Protocol, request.MountedIso, request.PlayableStreamFileNames); var extractKeyFrameInterval = request.ExtractKeyFrameInterval && request.Protocol == MediaProtocol.File && request.VideoType == VideoType.VideoFile; @@ -199,10 +216,10 @@ namespace MediaBrowser.MediaEncoding.Encoder _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); - await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - using (var processWrapper = new ProcessWrapper(process, this, _logger)) { + await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + try { StartProcess(processWrapper); @@ -222,53 +239,55 @@ namespace MediaBrowser.MediaEncoding.Encoder var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream); - if (result != null) + if (result.streams == null && result.format == null) { - if (result.streams != null) + throw new ApplicationException("ffprobe failed - streams and format are both null."); + } + + if (result.streams != null) + { + // Normalize aspect ratio if invalid + foreach (var stream in result.streams) { - // Normalize aspect ratio if invalid - foreach (var stream in result.streams) + if (string.Equals(stream.display_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase)) { - if (string.Equals(stream.display_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase)) - { - stream.display_aspect_ratio = string.Empty; - } - if (string.Equals(stream.sample_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase)) - { - stream.sample_aspect_ratio = string.Empty; - } + stream.display_aspect_ratio = string.Empty; + } + if (string.Equals(stream.sample_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase)) + { + stream.sample_aspect_ratio = string.Empty; } } + } - var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); + var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol); - if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue) + if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue) + { + if (ConfigurationManager.Configuration.EnableVideoFrameByFrameAnalysis && mediaInfo.Size.HasValue) { - if (ConfigurationManager.Configuration.EnableVideoFrameByFrameAnalysis && mediaInfo.Size.HasValue) + foreach (var stream in mediaInfo.MediaStreams) { - foreach (var stream in mediaInfo.MediaStreams) + if (EnableKeyframeExtraction(mediaInfo, stream)) { - if (EnableKeyframeExtraction(mediaInfo, stream)) + try { - try - { - stream.KeyFrames = await GetKeyFrames(inputPath, stream.Index, cancellationToken).ConfigureAwait(false); - } - catch (OperationCanceledException) - { - - } - catch (Exception ex) - { - _logger.ErrorException("Error getting key frame interval", ex); - } + stream.KeyFrames = await GetKeyFrames(inputPath, stream.Index, cancellationToken).ConfigureAwait(false); + } + catch (OperationCanceledException) + { + + } + catch (Exception ex) + { + _logger.ErrorException("Error getting key frame interval", ex); } } } } - - return mediaInfo; } + + return mediaInfo; } catch { @@ -330,7 +349,7 @@ namespace MediaBrowser.MediaEncoding.Encoder EnableRaisingEvents = true }; - _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); + _logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); using (process) { @@ -356,7 +375,7 @@ namespace MediaBrowser.MediaEncoding.Encoder process.WaitForExit(); - _logger.Debug("Keyframe extraction took {0} seconds", (DateTime.UtcNow - start).TotalSeconds); + _logger.Info("Keyframe extraction took {0} seconds", (DateTime.UtcNow - start).TotalSeconds); //_logger.Debug("Found keyframes {0}", string.Join(",", lines.ToArray())); return lines; } @@ -483,9 +502,6 @@ namespace MediaBrowser.MediaEncoding.Encoder } } - // TODO: Output in webp for smaller sizes - // -f image2 -f webp - // Use ffmpeg to sample 100 (we can drop this if required using thumbnail=50 for 50 frames) frames and pick the best thumbnail. Have a fall back just in case. var args = useIFrame ? string.Format("-i {0} -threads 1 -v quiet -vframes 1 -vf \"{2},thumbnail=30\" -f image2 \"{1}\"", inputPath, "-", vf) : string.Format("-i {0} -threads 1 -v quiet -vframes 1 -vf \"{2}\" -f image2 \"{1}\"", inputPath, "-", vf); @@ -520,10 +536,10 @@ namespace MediaBrowser.MediaEncoding.Encoder _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); - await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); - using (var processWrapper = new ProcessWrapper(process, this, _logger)) { + await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); + bool ranToCompletion; var memoryStream = new MemoryStream(); @@ -605,7 +621,7 @@ namespace MediaBrowser.MediaEncoding.Encoder vf += string.Format(",scale=min(iw\\,{0}):trunc(ow/dar/2)*2", maxWidthParam); } - Directory.CreateDirectory(targetDirectory); + FileSystem.CreateDirectory(targetDirectory); var outputPath = Path.Combine(targetDirectory, filenamePrefix + "%05d.jpg"); var args = string.Format("-i {0} -threads 1 -v quiet -vf \"{2}\" -f image2 \"{1}\"", inputArgument, outputPath, vf); @@ -879,4 +895,4 @@ namespace MediaBrowser.MediaEncoding.Encoder } } } -} +}
\ No newline at end of file diff --git a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs index 49eed9ee5..127145aec 100644 --- a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs +++ b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs @@ -8,6 +8,7 @@ using MediaBrowser.Model.IO; using MediaBrowser.Model.Logging; using System; using System.IO; +using CommonIO; namespace MediaBrowser.MediaEncoding.Encoder { diff --git a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj index de05d9ffd..1f74994e5 100644 --- a/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj +++ b/MediaBrowser.MediaEncoding/MediaBrowser.MediaEncoding.csproj @@ -12,7 +12,6 @@ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <FileAlignment>512</FileAlignment> <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir> - <RestorePackages>true</RestorePackages> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -40,9 +39,16 @@ <Reference Include="BDInfo"> <HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\BDInfo.dll</HintPath> </Reference> + <Reference Include="CommonIO, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\packages\CommonIO.1.0.0.5\lib\net45\CommonIO.dll</HintPath> + </Reference> <Reference Include="DvdLib"> <HintPath>..\packages\MediaBrowser.BdInfo.1.0.0.10\lib\net35\DvdLib.dll</HintPath> </Reference> + <Reference Include="Patterns.Logging"> + <HintPath>..\packages\Patterns.Logging.1.0.0.2\lib\portable-net45+sl4+wp71+win8+wpa81\Patterns.Logging.dll</HintPath> + </Reference> <Reference Include="System" /> <Reference Include="System.Core" /> <Reference Include="System.Xml.Linq" /> diff --git a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs index 0226dbc5a..7e9fa151b 100644 --- a/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs +++ b/MediaBrowser.MediaEncoding/Probing/ProbeResultNormalizer.cs @@ -8,6 +8,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; +using CommonIO; using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; @@ -129,6 +130,7 @@ namespace MediaBrowser.MediaEncoding.Probing var stream = new MediaStream { Codec = streamInfo.codec_name, + CodecTag = streamInfo.codec_tag_string, Profile = streamInfo.profile, Level = streamInfo.level, Index = streamInfo.index, @@ -148,7 +150,11 @@ namespace MediaBrowser.MediaEncoding.Probing if (!string.IsNullOrEmpty(streamInfo.sample_rate)) { - stream.SampleRate = int.Parse(streamInfo.sample_rate, _usCulture); + int value; + if (int.TryParse(streamInfo.sample_rate, NumberStyles.Any, _usCulture, out value)) + { + stream.SampleRate = value; + } } stream.ChannelLayout = ParseChannelLayout(streamInfo.channel_layout); @@ -189,12 +195,21 @@ namespace MediaBrowser.MediaEncoding.Probing if (!string.IsNullOrEmpty(streamInfo.bit_rate)) { - bitrate = int.Parse(streamInfo.bit_rate, _usCulture); + int value; + if (int.TryParse(streamInfo.bit_rate, NumberStyles.Any, _usCulture, out value)) + { + bitrate = value; + } } - else if (formatInfo != null && !string.IsNullOrEmpty(formatInfo.bit_rate) && stream.Type == MediaStreamType.Video) + + if (bitrate == 0 && formatInfo != null && !string.IsNullOrEmpty(formatInfo.bit_rate) && stream.Type == MediaStreamType.Video) { // If the stream info doesn't have a bitrate get the value from the media format info - bitrate = int.Parse(formatInfo.bit_rate, _usCulture); + int value; + if (int.TryParse(formatInfo.bit_rate, NumberStyles.Any, _usCulture, out value)) + { + bitrate = value; + } } if (bitrate > 0) @@ -516,12 +531,25 @@ namespace MediaBrowser.MediaEncoding.Probing FetchStudios(audio, tags, "label"); // These support mulitple values, but for now we only store the first. - audio.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id"))); - audio.SetProviderId(MetadataProviders.MusicBrainzArtist, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id"))); + var mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Artist Id")); + if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMARTISTID")); + audio.SetProviderId(MetadataProviders.MusicBrainzAlbumArtist, mb); + + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Artist Id")); + if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ARTISTID")); + audio.SetProviderId(MetadataProviders.MusicBrainzArtist, mb); + + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id")); + if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_ALBUMID")); + audio.SetProviderId(MetadataProviders.MusicBrainzAlbum, mb); + + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id")); + if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASEGROUPID")); + audio.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, mb); - audio.SetProviderId(MetadataProviders.MusicBrainzAlbum, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Album Id"))); - audio.SetProviderId(MetadataProviders.MusicBrainzReleaseGroup, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Group Id"))); - audio.SetProviderId(MetadataProviders.MusicBrainzTrack, GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id"))); + mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MusicBrainz Release Track Id")); + if (mb == null) mb = GetMultipleMusicBrainzId(FFProbeHelpers.GetDictionaryValue(tags, "MUSICBRAINZ_RELEASETRACKID")); + audio.SetProviderId(MetadataProviders.MusicBrainzTrack, mb); } private string GetMultipleMusicBrainzId(string value) diff --git a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs index d40d4afa7..2a6aa993c 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SrtParser.cs @@ -69,7 +69,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } subEvent.Text = string.Join(ParserValues.NewLine, multiline); subEvent.Text = subEvent.Text.Replace(@"\N", ParserValues.NewLine, StringComparison.OrdinalIgnoreCase); - subEvent.Text = Regex.Replace(subEvent.Text, @"\{(\\[\w]+\(?([\w\d]+,?)+\)?)+\}", string.Empty, RegexOptions.IgnoreCase); + subEvent.Text = Regex.Replace(subEvent.Text, @"\{(?:\\\d?[\w.-]+(?:\([^\)]*\)|&H?[0-9A-Fa-f]+&|))+\}", string.Empty, RegexOptions.IgnoreCase); subEvent.Text = Regex.Replace(subEvent.Text, "<", "<", RegexOptions.IgnoreCase); subEvent.Text = Regex.Replace(subEvent.Text, ">", ">", RegexOptions.IgnoreCase); subEvent.Text = Regex.Replace(subEvent.Text, "<(\\/?(font|b|u|i|s))((\\s+(\\w|\\w[\\w\\-]*\\w)(\\s*=\\s*(?:\\\".*?\\\"|'.*?'|[^'\\\">\\s]+))?)+\\s*|\\s*)(\\/?)>", "<$1$3$7>", RegexOptions.IgnoreCase); diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs index 9d43cafb8..ba44ed7dd 100644 --- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs +++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs @@ -18,6 +18,7 @@ using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; +using CommonIO; using UniversalDetector; namespace MediaBrowser.MediaEncoding.Subtitles @@ -49,7 +50,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { get { - return Path.Combine(_appPaths.CachePath, "subtitles"); + return Path.Combine(_appPaths.DataPath, "subtitles"); } } @@ -183,7 +184,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } } - return File.OpenRead(path); + return _fileSystem.OpenRead(path); } private Encoding GetEncoding(string charset) @@ -346,7 +347,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles try { - if (!File.Exists(outputPath)) + if (!_fileSystem.FileExists(outputPath)) { await ConvertTextSubtitleToSrtInternal(inputPath, inputProtocol, outputPath, cancellationToken).ConfigureAwait(false); } @@ -383,7 +384,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles throw new ArgumentNullException("outputPath"); } - Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(outputPath)); var encodingParam = await GetSubtitleFileCharacterSet(inputPath, inputProtocol, cancellationToken).ConfigureAwait(false); @@ -410,10 +411,10 @@ namespace MediaBrowser.MediaEncoding.Subtitles } }; - _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); + _logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-convert-" + Guid.NewGuid() + ".txt"); - Directory.CreateDirectory(Path.GetDirectoryName(logFilePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(logFilePath)); var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true); @@ -466,7 +467,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles { failed = true; - if (File.Exists(outputPath)) + if (_fileSystem.FileExists(outputPath)) { try { @@ -479,7 +480,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles } } } - else if (!File.Exists(outputPath)) + else if (!_fileSystem.FileExists(outputPath)) { failed = true; } @@ -515,7 +516,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles try { - if (!File.Exists(outputPath)) + if (!_fileSystem.FileExists(outputPath)) { await ExtractTextSubtitleInternal(_mediaEncoder.GetInputArgument(inputFiles, protocol), subtitleStreamIndex, outputCodec, outputPath, cancellationToken).ConfigureAwait(false); @@ -540,7 +541,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles throw new ArgumentNullException("outputPath"); } - Directory.CreateDirectory(Path.GetDirectoryName(outputPath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(outputPath)); var processArgs = string.Format("-i {0} -map 0:{1} -an -vn -c:s {2} \"{3}\"", inputPath, subtitleStreamIndex, outputCodec, outputPath); @@ -566,7 +567,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles _logger.Info("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments); var logFilePath = Path.Combine(_appPaths.LogDirectoryPath, "ffmpeg-sub-extract-" + Guid.NewGuid() + ".txt"); - Directory.CreateDirectory(Path.GetDirectoryName(logFilePath)); + _fileSystem.CreateDirectory(Path.GetDirectoryName(logFilePath)); var logFileStream = _fileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true); @@ -635,7 +636,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles _logger.ErrorException("Error deleting extracted subtitle {0}", ex, outputPath); } } - else if (!File.Exists(outputPath)) + else if (!_fileSystem.FileExists(outputPath)) { failed = true; } diff --git a/MediaBrowser.MediaEncoding/packages.config b/MediaBrowser.MediaEncoding/packages.config index 6e52b72b8..e8a1767e3 100644 --- a/MediaBrowser.MediaEncoding/packages.config +++ b/MediaBrowser.MediaEncoding/packages.config @@ -1,4 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <packages> + <package id="CommonIO" version="1.0.0.5" targetFramework="net45" /> <package id="MediaBrowser.BdInfo" version="1.0.0.10" targetFramework="net45" /> + <package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" /> </packages>
\ No newline at end of file |
