c# - solucion - solución sin comandos en modo recovery/ reset factory celulares chinos
¿C#y FFmpeg preferiblemente sin comandos de shell? (5)
Me gustaría poder usar FFmpeg para convertir un archivo de video desde mi programa C #. Sé que solo puedo llamar a un comando de shell, pero ¿hay alguna manera mejor?
El problema con invocar un comando a través del shell, es que no estoy seguro de que puedas hacer cosas como una barra de progreso, etc. ¿O podrías hacerlo?
Si no hay una forma, ¿puede alguien sugerir la mejor manera de diseñar un marco para ejecutar comandos de shell? Pasar una cuerda larga y grande es un cajero automático muy engorroso.
¿Qué tal si escribes un envoltorio de C ++ / CLI alrededor de la interfaz nativa de ffmpeg y luego llamas a tu interfaz de envoltorio desde tu aplicación?
Acabo de encontrar fflib en sourceforge. Parece bastante prometedor, no lo he usado sin embargo.
Hay una biblioteca de wrapper sobre FFmpeg para .NET.
He encontrado esta publicación hace unas semanas cuando estaba buscando una respuesta para mi problema. Intenté iniciar el proceso ffmpeg y pasarle argumentos, pero me toma mucho tiempo hacerlo todo. En este punto, uso Xabe.FFmpeg ya que lo hace de forma Xabe.FFmpeg y no tengo que preocuparme por los ejecutables ffmpeg, ya que tienen la función de descargar la última versión.
bool conversionResult = await new Conversion().SetInput(Resources.MkvWithAudio)
.AddParameter(String.Format("-f image2pipe -i pipe:.bmp -maxrate {0}k -r {1} -an -y {2}",bitrate, fps, outputfilename))
.Start();
Hay documentación disponible here que muestra cómo obtener el porcentaje actual de conversión.
Puede implementar fácilmente una barra de progreso si ejecuta ffmpeg. La salida de ffmpeg mientras se ejecuta es algo como:
frame= 3366 fps=465 q=31.0 Lsize= 6474kB time=140.35 bitrate= 377.9kbits/s
Y se actualiza ~ dos veces por segundo. Puede analizar esa línea y obtener los datos que necesita para mostrar el progreso. Cuando se ejecuta en la línea de comandos, solo se ve una línea que se actualiza todo el tiempo, pero lo que hace ffmpeg es escribir la línea seguida de / r . Por eso no ves múltiples líneas. Sin embargo, cuando usa StreamReader.ReadLine () en la salida de error del programa, obtiene una línea por cada actualización.
A continuación se muestra un código de muestra para leer la salida. Tendría que ignorar cualquier línea que no comience con ''marco'', tal vez use BeginErrorReadLine() + ErrorDataReceived si desea que las líneas de lectura sean asíncronas, etc., pero tiene la idea (la he probado):
using System;
using System.Diagnostics;
using System.IO;
class Test {
static void Main (string [] args)
{
Process proc = new Process ();
proc.StartInfo.FileName = "ffmpeg";
proc.StartInfo.Arguments = "-i " + args [0] + " " + args [1];
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.UseShellExecute = false;
if (!proc.Start ()) {
Console.WriteLine ("Error starting");
return;
}
StreamReader reader = proc.StandardError;
string line;
while ((line = reader.ReadLine ()) != null) {
Console.WriteLine (line);
}
proc.Close ();
}
}