MediaInfo added
New: Samples will only be skipped when under 70MB and under 8 minutes in length #ND-121 fixed
This commit is contained in:
parent
eeb16d6d5a
commit
e136b458e0
|
@ -324,7 +324,7 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void import_new_episode_no_existing_episode_file()
|
public void should_import_new_episode_no_existing_episode_file()
|
||||||
{
|
{
|
||||||
const string fileName = "WEEDS.S03E01E02.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv";
|
const string fileName = "WEEDS.S03E01E02.DUAL.bluray.x264.AC3.-HELLYWOOD.mkv";
|
||||||
|
|
||||||
|
@ -354,48 +354,6 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
|
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void should_return_null_if_file_size_is_under_40MB()
|
|
||||||
{
|
|
||||||
var series = Builder<Series>
|
|
||||||
.CreateNew()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi";
|
|
||||||
|
|
||||||
Mocker.GetMock<MediaFileProvider>()
|
|
||||||
.Setup(m => m.Exists(path))
|
|
||||||
.Returns(false);
|
|
||||||
|
|
||||||
Mocker.GetMock<DiskProvider>()
|
|
||||||
.Setup(d => d.GetSize(path))
|
|
||||||
.Returns(20.Megabytes());
|
|
||||||
|
|
||||||
Mocker.Resolve<DiskScanProvider>().ImportFile(series, path).Should().BeNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void VerifyFileImport(EpisodeFile result, AutoMoqer Mocker, Episode fakeEpisode, long size)
|
|
||||||
{
|
|
||||||
result.Should().NotBeNull();
|
|
||||||
result.SeriesId.Should().Be(fakeEpisode.SeriesId);
|
|
||||||
result.Size.Should().Be(size);
|
|
||||||
result.DateAdded.Should().HaveDay(DateTime.Now.Day);
|
|
||||||
Mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Once());
|
|
||||||
|
|
||||||
//Get the count of episodes linked
|
|
||||||
var count = Mocker.GetMock<EpisodeProvider>().Object.GetEpisodesByParseResult(null).Count;
|
|
||||||
|
|
||||||
Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.Is<Episode>(e => e.EpisodeFileId == result.EpisodeFileId)), Times.Exactly(count));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void VerifySkipImport(EpisodeFile result, AutoMoqer Mocker)
|
|
||||||
{
|
|
||||||
result.Should().BeNull();
|
|
||||||
Mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Never());
|
|
||||||
Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.IsAny<Episode>()), Times.Never());
|
|
||||||
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void should_set_parseResult_SceneSource_if_not_in_series_Path()
|
public void should_set_parseResult_SceneSource_if_not_in_series_Path()
|
||||||
{
|
{
|
||||||
|
@ -441,5 +399,115 @@ namespace NzbDrone.Core.Test.ProviderTests.DiskScanProviderTests
|
||||||
|
|
||||||
Mocker.Verify<EpisodeProvider>(s => s.GetEpisodesByParseResult(It.Is<EpisodeParseResult>(p => p.SceneSource == false)), Times.Once());
|
Mocker.Verify<EpisodeProvider>(s => s.GetEpisodesByParseResult(It.Is<EpisodeParseResult>(p => p.SceneSource == false)), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_return_null_if_file_size_is_under_70MB_and_runTime_under_8_minutes()
|
||||||
|
{
|
||||||
|
var series = Builder<Series>
|
||||||
|
.CreateNew()
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi";
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(m => m.Exists(path))
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(d => d.GetSize(path))
|
||||||
|
.Returns(20.Megabytes());
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaInfoProvider>()
|
||||||
|
.Setup(s => s.GetRunTime(path))
|
||||||
|
.Returns(300);
|
||||||
|
|
||||||
|
Mocker.Resolve<DiskScanProvider>().ImportFile(series, path).Should().BeNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_import_if_file_size_is_under_70MB_but_runTime_over_8_minutes()
|
||||||
|
{
|
||||||
|
var fakeSeries = Builder<Series>.CreateNew().Build();
|
||||||
|
|
||||||
|
var fakeEpisode = Builder<Episode>.CreateNew()
|
||||||
|
.With(e => e.EpisodeFileId = 0)
|
||||||
|
.With(e => e.EpisodeFile = null)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi";
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(m => m.Exists(path))
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
Mocker.GetMock<DiskProvider>()
|
||||||
|
.Setup(d => d.GetSize(path))
|
||||||
|
.Returns(20.Megabytes());
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaInfoProvider>()
|
||||||
|
.Setup(s => s.GetRunTime(path))
|
||||||
|
.Returns(600);
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>())).Returns(new List<Episode> { fakeEpisode });
|
||||||
|
|
||||||
|
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, path);
|
||||||
|
|
||||||
|
VerifyFileImport(result, Mocker, fakeEpisode, 20.Megabytes());
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void should_import_if_file_size_is_over_70MB_but_runTime_under_8_minutes()
|
||||||
|
{
|
||||||
|
With80MBFile();
|
||||||
|
|
||||||
|
var fakeSeries = Builder<Series>.CreateNew().Build();
|
||||||
|
|
||||||
|
var fakeEpisode = Builder<Episode>.CreateNew()
|
||||||
|
.With(e => e.EpisodeFileId = 0)
|
||||||
|
.With(e => e.EpisodeFile = null)
|
||||||
|
.Build();
|
||||||
|
|
||||||
|
const string path = @"C:\Test\TV\30.rock.s01e01.pilot.avi";
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaFileProvider>()
|
||||||
|
.Setup(m => m.Exists(path))
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
Mocker.GetMock<MediaInfoProvider>()
|
||||||
|
.Setup(s => s.GetRunTime(path))
|
||||||
|
.Returns(600);
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>()
|
||||||
|
.Setup(e => e.GetEpisodesByParseResult(It.IsAny<EpisodeParseResult>())).Returns(new List<Episode> { fakeEpisode });
|
||||||
|
|
||||||
|
var result = Mocker.Resolve<DiskScanProvider>().ImportFile(fakeSeries, path);
|
||||||
|
|
||||||
|
VerifyFileImport(result, Mocker, fakeEpisode, SIZE);
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void VerifyFileImport(EpisodeFile result, AutoMoqer Mocker, Episode fakeEpisode, long size)
|
||||||
|
{
|
||||||
|
result.Should().NotBeNull();
|
||||||
|
result.SeriesId.Should().Be(fakeEpisode.SeriesId);
|
||||||
|
result.Size.Should().Be(size);
|
||||||
|
result.DateAdded.Should().HaveDay(DateTime.Now.Day);
|
||||||
|
Mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Once());
|
||||||
|
|
||||||
|
//Get the count of episodes linked
|
||||||
|
var count = Mocker.GetMock<EpisodeProvider>().Object.GetEpisodesByParseResult(null).Count;
|
||||||
|
|
||||||
|
Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.Is<Episode>(e => e.EpisodeFileId == result.EpisodeFileId)), Times.Exactly(count));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void VerifySkipImport(EpisodeFile result, AutoMoqer Mocker)
|
||||||
|
{
|
||||||
|
result.Should().BeNull();
|
||||||
|
Mocker.GetMock<MediaFileProvider>().Verify(p => p.Add(It.IsAny<EpisodeFile>()), Times.Never());
|
||||||
|
Mocker.GetMock<EpisodeProvider>().Verify(p => p.UpdateEpisode(It.IsAny<Episode>()), Times.Never());
|
||||||
|
Mocker.GetMock<DiskProvider>().Verify(p => p.DeleteFile(It.IsAny<string>()), Times.Never());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Model
|
||||||
|
{
|
||||||
|
public class MediaInfoModel
|
||||||
|
{
|
||||||
|
public string VideoCodec { get; set; }
|
||||||
|
public int VideoBitrate { get; set; }
|
||||||
|
public int Width { get; set; }
|
||||||
|
public int Height { get; set; }
|
||||||
|
public string AudioFormat { get; set; }
|
||||||
|
public int AudioBitrate { get; set; }
|
||||||
|
public int RunTime { get; set; }
|
||||||
|
public int AudioStreamCount { get; set; }
|
||||||
|
public int AudioChannels { get; set; }
|
||||||
|
public string AudioProfile { get; set; }
|
||||||
|
public decimal VideoFps { get; set; }
|
||||||
|
public string AudioLanguages { get; set; }
|
||||||
|
public string Subtitles { get; set; }
|
||||||
|
public string ScanType { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -145,6 +145,9 @@
|
||||||
<Reference Include="Ionic.Zip">
|
<Reference Include="Ionic.Zip">
|
||||||
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
|
<HintPath>..\packages\DotNetZip.1.9.1.8\lib\net20\Ionic.Zip.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="MediaInfoDotNet">
|
||||||
|
<HintPath>..\packages\MediaInfoNet.0.3\lib\MediaInfoDotNet.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
<Private>True</Private>
|
<Private>True</Private>
|
||||||
|
@ -277,6 +280,7 @@
|
||||||
<Compile Include="Model\AtomicParsleyTitleType.cs" />
|
<Compile Include="Model\AtomicParsleyTitleType.cs" />
|
||||||
<Compile Include="Model\ConnectionInfoModel.cs" />
|
<Compile Include="Model\ConnectionInfoModel.cs" />
|
||||||
<Compile Include="Model\BacklogSettingType.cs" />
|
<Compile Include="Model\BacklogSettingType.cs" />
|
||||||
|
<Compile Include="Model\MediaInfoModel.cs" />
|
||||||
<Compile Include="Model\Nzbx\NzbxSearchItem.cs" />
|
<Compile Include="Model\Nzbx\NzbxSearchItem.cs" />
|
||||||
<Compile Include="Model\Nzbx\NzbxRecentItem.cs" />
|
<Compile Include="Model\Nzbx\NzbxRecentItem.cs" />
|
||||||
<Compile Include="Model\Nzbx\NzbxVotesModel.cs" />
|
<Compile Include="Model\Nzbx\NzbxVotesModel.cs" />
|
||||||
|
@ -314,6 +318,7 @@
|
||||||
<Compile Include="AutofacSignalrDependencyResolver.cs" />
|
<Compile Include="AutofacSignalrDependencyResolver.cs" />
|
||||||
<Compile Include="Providers\BannerProvider.cs" />
|
<Compile Include="Providers\BannerProvider.cs" />
|
||||||
<Compile Include="Providers\DecisionEngine\LanguageSpecification.cs" />
|
<Compile Include="Providers\DecisionEngine\LanguageSpecification.cs" />
|
||||||
|
<Compile Include="Providers\MediaInfoProvider.cs" />
|
||||||
<Compile Include="Providers\SearchProvider2.cs" />
|
<Compile Include="Providers\SearchProvider2.cs" />
|
||||||
<Compile Include="Providers\DecisionEngine\AllowedReleaseGroupSpecification.cs" />
|
<Compile Include="Providers\DecisionEngine\AllowedReleaseGroupSpecification.cs" />
|
||||||
<Compile Include="Providers\DecisionEngine\CustomStartDateSpecification.cs" />
|
<Compile Include="Providers\DecisionEngine\CustomStartDateSpecification.cs" />
|
||||||
|
@ -618,6 +623,9 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="GettingStarted.txt" />
|
<Content Include="GettingStarted.txt" />
|
||||||
<Content Include="Json.NET.license.txt" />
|
<Content Include="Json.NET.license.txt" />
|
||||||
|
<Content Include="MediaInfo.dll">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
<Content Include="NzbDrone.ico" />
|
<Content Include="NzbDrone.ico" />
|
||||||
<Content Include="license.txt" />
|
<Content Include="license.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -23,12 +23,13 @@ namespace NzbDrone.Core.Providers
|
||||||
private readonly SignalRProvider _signalRProvider;
|
private readonly SignalRProvider _signalRProvider;
|
||||||
private readonly ConfigProvider _configProvider;
|
private readonly ConfigProvider _configProvider;
|
||||||
private readonly RecycleBinProvider _recycleBinProvider;
|
private readonly RecycleBinProvider _recycleBinProvider;
|
||||||
|
private readonly MediaInfoProvider _mediaInfoProvider;
|
||||||
|
|
||||||
public DiskScanProvider(DiskProvider diskProvider, EpisodeProvider episodeProvider,
|
public DiskScanProvider(DiskProvider diskProvider, EpisodeProvider episodeProvider,
|
||||||
SeriesProvider seriesProvider, MediaFileProvider mediaFileProvider,
|
SeriesProvider seriesProvider, MediaFileProvider mediaFileProvider,
|
||||||
ExternalNotificationProvider externalNotificationProvider, DownloadProvider downloadProvider,
|
ExternalNotificationProvider externalNotificationProvider, DownloadProvider downloadProvider,
|
||||||
SignalRProvider signalRProvider, ConfigProvider configProvider,
|
SignalRProvider signalRProvider, ConfigProvider configProvider,
|
||||||
RecycleBinProvider recycleBinProvider)
|
RecycleBinProvider recycleBinProvider, MediaInfoProvider mediaInfoProvider)
|
||||||
{
|
{
|
||||||
_diskProvider = diskProvider;
|
_diskProvider = diskProvider;
|
||||||
_episodeProvider = episodeProvider;
|
_episodeProvider = episodeProvider;
|
||||||
|
@ -39,6 +40,7 @@ namespace NzbDrone.Core.Providers
|
||||||
_signalRProvider = signalRProvider;
|
_signalRProvider = signalRProvider;
|
||||||
_configProvider = configProvider;
|
_configProvider = configProvider;
|
||||||
_recycleBinProvider = recycleBinProvider;
|
_recycleBinProvider = recycleBinProvider;
|
||||||
|
_mediaInfoProvider = mediaInfoProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiskScanProvider()
|
public DiskScanProvider()
|
||||||
|
@ -110,10 +112,9 @@ namespace NzbDrone.Core.Providers
|
||||||
}
|
}
|
||||||
|
|
||||||
long size = _diskProvider.GetSize(filePath);
|
long size = _diskProvider.GetSize(filePath);
|
||||||
|
var runTime = _mediaInfoProvider.GetRunTime(filePath);
|
||||||
//Todo: We shouldn't skip on file size alone, 64MB Family Guy episodes are skipped...
|
|
||||||
//Skip any file under 70MB - New samples don't even have sample in the name...
|
if(size < Constants.IgnoreFileSize && runTime < 480)
|
||||||
if (size < Constants.IgnoreFileSize)
|
|
||||||
{
|
{
|
||||||
Logger.Trace("[{0}] appears to be a sample. skipping.", filePath);
|
Logger.Trace("[{0}] appears to be a sample. skipping.", filePath);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using MediaInfoLib;
|
||||||
|
using NLog;
|
||||||
|
using NzbDrone.Common;
|
||||||
|
using NzbDrone.Core.Model;
|
||||||
|
|
||||||
|
namespace NzbDrone.Core.Providers
|
||||||
|
{
|
||||||
|
public class MediaInfoProvider
|
||||||
|
{
|
||||||
|
private readonly DiskProvider _diskProvider;
|
||||||
|
|
||||||
|
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
public MediaInfoProvider(DiskProvider diskProvider)
|
||||||
|
{
|
||||||
|
_diskProvider = diskProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaInfoProvider()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual MediaInfoModel GetMediaInfo(string filename)
|
||||||
|
{
|
||||||
|
if (!_diskProvider.FileExists(filename))
|
||||||
|
throw new FileNotFoundException("Media file does not exist: " + filename);
|
||||||
|
|
||||||
|
var mediaInfo = new MediaInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logger.Trace("Getting media info from {0}", filename);
|
||||||
|
|
||||||
|
mediaInfo.Option("ParseSpeed", "0.2");
|
||||||
|
int open = mediaInfo.Open(filename);
|
||||||
|
|
||||||
|
if (open != 0)
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int videoBitRate;
|
||||||
|
int audioBitRate;
|
||||||
|
int runTime;
|
||||||
|
int streamCount;
|
||||||
|
int audioChannels;
|
||||||
|
|
||||||
|
string subtitles = mediaInfo.Get(StreamKind.General, 0, "Text_Language_List");
|
||||||
|
string scanType = mediaInfo.Get(StreamKind.Video, 0, "ScanType");
|
||||||
|
Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Width"), out width);
|
||||||
|
Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "Height"), out height);
|
||||||
|
Int32.TryParse(mediaInfo.Get(StreamKind.Video, 0, "BitRate"), out videoBitRate);
|
||||||
|
|
||||||
|
string aBitRate = mediaInfo.Get(StreamKind.Audio, 0, "BitRate");
|
||||||
|
int ABindex = aBitRate.IndexOf(" /");
|
||||||
|
if (ABindex > 0)
|
||||||
|
aBitRate = aBitRate.Remove(ABindex);
|
||||||
|
|
||||||
|
Int32.TryParse(aBitRate, out audioBitRate);
|
||||||
|
Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out runTime);
|
||||||
|
Int32.TryParse(mediaInfo.Get(StreamKind.Audio, 0, "StreamCount"), out streamCount);
|
||||||
|
|
||||||
|
string audioChannelsStr = mediaInfo.Get(StreamKind.Audio, 0, "Channel(s)");
|
||||||
|
int ACindex = audioChannelsStr.IndexOf(" /");
|
||||||
|
if (ACindex > 0)
|
||||||
|
audioChannelsStr = audioChannelsStr.Remove(ACindex);
|
||||||
|
|
||||||
|
string audioLanguages = mediaInfo.Get(StreamKind.General, 0, "Audio_Language_List");
|
||||||
|
decimal videoFrameRate = Decimal.Parse(mediaInfo.Get(StreamKind.Video, 0, "FrameRate"));
|
||||||
|
string audioProfile = mediaInfo.Get(StreamKind.Audio, 0, "Format_Profile");
|
||||||
|
|
||||||
|
int APindex = audioProfile.IndexOf(" /");
|
||||||
|
if (APindex > 0)
|
||||||
|
audioProfile = audioProfile.Remove(APindex);
|
||||||
|
|
||||||
|
Int32.TryParse(audioChannelsStr, out audioChannels);
|
||||||
|
var mediaInfoModel = new MediaInfoModel
|
||||||
|
{
|
||||||
|
VideoCodec = mediaInfo.Get(StreamKind.Video, 0, "Codec/String"),
|
||||||
|
VideoBitrate = videoBitRate,
|
||||||
|
Height = height,
|
||||||
|
Width = width,
|
||||||
|
AudioFormat = mediaInfo.Get(StreamKind.Audio, 0, "Format"),
|
||||||
|
AudioBitrate = audioBitRate,
|
||||||
|
RunTime = (runTime / 1000), //InSeconds
|
||||||
|
AudioStreamCount = streamCount,
|
||||||
|
AudioChannels = audioChannels,
|
||||||
|
AudioProfile = audioProfile.Trim(),
|
||||||
|
VideoFps = videoFrameRate,
|
||||||
|
AudioLanguages = audioLanguages,
|
||||||
|
Subtitles = subtitles,
|
||||||
|
ScanType = scanType
|
||||||
|
};
|
||||||
|
|
||||||
|
mediaInfo.Close();
|
||||||
|
return mediaInfoModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.ErrorException("Unable to parse media info from file: " + filename, ex);
|
||||||
|
mediaInfo.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual Int32 GetRunTime(string filename)
|
||||||
|
{
|
||||||
|
var mediaInfo = new MediaInfo();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
logger.Trace("Getting media info from {0}", filename);
|
||||||
|
|
||||||
|
mediaInfo.Option("ParseSpeed", "0.2");
|
||||||
|
int open = mediaInfo.Open(filename);
|
||||||
|
|
||||||
|
if (open != 0)
|
||||||
|
{
|
||||||
|
int runTime;
|
||||||
|
Int32.TryParse(mediaInfo.Get(StreamKind.General, 0, "PlayTime"), out runTime);
|
||||||
|
|
||||||
|
mediaInfo.Close();
|
||||||
|
return runTime / 1000; //Convert to seconds
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.ErrorException("Unable to parse media info from file: " + filename, ex);
|
||||||
|
mediaInfo.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
<package id="DataTables.Mvc.Core" version="0.1.0.85" />
|
<package id="DataTables.Mvc.Core" version="0.1.0.85" />
|
||||||
<package id="DotNetZip" version="1.9.1.8" />
|
<package id="DotNetZip" version="1.9.1.8" />
|
||||||
<package id="Growl" version="0.6" />
|
<package id="Growl" version="0.6" />
|
||||||
|
<package id="MediaInfoNet" version="0.3" targetFramework="net40" />
|
||||||
<package id="Microsoft.SqlServer.Compact" version="4.0.8876.1" targetFramework="net40" />
|
<package id="Microsoft.SqlServer.Compact" version="4.0.8876.1" targetFramework="net40" />
|
||||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" />
|
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" />
|
||||||
<package id="MiniProfiler" version="2.0.2" />
|
<package id="MiniProfiler" version="2.0.2" />
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.8.0" newVersion="4.0.8.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||||
|
|
|
@ -72,7 +72,7 @@
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||||
<bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
|
<bindingRedirect oldVersion="0.0.0.0-4.0.8.0" newVersion="4.0.8.0" />
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</assemblyBinding>
|
</assemblyBinding>
|
||||||
</runtime>
|
</runtime>
|
||||||
|
|
Loading…
Reference in New Issue