ffmpeg Consult a(1)

Iniciado por rigorvzla, 15 Abril 2018, 07:30 AM

0 Miembros y 1 Visitante están viendo este tema.

rigorvzla

Buenas noches amigos, estoy con una consulta y espero puedan ayudarme como en ocasiones anteriores, que mas que eso han sido respuestas con un gran valir educativo.

El asunto es el siguiente, usando el programa ffmpeg eh hecho muchas cosas y en este caso el poder capturar el sonido del microfono y la pantalla del escritorio en un video.
Este codigo es totalmente funcional, el unico detalle es que el video va a una velocidad muy rapida no acorde a la voz del microfono asi que no se reproduce como debe ser se corta antes de  tiempo, eh buscado mucho y no eh encontrado nada relacionado a eso, espero alguien pueda ayudarme.


    string input = "salida";
            string audio = Settings.Default.micDefault;
            string destFile = Path.Combine(Settings.Default.directorioVideo, Path.GetFileNameWithoutExtension(input) + ".mp4");
            string args = string.Format(@"-y -rtbufsize 200M -f gdigrab -thread_queue_size 1024 -probesize 10M -r 30 -draw_mouse 1 -i desktop -f dshow -channel_layout stereo -thread_queue_size 1024 -i audio=""{0}"" -c:v libx264 -r 30 -preset ultrafast -tune zerolatency -crf 25 -pix_fmt yuv420p -c:a aac -strict -2 -ac 2 -b:a 128k  ""{1}", audio, destFile);

            System.Threading.Tasks.Task.Run(() =>
            {
                System.Diagnostics.Process Conversor = new System.Diagnostics.Process();
                Conversor.StartInfo.FileName = "ffmpeg";
                Conversor.StartInfo.Arguments = args;
                Conversor.Start();
                Conversor.WaitForExit();
                Conversor.Close();
            });


Nota: Como un extra , si alguien sabe como bajar el peso del archivo seria fantastico ya que con solo 2 segundos ya son 2 Mb aproximadamente... (muy alto).

Nota 2 : La  Settings.Default.micDefault; es donde se guarda un microfono (nombre exactamente)

Settings.Default.directorioVideo; Ruta de salida odnde se guarda el archivo.

Muchas Gracias

Eleкtro

#1
Aunque estés trabajando en C#, la duda solo concierne al uso de la aplicación command-line FFMPEG y el fallo de sincronización que esta te genera...

Cita de: rigorvzla en 15 Abril 2018, 07:30 AMel unico detalle es que el video va a una velocidad muy rapida no acorde a la voz del microfono asi que no se reproduce como debe ser se corta antes de  tiempo

Utiliza el filtro de audio aresample para tratar de solucionarlo:

-af aresample=async=1000

Cita de: rigorvzla en 15 Abril 2018, 07:30 AM
si alguien sabe como bajar el peso del archivo seria fantastico ya que con solo 2 segundos ya son 2 Mb aproximadamente... (muy alto).

Bueno, resulta evidente que para conseguir una reducción del tamaño de archivo resultante debes reducir la calidad general de los parámetros de codificación de video / audio. Algunas cosas que te pueden ayudar: especificar un perfil de baja calidad en el parámetro -preset, aumentar el valor del parámetro -crf, especificar un códec de audio con bitrate variable (VBR). Pero es que en este caso creo que resulta innecesario modificar esos parámetros puesto que la calidad de grabación ya es lo bastante mediocre y lo suficientemente decente para equilibrar el tamaño resultante del archivo, como para preocuparse por reducirle aun más la calidad, me refiero, con los parámetros de codificación que especificaste, 1 minuto de grabación apenas genera un archivo de 9 megabytes, sin embargo tú dices que solo 2 segundos de grabación ya te genera un archivo de 2 mb, ¿cómo es posible eso?, jeje.

un saludo.








