Задача проверять на сайте asp.net mvc загружаемое пользователем видео на соответствие требованиям по длительности, кодеку, разрешению.
Испробовал множество способов, в итоге ни один не заработал на IIS:
Способ № 1
при помощи библиотеки Shell32
var shl = new Shell();
var fldr = shl.NameSpace(Path.GetDirectoryName(fileName));
var itm = fldr.ParseName(Path.GetFileName(fileName));
var res = new Dictionary<string, string>();
for (int i = 0; i < short.MaxValue; i++)
{
string header = fldr.GetDetailsOf(null, i);
if (!String.IsNullOrEmpty(header) && !res.ContainsKey(header))
{
string detailsOf = fldr.GetDetailsOf(itm, i);
if(!String.IsNullOrEmpty(detailsOf))
res.Add(header, detailsOf);
}
}
var lengthString = res.Where(i => i.Key.ToLower() == "length");
if (!lengthString.Any()) throw new ValidateVideoException("Не удалось определить длительность видео.");
var parts = lengthString.FirstOrDefault().Value.Split(new[] {':'});
var size = int.Parse(parts[0]) * 3600 + int.Parse(parts[1]) * 60 + int.Parse(parts[2]);
if (size > _minMax.Max) throw new ValidateVideoException("Доина файла {0} сек превышает ограничение {1} сек.", size, _minMax.Max);
if (size < _minMax.Min) throw new ValidateVideoException("Размер файла {0} сек ниже ограничения {1} сек.", size, _minMax.Min);
не работает из под IIS, так как не может создать Com объект, способ не нравится, так как свойства можно подделать.
Способ № 2
пробовал использовать бесплатные обертки ffmpeg, но в итоге ни одной работающей нормально так и не нашел.
Способ № 3
Используя DirectX, класс Microsoft.DirectX.AudioVideoPlayback.Video. библиотека 32-х битная, в студии проблема с модульными тестами, но главное - из под IIS падает при попытке создать объект Video с ошибкой "Error in the application." :-).
using (var video = new Video(fileName))
{
_resolution.Height.Check(video.Size.Width, "Ширина");
_resolution.Height.Check(video.Size.Height, "Высота");
}
Способ № 3.1
Используя обертку DirectShowLib -
try
{
var hr = graph.RenderFile(fileName, null);
DsError.ThrowExceptionForHR(hr);
var basicVideo = graph as IBasicVideo;
int videoHeight;
hr = basicVideo.get_VideoHeight(out videoHeight);
DsError.ThrowExceptionForHR(hr);
...проверяем...
}
finally
{
Marshal.ReleaseComObject(graph);
}
Модульные тесты работают, из-под IIS при получении "basicVideo.get_VideoHeight" в hr выдает код "No such interface supported"
Способ № 4
Через обертку Медиа плеера. Тесты работают нормально, из под IIS считывается только длительность файла, ширина и высота нулевые.