Comments 10
А ваша библиотека (ну или ffmpeg) научился делать видео заданного разрешение из картинок которые абсолютно разных размеров в режиме cover ?
Тоесть если супер узкая , то растягивается в ширину сохраняя пропорции и режится верш и низ. Если картинка слишком большая то скейлится вниз до лучших сторон чтобы отрезать как можно меньше.
Или это всё ручные скрипты с десятками if ?
Зачем велосипедить? Сделайте желаемое на html css js и а фреймы уже загоните через ffmpeg. Вообще это умеет делать почти любая кропалка изображений.
На данный момент при конвертации набора изображений они подвергнуться изменению исходного размера. В текущей версии указан лишь стартовый функционал с указанием базовых конфигураций. Различные форматы входных и выходных файлов могут потребовать указания разного набора конфигураций. Указанные функции я тестировал с некоторыми наиболее востребованными форматами mp4 avi png jpg bmp wav и mpeg. другие форматы могут потребовать дополнительных настроек. В будущем я собираюсь развить библиотеку до возможно подкапотной установки настроек под любые форматы.
Можно допилить, сделав необязательным соблюдение порядка вызова методов у `VideoProcessingSettings`. Всяко автору библиотеки виднее, какой порядок более правильный, чем пользователю.
Да, изначально я так и начинал, но позже выяснилось что некоторые аргументы должны быть обязательно указаны до входных аргументов, некоторые после, некоторые и могут указываться и до и после. А в случае нескольких входных аргументов аргументы должны быть указаны после или пере ними по отдельности. Я принял решение пока оставить это для на рассмотрение пользователя, но в будущем постараюсь сделать автонастройку позиций аргументов и максимально упростить примемение для пользователя, чтобы он мог легко пользоваться вообще не зная что такое ffmpeg и с чем его есть.
А чем не устроил тот же FFmpegCore? Эта оболочка вроде умеет работать с пайпами и активно их использует внутри себя.
Все сказанное ниже вкусовщина, но, как я считаю, при работе с изображениями и видеопотоками нужно более бережно обращаться с ресурсами во избежание проблем.
MediaFileProcess - содержит Disposible свойства, но не реализует интерфейс
MediaFileProcess.ctor
Создается Disposible объект Process, но уничтожение происходит внутри одного из методов а не в методе Dispose класса
InputStreams - не определено время жизни Stram'ов. Соответственно, если это файловый stram, невозможно определить момент освобождения файла. Если предполагается, что передается пользование а не владение потоками, то на вызывающей стороне нигде не обнаружил этому подтверждение.
MediaFileProcess.ProcessOnExited - целесообразность метода вызывает вопрос. возможно, планировалось в нем сделать очистку зарегистрированных обработчиков событий, но сейчас необходимость в нем неочевидна.
MediaFileProcess.ExecuteAsync
метод можно вызвать только один раз. при повторном вызове будут исключительные ситуации
спорное решение с обработкой всего ввода-вывода в синхронном потоке.
MediaFileProcess.Run
cancellationToken.Register может привести к утечке памяти, так как через cancellationToken будут заблокированы от финализации Process, Settings, InputStreams и тд.
Task.Run(WriteStandartInput, cancellationToken) - cancellationToken будет использоваться только как токен отмены создания таска, а не исполнения таска.
при аварийном закрытии приложения дочерние процессы могут остаться живыми. Для Windows рекомендую посмотреть в сторону kernel32 CreateJobObject.
MediaFileProcess.MultiInputWindowsOS - созданным pipe'ам не плохо бы сделать Dispose.
MediaFileProcess.MultiInpuLinuxOS
вероятность словить исключение при удалении файла стремится к 100%
не понятно как созданные файлы должны обрабатываться, ведь сразу после создания они удаляются.
MediaFileProcess.ReadStandartOutput - реализован метод Stream.CopyTo
по опыту, возможно возникновение OOM из-за подходов работы с объектами, попадающими в LOH. Вместо использования byte[] размером более 80 кб я бы посоветовал посмотреть в сторону System.Buffers.
using Nerdbank.Streams;
using System.Buffers;
var seq = new Sequence<byte>();
while (true)
{
var buffer = new byte[64 * 1024];
var lastRead = Process.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);
if (lastRead == 0)
break;
seq.Append(buffer[..lastRead]);
}
return ((ReadOnlySequence<byte>)seq).AsStream();
Работу с MultiStream круто получилось!
Думаю удобно будет настройку через DI сделать. Но библиотека ТОП!!!
C# и обработка медиафайлов средствами FFmpeg, Pandoc и ImageMagick