You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Readarr/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs

149 lines
5.9 KiB

using System;
using System.IO;
using MediaInfoLib;
using NLog;
using NzbDrone.Common;
using NzbDrone.Core.Model;
namespace NzbDrone.Core.MediaFiles.MediaInfo
{
public interface IVideoFileInfoReader
{
MediaInfoModel GetMediaInfo(string filename);
TimeSpan GetRunTime(string filename);
}
public class VideoFileInfoReader : IVideoFileInfoReader
{
private readonly IDiskProvider _diskProvider;
private readonly Logger _logger;
public VideoFileInfoReader(IDiskProvider diskProvider, Logger logger)
{
_diskProvider = diskProvider;
_logger = logger;
}
public MediaInfoModel GetMediaInfo(string filename)
{
if (!_diskProvider.FileExists(filename))
throw new FileNotFoundException("Media file does not exist: " + filename);
var mediaInfo = new MediaInfoLib.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 TimeSpan GetRunTime(string filename)
{
MediaInfoLib.MediaInfo mediaInfo = null;
try
{
mediaInfo = new MediaInfoLib.MediaInfo();
_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 TimeSpan.FromMilliseconds(runTime);
}
}
catch (Exception ex)
{
_logger.ErrorException("Unable to parse media info from file: " + filename, ex);
}
finally
{
if (mediaInfo != null)
{
mediaInfo.Close();
}
}
return new TimeSpan();
}
}
}