diff --git a/build.ps1 b/build.ps1
index 9e493454f..0ca821f4a 100644
--- a/build.ps1
+++ b/build.ps1
@@ -114,8 +114,8 @@ Function PackageMono()
get-childitem $outputFolderMono -File -Filter sqlite3.* -Recurse | foreach ($_) {remove-item $_.fullname}
get-childitem $outputFolderMono -File -Filter MediaInfo.* -Recurse | foreach ($_) {remove-item $_.fullname}
- Write-Host "Adding MediaInfoDotNet.dll.config (for dllmap)"
- Copy-Item "$sourceFolder\MediaInfoDotNet.dll.config" $outputFolderMono
+ Write-Host "Adding NzbDrone.Core.dll.config (for dllmap)"
+ Copy-Item "$sourceFolder\NzbDrone.Core\NzbDrone.Core.dll.config" $outputFolderMono
Write-Host Renaming NzbDrone.Console.exe to NzbDrone.exe
Get-ChildItem $outputFolderMono -File -Filter "NzbDrone.exe*" -Recurse | foreach ($_) {remove-item $_.fullname}
@@ -212,8 +212,8 @@ Function PackageTests()
CleanFolder $testPackageFolder $true
- Write-Host "Adding MediaInfoDotNet.dll.config (for dllmap)"
- Copy-Item "$sourceFolder\MediaInfoDotNet.dll.config" -Destination $testPackageFolder -Force
+ Write-Host "Adding NzbDrone.Core.dll.config (for dllmap)"
+ Copy-Item "$sourceFolder\NzbDrone.Core\NzbDrone.Core.dll.config" -Destination $testPackageFolder -Force
Write-Host "##teamcity[progressFinish 'Creating Test Package']"
}
diff --git a/src/MediaInfoDotNet.dll.config b/src/MediaInfoDotNet.dll.config
deleted file mode 100644
index 3094db159..000000000
--- a/src/MediaInfoDotNet.dll.config
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/VideoFileInfoReaderFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/VideoFileInfoReaderFixture.cs
index 89ee06773..438766c0f 100644
--- a/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/VideoFileInfoReaderFixture.cs
+++ b/src/NzbDrone.Core.Test/MediaFiles/MediaInfo/VideoFileInfoReaderFixture.cs
@@ -19,6 +19,10 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
Mocker.GetMock()
.Setup(s => s.FileExists(It.IsAny()))
.Returns(true);
+
+ Mocker.GetMock()
+ .Setup(s => s.OpenReadStream(It.IsAny()))
+ .Returns(s => new FileStream(s, FileMode.Open, FileAccess.Read));
}
[Test]
@@ -56,7 +60,6 @@ namespace NzbDrone.Core.Test.MediaFiles.MediaInfo
}
[Test]
- [Ignore]
public void get_info_unicode()
{
var srcPath = Path.Combine(Directory.GetCurrentDirectory(), "Files", "Media", "H264_sample.mp4");
diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MediaInfoDllCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MediaInfoDllCheck.cs
index f8eab9451..d52e6e58f 100644
--- a/src/NzbDrone.Core/HealthCheck/Checks/MediaInfoDllCheck.cs
+++ b/src/NzbDrone.Core/HealthCheck/Checks/MediaInfoDllCheck.cs
@@ -1,6 +1,6 @@
using System;
using System.Runtime.CompilerServices;
-using MediaInfoLib;
+using NzbDrone.Core.MediaFiles.MediaInfo;
namespace NzbDrone.Core.HealthCheck.Checks
{
diff --git a/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoLib.cs b/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoLib.cs
new file mode 100644
index 000000000..a4fcb03be
--- /dev/null
+++ b/src/NzbDrone.Core/MediaFiles/MediaInfo/MediaInfoLib.cs
@@ -0,0 +1,328 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using NzbDrone.Common.EnvironmentInfo;
+
+namespace NzbDrone.Core.MediaFiles.MediaInfo
+{
+ public enum StreamKind
+ {
+ General,
+ Video,
+ Audio,
+ Text,
+ Other,
+ Image,
+ Menu,
+ }
+
+ public enum InfoKind
+ {
+ Name,
+ Text,
+ Measure,
+ Options,
+ NameText,
+ MeasureText,
+ Info,
+ HowTo
+ }
+
+ public enum InfoOptions
+ {
+ ShowInInform,
+ Support,
+ ShowInSupported,
+ TypeOfValue
+ }
+
+ public enum InfoFileOptions
+ {
+ FileOption_Nothing = 0x00,
+ FileOption_NoRecursive = 0x01,
+ FileOption_CloseAll = 0x02,
+ FileOption_Max = 0x04
+ };
+
+
+ public class MediaInfo : IDisposable
+ {
+ private IntPtr _handle;
+
+ public bool MustUseAnsi { get; set; }
+ public Encoding Encoding { get; set; }
+
+ public MediaInfo()
+ {
+ _handle = MediaInfo_New();
+
+ InitializeEncoding();
+ }
+
+ ~MediaInfo()
+ {
+ MediaInfo_Delete(_handle);
+ }
+
+ public void Dispose()
+ {
+ MediaInfo_Delete(_handle);
+ GC.SuppressFinalize(this);
+ }
+
+ private void InitializeEncoding()
+ {
+ if (Environment.OSVersion.ToString().IndexOf("Windows") != -1)
+ {
+ // Windows guaranteed UCS-2
+ MustUseAnsi = false;
+ Encoding = Encoding.Unicode;
+ }
+ else
+ {
+ // Linux normally UCS-4. As fallback we try UCS-2 and plain Ansi.
+ MustUseAnsi = false;
+ Encoding = Encoding.UTF32;
+
+ if (Option("Info_Version", "").StartsWith("MediaInfoLib"))
+ {
+ return;
+ }
+
+ Encoding = Encoding.Unicode;
+
+ if (Option("Info_Version", "").StartsWith("MediaInfoLib"))
+ {
+ return;
+ }
+
+ MustUseAnsi = true;
+ Encoding = Encoding.Default;
+
+ if (Option("Info_Version", "").StartsWith("MediaInfoLib"))
+ {
+ return;
+ }
+
+ throw new NotSupportedException("Unsupported MediaInfoLib encoding");
+ }
+ }
+
+ private IntPtr MakeStringParameter(string value)
+ {
+ var buffer = Encoding.GetBytes(value);
+
+ Array.Resize(ref buffer, buffer.Length + 4);
+
+ var buf = Marshal.AllocHGlobal(buffer.Length);
+ Marshal.Copy(buffer, 0, buf, buffer.Length);
+
+ return buf;
+ }
+
+ private string MakeStringResult(IntPtr value)
+ {
+ if (Encoding == Encoding.Unicode)
+ {
+ return Marshal.PtrToStringUni(value);
+ }
+ else if (Encoding == Encoding.UTF32)
+ {
+ int i = 0;
+ for (; i < 1024; i += 4)
+ {
+ var data = Marshal.ReadInt32(value, i);
+ if (data == 0)
+ {
+ break;
+ }
+ }
+
+ var buffer = new byte[i];
+ Marshal.Copy(value, buffer, 0, i);
+
+ return Encoding.GetString(buffer, 0, i);
+ }
+ else
+ {
+ return Marshal.PtrToStringAnsi(value);
+ }
+ }
+
+ public int Open(string fileName)
+ {
+ var pFileName = MakeStringParameter(fileName);
+ try
+ {
+ if (MustUseAnsi)
+ {
+ return (int)MediaInfoA_Open(_handle, pFileName);
+ }
+ else
+ {
+ return (int)MediaInfo_Open(_handle, pFileName);
+ }
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(pFileName);
+ }
+ }
+
+ 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)
+ {
+ int bufferRead;
+
+ do
+ {
+ bufferRead = stream.Read(buffer, 0, buffer.Length);
+
+ if (MediaInfo_Open_Buffer_Continue(_handle, buffer, (IntPtr)bufferRead) == (IntPtr)0)
+ {
+ break;
+ }
+
+ var seekPos = MediaInfo_Open_Buffer_Continue_GoTo_Get(_handle);
+ if (seekPos != -1)
+ {
+ seekPos = stream.Seek(seekPos, SeekOrigin.Begin);
+ MediaInfo_Open_Buffer_Init(_handle, stream.Length, seekPos);
+ }
+ } while (bufferRead > 0);
+
+ MediaInfo_Open_Buffer_Finalize(_handle);
+ }
+
+ return isValid;
+ }
+
+ public void Close()
+ {
+ MediaInfo_Close(_handle);
+ }
+
+ public string Get(StreamKind streamKind, int streamNumber, string parameter, InfoKind infoKind = InfoKind.Text, InfoKind searchKind = InfoKind.Name)
+ {
+ var pParameter = MakeStringParameter(parameter);
+ try
+ {
+ if (MustUseAnsi)
+ {
+ return MakeStringResult(MediaInfoA_Get(_handle, (IntPtr)streamKind, (IntPtr)streamNumber, pParameter, (IntPtr)infoKind, (IntPtr)searchKind));
+ }
+ else
+ {
+ return MakeStringResult(MediaInfo_Get(_handle, (IntPtr)streamKind, (IntPtr)streamNumber, pParameter, (IntPtr)infoKind, (IntPtr)searchKind));
+ }
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(pParameter);
+ }
+ }
+
+ public string Get(StreamKind streamKind, int streamNumber, int parameter, InfoKind infoKind)
+ {
+ if (MustUseAnsi)
+ {
+ return MakeStringResult(MediaInfoA_GetI(_handle, (IntPtr)streamKind, (IntPtr)streamNumber, (IntPtr)parameter, (IntPtr)infoKind));
+ }
+ else
+ {
+ return MakeStringResult(MediaInfo_GetI(_handle, (IntPtr)streamKind, (IntPtr)streamNumber, (IntPtr)parameter, (IntPtr)infoKind));
+ }
+ }
+
+ public String Option(String option, String value)
+ {
+ var pOption = MakeStringParameter(option);
+ var pValue = MakeStringParameter(value);
+ try
+ {
+ if (MustUseAnsi)
+ {
+ return MakeStringResult(MediaInfoA_Option(_handle, pOption, pValue));
+ }
+ else
+ {
+ return MakeStringResult(MediaInfo_Option(_handle, pOption, pValue));
+ }
+ }
+ finally
+ {
+ Marshal.FreeHGlobal(pOption);
+ Marshal.FreeHGlobal(pValue);
+ }
+ }
+
+ public int State_Get()
+ {
+ return (int)MediaInfo_State_Get(_handle);
+ }
+
+ public int Count_Get(StreamKind streamKind, int streamNumber = -1)
+ {
+ return (int)MediaInfo_Count_Get(_handle, (IntPtr)streamKind, (IntPtr)streamNumber);
+ }
+
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_New();
+ [DllImport("MediaInfo.dll")]
+ private static extern void MediaInfo_Delete(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_Open(IntPtr handle, IntPtr fileName);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_Open_Buffer_Init(IntPtr handle, Int64 fileSize, Int64 fileOffset);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_Open_Buffer_Continue(IntPtr handle, byte[] buffer, IntPtr bufferSize);
+ [DllImport("MediaInfo.dll")]
+ private static extern Int64 MediaInfo_Open_Buffer_Continue_GoTo_Get(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_Open_Buffer_Finalize(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern void MediaInfo_Close(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_GetI(IntPtr handle, IntPtr streamKind, IntPtr streamNumber, IntPtr parameter, IntPtr infoKind);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_Get(IntPtr handle, IntPtr streamKind, IntPtr streamNumber, IntPtr parameter, IntPtr infoKind, IntPtr searchKind);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_Option(IntPtr handle, IntPtr option, IntPtr value);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_State_Get(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfo_Count_Get(IntPtr handle, IntPtr StreamKind, IntPtr streamNumber);
+
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_New();
+ [DllImport("MediaInfo.dll")]
+ private static extern void MediaInfoA_Delete(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_Open(IntPtr handle, IntPtr fileName);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_Open_Buffer_Init(IntPtr handle, Int64 fileSize, Int64 fileOffset);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_Open_Buffer_Continue(IntPtr handle, byte[] buffer, IntPtr bufferSize);
+ [DllImport("MediaInfo.dll")]
+ private static extern Int64 MediaInfoA_Open_Buffer_Continue_GoTo_Get(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_Open_Buffer_Finalize(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern void MediaInfoA_Close(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_GetI(IntPtr handle, IntPtr streamKind, IntPtr streamNumber, IntPtr parameter, IntPtr infoKind);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_Get(IntPtr handle, IntPtr streamKind, IntPtr streamNumber, IntPtr parameter, IntPtr infoKind, IntPtr searchKind);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_Option(IntPtr handle, IntPtr option, IntPtr value);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_State_Get(IntPtr handle);
+ [DllImport("MediaInfo.dll")]
+ private static extern IntPtr MediaInfoA_Count_Get(IntPtr handle, IntPtr StreamKind, IntPtr streamNumber);
+ }
+}
diff --git a/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs b/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs
index 85666bde3..e43b3cf48 100644
--- a/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs
+++ b/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs
@@ -2,7 +2,6 @@
using System.Globalization;
using System.IO;
using System.Text;
-using MediaInfoLib;
using NLog;
using NzbDrone.Common.Disk;
using NzbDrone.Common.EnvironmentInfo;
@@ -33,29 +32,16 @@ namespace NzbDrone.Core.MediaFiles.MediaInfo
if (!_diskProvider.FileExists(filename))
throw new FileNotFoundException("Media file does not exist: " + filename);
- MediaInfoLib.MediaInfo mediaInfo = null;
+ MediaInfo mediaInfo = null;
try
{
- mediaInfo = new MediaInfoLib.MediaInfo();
+ mediaInfo = new MediaInfo();
_logger.Debug("Getting media info from {0}", filename);
mediaInfo.Option("ParseSpeed", "0.2");
- int open;
- if (OsInfo.IsWindows)
- {
- open = mediaInfo.Open(filename);
- }
- else
- {
- mediaInfo.Option("CharSet", "UTF-8");
-
- // On non-Windows the wrapper uses the ansi library methods, which libmediainfo converts internally to unicode from multibyte (utf8).
- // To avoid building MediaInfoDotNet ourselves we simply trick the wrapper to send utf8 strings instead of ansi.
- var utf8filename = Encoding.Default.GetString(Encoding.UTF8.GetBytes(filename));
- open = mediaInfo.Open(utf8filename);
- }
+ int open = mediaInfo.Open(_diskProvider.OpenReadStream(filename));
if (open != 0)
{
diff --git a/src/NzbDrone.Core/NzbDrone.Core.csproj b/src/NzbDrone.Core/NzbDrone.Core.csproj
index e09d61b9e..071cc4746 100644
--- a/src/NzbDrone.Core/NzbDrone.Core.csproj
+++ b/src/NzbDrone.Core/NzbDrone.Core.csproj
@@ -93,9 +93,6 @@
-
- ..\packages\MediaInfoNet.0.3\lib\MediaInfoDotNet.dll
-
..\packages\NLog.2.1.0\lib\net40\NLog.dll
@@ -606,6 +603,7 @@
Code
+
@@ -940,6 +938,9 @@
+
+ Always
+
diff --git a/src/NzbDrone.Core/NzbDrone.Core.dll.config b/src/NzbDrone.Core/NzbDrone.Core.dll.config
new file mode 100644
index 000000000..a139791b4
--- /dev/null
+++ b/src/NzbDrone.Core/NzbDrone.Core.dll.config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/NzbDrone.Core/packages.config b/src/NzbDrone.Core/packages.config
index b7a2989ee..4d6664b8a 100644
--- a/src/NzbDrone.Core/packages.config
+++ b/src/NzbDrone.Core/packages.config
@@ -4,7 +4,6 @@
-