Как работать с потоком который содержит множество файлов?
Цитата: Overd от 09.01.2023, 19:17Здравствуйте господа кодеры и кодерессы).
Проблема следующая. Мне надо конвертировать видео в набор картинок через процесс ffmpeg. Раньше я успешно это делал при помощи следующего кода:
[spoiler title=""]public void VideoToImages1() { var inputFile = @"D:\testVideo.avi"; var outputFilesPattern = @"D:\image%03d.jpg"; using (var process = new Process { StartInfo = new ProcessStartInfo { UseShellExecute = false, CreateNoWindow = true, Arguments = $"-y -i {inputFile} {outputFilesPattern}", FileName = "ffmpeg.exe" }, EnableRaisingEvents = true }) { process.Start(); process.WaitForExit(); } }[/spoiler]
Теперь же мне необходимо передавать видео через входной Stream и получать данные из выходного Stream. Для этого у меня следующий код. Он полностью рабочий так как я использовал его для конвертации видео и успешно передавал входные данные через Stream и получал выходные данные в через Stream и создавал корректный файл.
Проблема здесь в том что вместо того чтобы создать файлы в директории по указанному паттерну он возвращает эти файлы в потоке. В итоге я не знаю записать все файлы из Stream и как этот выходной обрабатывать так как он содержит множество файлов. В данный момент у меня создается лишь 1 картинка.
При указании выходного паттерна для файлов он ведь создает множество файлов на диске, а при указании выходного канала он ведь все выходные данные отправляет в выходной стрим.
[spoiler title=""]public void VideoToImages2() { var inputFile = @"D:\testVideo.avi"; var outputFile = @"D:\resultImages.png"; var process = new Process { StartInfo = new ProcessStartInfo { RedirectStandardInput = true, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true, Arguments = "-y -i - -f image2 -", FileName = _ffmpeg }, EnableRaisingEvents = true }; process.Start(); //Write input data to input stream var inputTask = Task.Run(() => { using (var input = new FileStream(inputFile, FileMode.Open)) { input.CopyTo(process.StandardInput.BaseStream); process.StandardInput.Close(); } }); //Read multiple files from output stream var outputTask = Task.Run(() => { //Problem here using (var output = new FileStream(outputFile, FileMode.Create)) process.StandardOutput.BaseStream.CopyTo(output); }); Task.WaitAll(inputTask, outputTask); process.WaitForExit(); }[/spoiler]
Вот мне как раз таки нужно как то эти данные из этого стрима получить. Когда выходным файлом является один файл то его легко считать, куда-то записать или обработать каким то образом. А в этом случае как быть с множеством файлов в выходном потоке? Я пытался искать по документации, нигде информацию не нашел. Дело как раз таки в том как работать с этим выходным потоком.
Помогите пожалуйста.
[MNotice]Больше не оформляйте так код, пожалуйста. Посмотрите видео: Как оформлять свои темы и комментарии | Как делать крутые скриншоты [/MNotice]
Здравствуйте господа кодеры и кодерессы).
Проблема следующая. Мне надо конвертировать видео в набор картинок через процесс ffmpeg. Раньше я успешно это делал при помощи следующего кода:
public void VideoToImages1()
{
var inputFile = @"D:\testVideo.avi";
var outputFilesPattern = @"D:\image%03d.jpg" style="color: #25d39d !important";
using (var process = new Process
{
StartInfo = new ProcessStartInfo
{
UseShellExecute = false,
CreateNoWindow = true,
Arguments = $"-y -i {inputFile} {outputFilesPattern}",
FileName = "ffmpeg.exe"
},
EnableRaisingEvents = true
})
{
process.Start();
process.WaitForExit();
}
}
Теперь же мне необходимо передавать видео через входной Stream и получать данные из выходного Stream. Для этого у меня следующий код. Он полностью рабочий так как я использовал его для конвертации видео и успешно передавал входные данные через Stream и получал выходные данные в через Stream и создавал корректный файл.
Проблема здесь в том что вместо того чтобы создать файлы в директории по указанному паттерну он возвращает эти файлы в потоке. В итоге я не знаю записать все файлы из Stream и как этот выходной обрабатывать так как он содержит множество файлов. В данный момент у меня создается лишь 1 картинка.
При указании выходного паттерна для файлов он ведь создает множество файлов на диске, а при указании выходного канала он ведь все выходные данные отправляет в выходной стрим.
public void VideoToImages2()
{
var inputFile = @"D:\testVideo.avi";
var outputFile = @"D:\resultImages.png" style="color: #25d39d !important";
var process = new Process
{
StartInfo = new ProcessStartInfo
{
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
Arguments = "-y -i - -f image2 -",
FileName = _ffmpeg
},
EnableRaisingEvents = true
};
process.Start();
//Write input data to input stream
var inputTask = Task.Run(() =>
{
using (var input = new FileStream(inputFile, FileMode.Open))
{
input.CopyTo(process.StandardInput.BaseStream);
process.StandardInput.Close();
}
});
//Read multiple files from output stream
var outputTask = Task.Run(() =>
{
//Problem here
using (var output = new FileStream(outputFile, FileMode.Create))
process.StandardOutput.BaseStream.CopyTo(output);
});
Task.WaitAll(inputTask, outputTask);
process.WaitForExit();
}
Вот мне как раз таки нужно как то эти данные из этого стрима получить. Когда выходным файлом является один файл то его легко считать, куда-то записать или обработать каким то образом. А в этом случае как быть с множеством файлов в выходном потоке? Я пытался искать по документации, нигде информацию не нашел. Дело как раз таки в том как работать с этим выходным потоком.
Помогите пожалуйста.
Комментарий модератора:
Больше не оформляйте так код, пожалуйста. Посмотрите видео: Как оформлять свои темы и комментарии | Как делать крутые скриншоты
Цитата: Viсtor от 12.01.2023, 07:20Привет. Посмотри. Может на мысль наведёт.
[spoiler title="Код"]internal class Program { private const string Pathffmpeg = @"C:\work\Studio\Tests\ffmpeg\bin\ffmpeg.exe"; private const string PathFile = @"C:\Users\Vikto\OneDrive\Документы\Test.mp4"; private const string PathOutput = @"C:\Users\Vikto\Desktop\Моя папка на рабочем столе\"; private static async Task Main() { await Start(Pathffmpeg, File.ReadAllBytes(PathFile)); File.WriteAllBytes(@"C:\Users\Vikto\Desktop\8888\a1.avi", Start2(Pathffmpeg, File.ReadAllBytes(PathFile)).ToArray()); // MemoryStream mstream = Start3(Pathffmpeg, File.ReadAllBytes(PathFile)); } private static async Task Start(string pathffmpeg, byte[] write) { string args = @$"-i pipe:, ""{PathOutput}\%d.png"""; using Process proc = Process.Start(new ProcessStartInfo() { FileName = pathffmpeg, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = false, }) ?? throw new NullReferenceException(); await proc.StandardInput.BaseStream.WriteAsync(write); proc.StandardInput.Dispose(); await proc.WaitForExitAsync(); } private static MemoryStream Start2(string path, byte[] write) { string args = @$"-i pipe:, -f avi pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; } private static MemoryStream Start3(string path, byte[] write) { string args = @$"-i pipe:, -c:v png -f image2pipe pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; }[/spoiler]
Первый вариант из стрима в последовательность png файлов в директории.
Второй вариант как у тебя из стрима в стрим, но только для одиночных файлов.
Если нужно именно и из стрима в стрим, последовательность png без выгрузки на диск. К сожалению я не разобрался до конца. Стрим можно получить, третий вариант, но вопрос его дешифровки остаётся открытым. Насколько я понимаю человек вроде как-то смог этого добиться. Удачи. 🌈P.S. Твой код там исключение выводит. Достаточно посмотреть в вывод консоли ffmpeg. Можно даже тупо MemoryStream в bitmap запихнуть, и получить как раз один файл png, размера всех изображений(бесполезный).
Привет. Посмотри. Может на мысль наведёт.
internal class Program
{
private const string Pathffmpeg = @"C:\work\Studio\Tests\ffmpeg\bin\ffmpeg.exe";
private const string PathFile = @"C:\Users\Vikto\OneDrive\Документы\Test.mp4";
private const string PathOutput = @"C:\Users\Vikto\Desktop\Моя папка на рабочем столе\";
private static async Task Main()
{
await Start(Pathffmpeg, File.ReadAllBytes(PathFile));
File.WriteAllBytes(@"C:\Users\Vikto\Desktop\8888\a1.avi", Start2(Pathffmpeg, File.ReadAllBytes(PathFile)).ToArray());
// MemoryStream mstream = Start3(Pathffmpeg, File.ReadAllBytes(PathFile));
}
private static async Task Start(string pathffmpeg, byte[] write)
{
string args = @$"-i pipe:, ""{PathOutput}\%d.png" style="color: #25d39d !important""";
using Process proc = Process.Start(new ProcessStartInfo()
{
FileName = pathffmpeg,
Arguments = args,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = false,
}) ?? throw new NullReferenceException();
await proc.StandardInput.BaseStream.WriteAsync(write);
proc.StandardInput.Dispose();
await proc.WaitForExitAsync();
}
private static MemoryStream Start2(string path, byte[] write)
{
string args = @$"-i pipe:, -f avi pipe:";
using Process proc = Process.Start(new ProcessStartInfo()
{
FileName = path,
Arguments = args,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = false
}) ?? throw new NullReferenceException();
MemoryStream memoryStream = new MemoryStream();
Parallel.Invoke(async () =>
{
await proc.StandardInput.BaseStream.WriteAsync(write);
await proc.StandardInput.BaseStream.DisposeAsync();
}, () =>
{
proc.StandardOutput.BaseStream.CopyTo(memoryStream);
proc.Dispose();
});
return memoryStream;
}
private static MemoryStream Start3(string path, byte[] write)
{
string args = @$"-i pipe:, -c:v png -f image2pipe pipe:";
using Process proc = Process.Start(new ProcessStartInfo()
{
FileName = path,
Arguments = args,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = false
}) ?? throw new NullReferenceException();
MemoryStream memoryStream = new MemoryStream();
Parallel.Invoke(async () =>
{
await proc.StandardInput.BaseStream.WriteAsync(write);
await proc.StandardInput.BaseStream.DisposeAsync();
}, () =>
{
proc.StandardOutput.BaseStream.CopyTo(memoryStream);
proc.Dispose();
});
return memoryStream;
}
Первый вариант из стрима в последовательность png файлов в директории.
Второй вариант как у тебя из стрима в стрим, но только для одиночных файлов.
Если нужно именно и из стрима в стрим, последовательность png без выгрузки на диск. К сожалению я не разобрался до конца. Стрим можно получить, третий вариант, но вопрос его дешифровки остаётся открытым. Насколько я понимаю человек вроде как-то смог этого добиться. Удачи. 🌈
P.S. Твой код там исключение выводит. Достаточно посмотреть в вывод консоли ffmpeg. Можно даже тупо MemoryStream в bitmap запихнуть, и получить как раз один файл png, размера всех изображений(бесполезный).
Цитата: Overd от 13.01.2023, 22:25Цитата: Viсtor от 12.01.2023, 07:20Привет. Посмотри. Может на мысль наведёт.
[spoiler title="Код"]internal class Program{private const string Pathffmpeg = @"C:\work\Studio\Tests\ffmpeg\bin\ffmpeg.exe";private const string PathFile = @"C:\Users\Vikto\OneDrive\Документы\Test.mp4";private const string PathOutput = @"C:\Users\Vikto\Desktop\Моя папка на рабочем столе\";private static async Task Main(){await Start(Pathffmpeg, File.ReadAllBytes(PathFile));File.WriteAllBytes(@"C:\Users\Vikto\Desktop\8888\a1.avi", Start2(Pathffmpeg, File.ReadAllBytes(PathFile)).ToArray());// MemoryStream mstream = Start3(Pathffmpeg, File.ReadAllBytes(PathFile));}private static async Task Start(string pathffmpeg, byte[] write){string args = @$"-i pipe:, ""{PathOutput}\%d.png""";using Process proc = Process.Start(new ProcessStartInfo(){FileName = pathffmpeg,Arguments = args,UseShellExecute = false,RedirectStandardInput = true,RedirectStandardOutput = false,}) ?? throw new NullReferenceException();await proc.StandardInput.BaseStream.WriteAsync(write);proc.StandardInput.Dispose();await proc.WaitForExitAsync();}private static MemoryStream Start2(string path, byte[] write){string args = @$"-i pipe:, -f avi pipe:";using Process proc = Process.Start(new ProcessStartInfo(){FileName = path,Arguments = args,UseShellExecute = false,RedirectStandardInput = true,RedirectStandardOutput = true,RedirectStandardError = false}) ?? throw new NullReferenceException();MemoryStream memoryStream = new MemoryStream();Parallel.Invoke(async () =>{await proc.StandardInput.BaseStream.WriteAsync(write);await proc.StandardInput.BaseStream.DisposeAsync();}, () =>{proc.StandardOutput.BaseStream.CopyTo(memoryStream);proc.Dispose();});return memoryStream;}private static MemoryStream Start3(string path, byte[] write){string args = @$"-i pipe:, -c:v png -f image2pipe pipe:";using Process proc = Process.Start(new ProcessStartInfo(){FileName = path,Arguments = args,UseShellExecute = false,RedirectStandardInput = true,RedirectStandardOutput = true,RedirectStandardError = false}) ?? throw new NullReferenceException();MemoryStream memoryStream = new MemoryStream();Parallel.Invoke(async () =>{await proc.StandardInput.BaseStream.WriteAsync(write);await proc.StandardInput.BaseStream.DisposeAsync();}, () =>{proc.StandardOutput.BaseStream.CopyTo(memoryStream);proc.Dispose();});return memoryStream;}internal class Program { private const string Pathffmpeg = @"C:\work\Studio\Tests\ffmpeg\bin\ffmpeg.exe"; private const string PathFile = @"C:\Users\Vikto\OneDrive\Документы\Test.mp4"; private const string PathOutput = @"C:\Users\Vikto\Desktop\Моя папка на рабочем столе\"; private static async Task Main() { await Start(Pathffmpeg, File.ReadAllBytes(PathFile)); File.WriteAllBytes(@"C:\Users\Vikto\Desktop\8888\a1.avi", Start2(Pathffmpeg, File.ReadAllBytes(PathFile)).ToArray()); // MemoryStream mstream = Start3(Pathffmpeg, File.ReadAllBytes(PathFile)); } private static async Task Start(string pathffmpeg, byte[] write) { string args = @$"-i pipe:, ""{PathOutput}\%d.png"""; using Process proc = Process.Start(new ProcessStartInfo() { FileName = pathffmpeg, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = false, }) ?? throw new NullReferenceException(); await proc.StandardInput.BaseStream.WriteAsync(write); proc.StandardInput.Dispose(); await proc.WaitForExitAsync(); } private static MemoryStream Start2(string path, byte[] write) { string args = @$"-i pipe:, -f avi pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; } private static MemoryStream Start3(string path, byte[] write) { string args = @$"-i pipe:, -c:v png -f image2pipe pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; }internal class Program { private const string Pathffmpeg = @"C:\work\Studio\Tests\ffmpeg\bin\ffmpeg.exe"; private const string PathFile = @"C:\Users\Vikto\OneDrive\Документы\Test.mp4"; private const string PathOutput = @"C:\Users\Vikto\Desktop\Моя папка на рабочем столе\"; private static async Task Main() { await Start(Pathffmpeg, File.ReadAllBytes(PathFile)); File.WriteAllBytes(@"C:\Users\Vikto\Desktop\8888\a1.avi", Start2(Pathffmpeg, File.ReadAllBytes(PathFile)).ToArray()); // MemoryStream mstream = Start3(Pathffmpeg, File.ReadAllBytes(PathFile)); } private static async Task Start(string pathffmpeg, byte[] write) { string args = @$"-i pipe:, ""{PathOutput}\%d.png"""; using Process proc = Process.Start(new ProcessStartInfo() { FileName = pathffmpeg, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = false, }) ?? throw new NullReferenceException(); await proc.StandardInput.BaseStream.WriteAsync(write); proc.StandardInput.Dispose(); await proc.WaitForExitAsync(); } private static MemoryStream Start2(string path, byte[] write) { string args = @$"-i pipe:, -f avi pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; } private static MemoryStream Start3(string path, byte[] write) { string args = @$"-i pipe:, -c:v png -f image2pipe pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; }[/spoiler]
Первый вариант из стрима в последовательность png файлов в директории.
Второй вариант как у тебя из стрима в стрим, но только для одиночных файлов.
Если нужно именно и из стрима в стрим, последовательность png без выгрузки на диск. К сожалению я не разобрался до конца. Стрим можно получить, третий вариант, но вопрос его дешифровки остаётся открытым. Насколько я понимаю человек вроде как-то смог этого добиться. Удачи.P.S. Твой код там исключение выводит. Достаточно посмотреть в вывод консоли ffmpeg. Можно даже тупо MemoryStream в bitmap запихнуть, и получить как раз один файл png, размера всех изображений(бесполезный).
Спасибо за наводки, кажись я вышел на нужную тропу. Как решу задачу отпишусь.
Цитата: Viсtor от 12.01.2023, 07:20Привет. Посмотри. Может на мысль наведёт.
Кодinternal class Program{private const string Pathffmpeg = @"C:\work\Studio\Tests\ffmpeg\bin\ffmpeg.exe";private const string PathFile = @"C:\Users\Vikto\OneDrive\Документы\Test.mp4";private const string PathOutput = @"C:\Users\Vikto\Desktop\Моя папка на рабочем столе\";private static async Task Main(){await Start(Pathffmpeg, File.ReadAllBytes(PathFile));File.WriteAllBytes(@"C:\Users\Vikto\Desktop\8888\a1.avi", Start2(Pathffmpeg, File.ReadAllBytes(PathFile)).ToArray());// MemoryStream mstream = Start3(Pathffmpeg, File.ReadAllBytes(PathFile));}private static async Task Start(string pathffmpeg, byte[] write){string args = @$"-i pipe:, ""{PathOutput}\%d.png""";using Process proc = Process.Start(new ProcessStartInfo(){FileName = pathffmpeg,Arguments = args,UseShellExecute = false,RedirectStandardInput = true,RedirectStandardOutput = false,}) ?? throw new NullReferenceException();await proc.StandardInput.BaseStream.WriteAsync(write);proc.StandardInput.Dispose();await proc.WaitForExitAsync();}private static MemoryStream Start2(string path, byte[] write){string args = @$"-i pipe:, -f avi pipe:";using Process proc = Process.Start(new ProcessStartInfo(){FileName = path,Arguments = args,UseShellExecute = false,RedirectStandardInput = true,RedirectStandardOutput = true,RedirectStandardError = false}) ?? throw new NullReferenceException();MemoryStream memoryStream = new MemoryStream();Parallel.Invoke(async () =>{await proc.StandardInput.BaseStream.WriteAsync(write);await proc.StandardInput.BaseStream.DisposeAsync();}, () =>{proc.StandardOutput.BaseStream.CopyTo(memoryStream);proc.Dispose();});return memoryStream;}private static MemoryStream Start3(string path, byte[] write){string args = @$"-i pipe:, -c:v png -f image2pipe pipe:";using Process proc = Process.Start(new ProcessStartInfo(){FileName = path,Arguments = args,UseShellExecute = false,RedirectStandardInput = true,RedirectStandardOutput = true,RedirectStandardError = false}) ?? throw new NullReferenceException();MemoryStream memoryStream = new MemoryStream();Parallel.Invoke(async () =>{await proc.StandardInput.BaseStream.WriteAsync(write);await proc.StandardInput.BaseStream.DisposeAsync();}, () =>{proc.StandardOutput.BaseStream.CopyTo(memoryStream);proc.Dispose();});return memoryStream;}internal class Program { private const string Pathffmpeg = @"C:\work\Studio\Tests\ffmpeg\bin\ffmpeg.exe"; private const string PathFile = @"C:\Users\Vikto\OneDrive\Документы\Test.mp4"; private const string PathOutput = @"C:\Users\Vikto\Desktop\Моя папка на рабочем столе\"; private static async Task Main() { await Start(Pathffmpeg, File.ReadAllBytes(PathFile)); File.WriteAllBytes(@"C:\Users\Vikto\Desktop\8888\a1.avi", Start2(Pathffmpeg, File.ReadAllBytes(PathFile)).ToArray()); // MemoryStream mstream = Start3(Pathffmpeg, File.ReadAllBytes(PathFile)); } private static async Task Start(string pathffmpeg, byte[] write) { string args = @$"-i pipe:, ""{PathOutput}\%d.png" style="color: #25d39d !important"""; using Process proc = Process.Start(new ProcessStartInfo() { FileName = pathffmpeg, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = false, }) ?? throw new NullReferenceException(); await proc.StandardInput.BaseStream.WriteAsync(write); proc.StandardInput.Dispose(); await proc.WaitForExitAsync(); } private static MemoryStream Start2(string path, byte[] write) { string args = @$"-i pipe:, -f avi pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; } private static MemoryStream Start3(string path, byte[] write) { string args = @$"-i pipe:, -c:v png -f image2pipe pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; }internal class Program { private const string Pathffmpeg = @"C:\work\Studio\Tests\ffmpeg\bin\ffmpeg.exe"; private const string PathFile = @"C:\Users\Vikto\OneDrive\Документы\Test.mp4"; private const string PathOutput = @"C:\Users\Vikto\Desktop\Моя папка на рабочем столе\"; private static async Task Main() { await Start(Pathffmpeg, File.ReadAllBytes(PathFile)); File.WriteAllBytes(@"C:\Users\Vikto\Desktop\8888\a1.avi", Start2(Pathffmpeg, File.ReadAllBytes(PathFile)).ToArray()); // MemoryStream mstream = Start3(Pathffmpeg, File.ReadAllBytes(PathFile)); } private static async Task Start(string pathffmpeg, byte[] write) { string args = @$"-i pipe:, ""{PathOutput}\%d.png" style="color: #25d39d !important"""; using Process proc = Process.Start(new ProcessStartInfo() { FileName = pathffmpeg, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = false, }) ?? throw new NullReferenceException(); await proc.StandardInput.BaseStream.WriteAsync(write); proc.StandardInput.Dispose(); await proc.WaitForExitAsync(); } private static MemoryStream Start2(string path, byte[] write) { string args = @$"-i pipe:, -f avi pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; } private static MemoryStream Start3(string path, byte[] write) { string args = @$"-i pipe:, -c:v png -f image2pipe pipe:"; using Process proc = Process.Start(new ProcessStartInfo() { FileName = path, Arguments = args, UseShellExecute = false, RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = false }) ?? throw new NullReferenceException(); MemoryStream memoryStream = new MemoryStream(); Parallel.Invoke(async () => { await proc.StandardInput.BaseStream.WriteAsync(write); await proc.StandardInput.BaseStream.DisposeAsync(); }, () => { proc.StandardOutput.BaseStream.CopyTo(memoryStream); proc.Dispose(); }); return memoryStream; }
Первый вариант из стрима в последовательность png файлов в директории.
Второй вариант как у тебя из стрима в стрим, но только для одиночных файлов.
Если нужно именно и из стрима в стрим, последовательность png без выгрузки на диск. К сожалению я не разобрался до конца. Стрим можно получить, третий вариант, но вопрос его дешифровки остаётся открытым. Насколько я понимаю человек вроде как-то смог этого добиться. Удачи.![]()
P.S. Твой код там исключение выводит. Достаточно посмотреть в вывод консоли ffmpeg. Можно даже тупо MemoryStream в bitmap запихнуть, и получить как раз один файл png, размера всех изображений(бесполезный).
Спасибо за наводки, кажись я вышел на нужную тропу. Как решу задачу отпишусь.