rigorvzla

 muchas gracias elektro, aunque lo coloque no sirvio,  entre el codigo quizas lo puse mal, lo coloque justo antes de terminar la parte del microfono y probe antes del nombre de salida del archivo y se mantuvo igual, si como dijiste por cada minuto es el valor de megas jeje no vi bien, por ultimo y esto es por lo que eh llegado aqui, (todo lo demas que hice con el archivo fue un extra no previsto pero muy bien todo lo que logre) es que no se cual es el valor stream o el codigo para ver el progreso de conversion de  los archivos, esto tambien eh buscado como loco sin exito, ya que al yo convertir xarchivo.mp4 a xaudio.mp3 no me da referencia de que % va y puedo asumir que se quedo pegado.

Nota: Disculpa por haber puesto en el otro foro mi consulta no sabia que se relacionaba a cosas generales. Procurare no se repita. Y Gracias nuevamente por tu asistencia.

Eleкtro

#3
Cita de: rigorvzla en 15 Abril 2018, 15:37 PMel codigo para ver el progreso de conversion de  los archivos, esto tambien eh buscado como loco sin exito

Para ello debes leer la salida estándar (o stdout por su acrónimo en Inglés) del proceso.

Si buscas encontrarás miles de ejemplos genéricos para C#. Te hago un resumen: en la referencia de tu objeto de tipo Process debes activar la propiedad ProcessStartInfo.RedirectStandardOutput para poder redirigir la salida estándar del proceso, y con ello debes elaborar tu propio algoritmo de análisis de datos (o data parsing) para calcular un porcentaje de progreso con los datos que puedas extraer/obtener de la salida del proceso (algo facil puesto que la salida de FFMPEG muestra un porcentaje). Opcionálmente también te convendría activar la propiedad ProcessStartInfo.RedirectStandardError para redirigir la salida de error y elaborar otro análisis de datos con el que capturar (y luego controlar) posibles errores que aparezcan en la salida de FFMPEG.

Teniendo esos dos conceptos claros, deberás elegir como quieres implementar el controlador de la salida stdout y stderr: de forma sincrónica, o asincrónica. Eso ya depende de tus necesidades y cuanto tiempo quieras invertir en hacerlo más sofisticado y estable.
Ten en cuenta que la frecuencia de actualización de la salida estándar de FFMPEG tiene intervalos cortos de tiempo, y por eso una implementación sincrónica (una llamada bloqueante) de la lectura del stdout podría resultar en un ligero aumento del tiempo total de ejecución de FFMPEG que ralentizaría en menor o mayor medida el tiempo necesario para finalizar la operación de conversión / lo que sea.
Para una implementación asincrónica primero debes activar la propiedad Process.EnableRaisingEvents y luego suscribirte a los eventos Process.OutputDataReceived y Process.ErrorDataReceived en función de si quieres controlar la salida stdout o stderr, o ambas (que sería lo eficiente). No debes tener en cuenta la salida de entrada (stdin) en este caso.

Por último, aquí te dejo un wrapper que desarrollé de FFMPEG hace tiempo, está escrito en VB.NET (para ver cosas hechas en C# ya tienes a Google) y no tiene la funcionalidad de capturar video, está enfocado a demuxear streams de video y audio, y convertir audio, pero quizás te pueda servir de algún modo aunque sea por analizar el código fuente y ver como extraigo los datos de la salida stdout y stdrr (de forma sincrónica) y como implementé la notificación de progreso de la operación de FFMPEG, la cual está orientada al uso de eventos...


nota: hace siglos que no uso ni actualizo ese código. en el caso de que no funcione probablemente pueda ser causa de que hayan modificado algún string en la salida de FFMPEG y haya que renovar el algoritmo de captura de datos del búfer stdout.

Saludos.








rigorvzla

muchisimas gracias como siempre, ya tengo de donde partir y si con este programa se pueden hacer gran cantidad de cosas, yo en lo personal tengo un "catalogo de botonones" donde extraigo el mp3 de cualquier archivo multimedia, convierto cualquier video a mp4 , creo gif de un tiempo a -hasta b, capturo la pantallaescritorio sin sonido, y aunque tengo el de captura de pantalla con sonido (no esta como lo quiero)... y todo esto lo consegui por buscar solamente el progreso en "%" jeje... en fin muchas gracias por la asistencia . Feliz Domingo