diff --git a/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoLib.cs b/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoLib.cs index a4fcb03be..b094cd401 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoLib.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoLib.cs @@ -2,10 +2,20 @@ using System.IO; using System.Runtime.InteropServices; using System.Text; -using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Common.Instrumentation; +using NLog; namespace NzbDrone.Core.MediaFiles.MediaInfo { + [Flags] + public enum BufferStatus + { + Accepted = 1, + Filled = 2, + Updated = 4, + Finalized = 8 + } + public enum StreamKind { General, @@ -14,7 +24,7 @@ public enum StreamKind Text, Other, Image, - Menu, + Menu } public enum InfoKind @@ -48,6 +58,7 @@ public enum InfoFileOptions public class MediaInfo : IDisposable { + private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(MediaInfo)); private IntPtr _handle; public bool MustUseAnsi { get; set; } @@ -172,31 +183,40 @@ public int Open(string fileName) public int Open(Stream stream) { - var buffer = new byte[64 * 1024]; - var isValid = (int)MediaInfo_Open_Buffer_Init(_handle, stream.Length, 0); if (isValid == 1) { + var buffer = new byte[16 * 1024]; + long seekStart = 0; + long totalRead = 0; int bufferRead; do { bufferRead = stream.Read(buffer, 0, buffer.Length); + totalRead += bufferRead; - if (MediaInfo_Open_Buffer_Continue(_handle, buffer, (IntPtr)bufferRead) == (IntPtr)0) + var status = (BufferStatus)MediaInfo_Open_Buffer_Continue(_handle, buffer, (IntPtr)bufferRead); + + if (status.HasFlag(BufferStatus.Finalized) || status <= 0 || bufferRead == 0) { + Logger.Trace("Read file offset {0}-{1} ({2} bytes)", seekStart, stream.Position, stream.Position - seekStart); break; } var seekPos = MediaInfo_Open_Buffer_Continue_GoTo_Get(_handle); if (seekPos != -1) { + Logger.Trace("Read file offset {0}-{1} ({2} bytes)", seekStart, stream.Position, stream.Position - seekStart); seekPos = stream.Seek(seekPos, SeekOrigin.Begin); + seekStart = seekPos; MediaInfo_Open_Buffer_Init(_handle, stream.Length, seekPos); } } while (bufferRead > 0); MediaInfo_Open_Buffer_Finalize(_handle); + + Logger.Trace("Read a total of {0} bytes ({1:0.0}%)", totalRead, totalRead * 100.0 / stream.Length); } return isValid; diff --git a/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs b/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs index 61a1d84ef..e86680190 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs @@ -39,7 +39,7 @@ public MediaInfoModel GetMediaInfo(string filename) mediaInfo = new MediaInfo(); _logger.Debug("Getting media info from {0}", filename); - mediaInfo.Option("ParseSpeed", "0.2"); + mediaInfo.Option("ParseSpeed", "0.0"); int open; @@ -48,6 +48,28 @@ public MediaInfoModel GetMediaInfo(string filename) open = mediaInfo.Open(stream); } + if (open != 0) + { + int audioRuntime; + int videoRuntime; + int generalRuntime; + + //Runtime + Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "PlayTime"), out videoRuntime); + Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "PlayTime"), out audioRuntime); + Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out generalRuntime); + + if (audioRuntime == 0 && videoRuntime == 0 && generalRuntime == 0) + { + mediaInfo.Option("ParseSpeed", "1.0"); + + using (var stream = _diskProvider.OpenReadStream(filename)) + { + open = mediaInfo.Open(stream); + } + } + } + if (open != 0) { int width;