Foros del Web » Programando para Internet » PHP »

[Aporte] Convertir videos con ffmpeg en background

Estas en el tema de [Aporte] Convertir videos con ffmpeg en background en el foro de PHP en Foros del Web. Despues de un tiempo de batallar con este tema, por fin logre solucionarlo y quiero compartirlo por si alguien lo necesita. Configuracion del servidor (en ...
  #1 (permalink)  
Antiguo 04/09/2009, 07:36
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 13 años, 5 meses
Puntos: 2236
[Aporte] Convertir videos con ffmpeg en background

Despues de un tiempo de batallar con este tema, por fin logre solucionarlo y quiero compartirlo por si alguien lo necesita.

Configuracion del servidor (en mi caso: ubuntu):

Antes que nada, ya debe estar instalado en el servidor ffmpeg con sus respectivos codecs, FlvTool2 para insertar metaData en el video (FLV injection) y la libreria ffmpeg_movie para obtener algunos datos necesarios y/o generar imagen de vista previa.

Uno de los problemas que tuve es que al ejecutar el script desde el navegador se realizaba la conversion sin problemas, pero, al ejecutarlo en segundo plano (background) fallaba.

La causa de esto es por la configuracion de PHP que no tenia acceso a ffmpeg_movie y no lo notaba porque en /etc/php5/apache2/php.ini aparece extension=ffmpeg.so, entonces busque todos los php.ini (find / -name php.ini) y encontre /etc/php/cli/php.ini, donde no estaba la linea, simplemente la agregue y funciono correctamente.

Subir archivo y ejecutar script de conversion:

Despues de subir el archivo y validar la extension (Las que yo permito: mov, wmv, avi, mpg, mpeg y flv) iniciamos la conversion en segundo plano:

Nota: No coloco todas las validaciones necesarias, porque es demasiado codigo y vamos al grano con la conversion.

Código php:
Ver original
  1. <?php
  2. // Subimos el archivo como lo hacemos con cualquier otro:
  3. move_uploaded_file($_FILES['video']['tmp_name'], "/ruta/convertir/$video");
  4. // Para mas informacion de como subir archivos, en la seccion de aportes hay varios ejemplos
  5.  
  6. // En este punto, guardamos el registro del video en base de datos
  7. // Algunos de los campos que uso:
  8. // -- id = varchar(10)
  9. // -- archivo = Nombre de archivo, primero solo almaceno la extension del archivo original
  10. // -- estado:
  11. // 0 = No se ha subido archivo
  12. // 1 = Video subido, convertido y listo para verse en la web
  13. // 2 = Se subio archivo y esta listo para convertir a FLV
  14. // 3 = Esta en proceso de conversion
  15.  
  16.  
  17. // Notificamos al usuario que el archivo subio y va a iniciar la conversion
  18. ?>
  19. <html>
  20. <body>
  21.     <p>El archivo fue subido correctamente, ahora lo vamos a convertir a FLV, mientras puedes ver otras paginas en nuestro sitio.</p>
  22. </body>
  23. </html>
  24.  
  25. <?php
  26. // >/dev/null &  ---- Esto es lo que hace que se ejecute en segundo plano
  27. exec("php /convertir.php?id=$id> /dev/null &");

convertir.php -> Configuracion general

Necesitaremos algunas variables:
- Ruta de videos pendientes de convertir: $ruta_convertir = '/ruta/convertir';
- Ruta final de videos: $ruta_video = '/ruta/videos';
- Ruta de imagen de marca de agua (opcional): $marca_agua = '/ruta/marca_agua.gif';
- Dimensiones del video convertido ANCHOxALTO: $medidas = '640x480';
- Frecuencia de audio (sample rate), especificamente, las 3 unicas permitidas en videos flv $frecuencia = array(44100, 22050, 11025);

convertir.php -> Obtener info general del video

Código php:
Ver original
  1. // Tomamos la id del video desde GET (es necesario validar)
  2. $video = $_GET['id'];
  3.  
  4. // Leemos info de la base de datos
  5. $result = mysql_query("SELECT id, archivo, mas_campos FROM videos WHERE id = '$video'");
  6. list($id, $archivo, $mas_campos) = mysql_fetch_row($result);
  7.  
  8. // En el campo archivo solo tengo almacenada la extension
  9. $original = "$ruta_convertir/$id$archivo";
  10. $final = "$ruta_video/$id" . '.flv';
  11. $vista_previa = "$ruta_video/$id" . '.jpg';
  12.  
  13. // Creamos un objeto ffmpeg_movie para obtener datos necesarios para convertir
  14. $movie = new ffmpeg_movie($original, false);
  15. $duracion = $movie->getDuration();      // Duracion en segundos
  16. $audioRate = $movie->getAudioSampleRate();
  17. $audioBitr = $movie->getAudioBitRate();
  18.  
  19. if(!in_array($audioRate, $frecuencia))
  20.     $audioRate = 22050;
  21. if(!isset($aidioBitr) || !$aidioBitr || $aidioBitr < 1)
  22.     $audioBitr = $audioRate;
  23.  
  24. // Creamos el comando ffmpeg
  25. $ffmpeg_cmd = "ffmpeg -i $original -ar  $audioRate -ab $audioBitr -f flv -s $medidas $final";
  26. // La siguiente linea es necesaria solo si vas a agregar marca de agua
  27. $ffmpeg_cmd .= " -vhook '/usr/local/lib/vhook/watermark.so -f $marca_agua'";
  28. // Ejecutamos el comando y guardamos la salida en una matriz (util para depurar)
  29. exec("$ffmpeg_cmd 2>&1", $salida);
  30. // Si necesitas depurar, despues de cada exec() incluye:
  31. // file_put_contents('depurar.txt', implode("\n", $salida));
  32.  
  33. // Injectamos metaData:
  34. $ffmpeg_cmd = "flvtool2 -U $final";
  35. exec("$ffmpeg_cmd 2>&1", $salida);
  36.  
  37. // Generamos la vista previa (120 x 90 pixeles, puedes modificarlo a tu gusto)
  38. // Seleccionamos una posicion en medio del video
  39. $posicion = sec2hms(ceil($duracion / 2));
  40. $ffmpeg_cmd2 = "ffmpeg -i $final -ss $posicion -t 00:00:01 -s 120x90 -r 1 -f image2 $vista_previa";
  41. exec("$ffmpeg_cmd2 2>&1", $salida);
  42. // Si algo fallo, intentamos otro metodo
  43. if(!file_exists($vista_previa)) {
  44.     $ffmpeg_cmd2 = "ffmpeg  -itsoffset -4  -i $final -vcodec mjpeg -vframes 1 -an -f rawvideo -s 120x90 $vista_previa";
  45.     exec("$ffmpeg_cmd2 2>&1", $salida);
  46. }
  47. // Si volvio a fallar, intentamos con ffmpeg_movie
  48. // Nota: la libreria GD tambien debe estar habilitada en /etc/php5/cli/php.ini
  49. // extension=gd.so
  50. if(!file_exists($vista_previa)) {
  51.     // Creamos el objeto, obtenemos total de cuadros y calculamos la mitad
  52.     $movie = new ffmpeg_movie($final, false);
  53.     $total = $movie->getFrameCount();
  54.     $medio = intval($total / 2);
  55.  
  56.     // Leemos el cuadro elegido y redimensionamos
  57.     $frame = $movie->getFrame($medio);
  58.     $frame->resize(120, 90);
  59.  
  60.     // Convertimos a imagen de GD, guardamos como jpg y destruimos el recurso GD
  61.     $gd_image = $frame->toGDImage();
  62.     imagejpeg($gd_image, $vista_previa);
  63.     imagedestroy($gd_image);
  64. }
  65.  
  66. // Actualizamos la base de datos con la informacion necesaria
  67. // Como depende de los campos que se tengan solo pongo un ejemplo:
  68. // archivo = '$final', vista_previa = '$vista_previa', duracion = $duracion, estado = 1
  69.  
  70. // Eliminamos archivo original
  71. unlink($original)
  72.  
  73. // Listo, eso es todo... yeah!!!!
  74.  
  75. // Funcion basada en http://snipplr.com/view/1459/sec2hms/
  76. function sec2hms($sec, $useColon = false) {
  77.     $hms = '';
  78.     $hours = intval(intval($sec) / 3600);
  79.     if ($hours > 0) {
  80.         $hms .= ($useColon) ? str_pad($hours, 2, "0", STR_PAD_LEFT). ':' : $hours. ' tim ';
  81.     } elseif ($useColon) {
  82.         $hms .= '00:';
  83.     }
  84.     $minutes = intval(($sec / 60) &#37; 60);
  85.     if ($minutes > 0 || $hours > 0)
  86.         $hms .= ($useColon) ? str_pad($minutes, 2, "0", STR_PAD_LEFT). ':' : $minutes. ' min ';
  87.     $seconds = intval($sec % 60);
  88.     $hms .= ($useColon) ? str_pad($seconds, 2, "0", STR_PAD_LEFT) : $seconds. ' sek ';
  89.     return $hms;
  90. }

Es posible realizar la conversion del video e insertar metaData en un mismo comando exec('comando1 | comando2'); pero no lo recomiendo, en ocasiones no funciono y no hay diferencia en los recursos que consume el script al ejecutarse, estuve monitoreando con TOP desde SSH.

Enlaces de interes:
- API (clase?) de ffmpeg-php
- Convertir segundos (entero) en cadena (hh:mm:ss)
__________________
- León, Guanajuato
- GV-Foto

Última edición por Triby; 05/09/2009 a las 13:45 Razón: Agregar validacion de $audioBitr
  #2 (permalink)  
Antiguo 04/09/2009, 08:50
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 12 años, 7 meses
Puntos: 1517
Respuesta: [Aporte] Convertir videos con ffmpeg en background

Iiiicchhhh ahora a probar pero con windows Te dejo saber como me va.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #3 (permalink)  
Antiguo 04/09/2009, 09:06
 
Fecha de Ingreso: agosto-2009
Ubicación: Lanzarote - Canarias
Mensajes: 57
Antigüedad: 12 años, 5 meses
Puntos: 2
Respuesta: [Aporte] Convertir videos con ffmpeg en background

yo tengo un sistema similar para hacer las capturas de los videos subidos o pasar los MP4 a FLV pero usando directamente FFMPEG a través exec()
  #4 (permalink)  
Antiguo 04/09/2009, 12:15
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 13 años, 5 meses
Puntos: 2236
Respuesta: [Aporte] Convertir videos con ffmpeg en background

Cita:
Iniciado por abimaelrc
ahora a probar pero con windows Te dejo saber como me va.
En algun momento yo tambien tendre que probar en windows; alguna caracteristica de ffmpeg o ffmpeg-php estaba disponible solo para linux, no recuerdo cual, pero creo que tampoco tenia que ver con lo que se hace con este script, asi que esperaremos tu reporte para saber si funciona.

Cita:
Iniciado por esdesign
yo tengo un sistema similar para hacer las capturas de los videos subidos o pasar los MP4 a FLV pero usando directamente FFMPEG a través exec()
De hecho la conversion se hace con exec('ffmpeg bla bla bla') y solo se usa la libreria ffmpeg_movie para detectar duracion y parametros de audio (si es necesario se modifica al convertir) y, en caso de errores en el exec(), tambien se genera la imagen de vista previa.

Posteriormente, y solo a peticion de algun usario, genero un archivo mp4 descargable para moviles. No he revisado esta opcion para actualizar / mejorar, pero es algo que debo hacer pronto.
__________________
- León, Guanajuato
- GV-Foto
  #5 (permalink)  
Antiguo 05/09/2009, 13:53
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 13 años, 5 meses
Puntos: 2236
Respuesta: [Aporte] Convertir videos con ffmpeg en background

ffmpeg_movie devuelve en audioBitRate un valor nulo, falso o "no reconocido" para algunos videos, en concreto, paso con MOV y FLV, ocasionando un error en el comando ffmpeg, por lo que no solo no se crearon el video final y la imagen de vista previa, sino que tambien se elimino el video original.

Acabo de editar el primer mensaje:
Código php:
Ver original
  1. // Esta validacion ya estaba, para aplicar audioSampleRate soportado en FLV
  2. if(!in_array($audioRate, $samples))
  3.     $audioRate = 22050;
  4. // Agregue estas dos lineas para corregir audioBitRate
  5. if(!isset($audioBitr) || !$audioBitr || $audioBitr < 1)
  6.     $audioBitr = $audioRate;
  7.  
  8. // Adicionalmente, se puede hacer otra validacion para evitar eliminar el video original
  9. // despues de ejecutar ffmpeg y antes de ejecutar flvtool2
  10. if(!file_exists($final)) {
  11.     file_put_contents('depurar.txt', implode("\n", $salida));
  12.     die();
  13. }
__________________
- León, Guanajuato
- GV-Foto
  #6 (permalink)  
Antiguo 25/11/2009, 10:10
 
Fecha de Ingreso: septiembre-2007
Ubicación: PyRoot
Mensajes: 1.515
Antigüedad: 14 años, 3 meses
Puntos: 188
Respuesta: [Aporte] Convertir videos con ffmpeg en background

Exelente muchas gracias
__________________
Si quieres agradecer el triangulo obscuro de la parte derecha debes presionar +.
  #7 (permalink)  
Antiguo 10/11/2010, 17:57
 
Fecha de Ingreso: noviembre-2004
Ubicación: NULL
Mensajes: 642
Antigüedad: 17 años, 1 mes
Puntos: 6
Respuesta: [Aporte] Convertir videos con ffmpeg en background

Ya buen tiempo que no entro por estos lados debido a que me bloquearon pero otra vez estoy aqui.

Buen aporte, ahora va mi pregunta, claro aun no lo pruebo, pero dime si en caso se suba mas de un video con el mismo nombre que pasa con el video se sobre-escribe, o se genera uno nuevo?

Ejemplo.

Video1 "Arroz" -> Primer video subido
Video1 "Azucar" Segundo video subido

El Video1 que contiene "Arroz" es reemplazado por Video1 "Azucar" ??
  #8 (permalink)  
Antiguo 22/06/2011, 11:43
Avatar de nuuk_ikel  
Fecha de Ingreso: agosto-2008
Ubicación: [ Dimensión desconocida ]
Mensajes: 164
Antigüedad: 13 años, 5 meses
Puntos: 3
Respuesta: [Aporte] Convertir videos con ffmpeg en background

Cita:
Iniciado por abimaelrc Ver Mensaje
Iiiicchhhh ahora a probar pero con windows Te dejo saber como me va.
Hey me gustaría saber si te funciono con windows y también me seria de mucha ayuda saber como lo hiciste, de antemano gracias !
__________________
[ Si hay un problema, existe una solución ]
  #9 (permalink)  
Antiguo 22/06/2011, 12:05
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 13 años, 5 meses
Puntos: 2236
Respuesta: [Aporte] Convertir videos con ffmpeg en background

En teoria, todo debe funcionar igual. Ya tienes FFmpeg para windows? http://ffmpeg.zeranoe.com/builds/, si tienes alguna duda de cual descargar, puedes usar sin problemas el "static".
__________________
- León, Guanajuato
- GV-Foto
  #10 (permalink)  
Antiguo 18/09/2011, 02:51
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 13 años, 5 meses
Puntos: 2236
Respuesta: [Aporte] Convertir videos con ffmpeg en background

Con los nuevos formatos de celulares y HTML 5 la cosa se va complicando un poco, hay que actualizar FFMPEG y software relacionado:

Para linux, se puede seguir esta guia: http://ubuntuforums.org/showthread.php?t=786095

Para windows es un poco mas complicado:
- MPlayer, que viene con MEncoder y una buena cantidad de codecs: http://www.mplayerhq.hu/design7/dload.html
- MPlayer (codecs binarios) desde la misma pagina: http://www.mplayerhq.hu/design7/dloa...#binary_codecs
- Libfaac, se requiere para MPlayer/MEncoder y no se incluye: http://oss.netfarm.it/mplayer/misc/libfaac-1.28.7z
- FFMPEG, el mas actualizado que encontre esta en: http://azzerti.free.fr/
- ffmpeg_php ya no es necesario, a menos que quieran usar los pocos codecs que se incluyen

Suponiendo que usan Wampserver, igual que yo, creamos la carpeta c:\wamp\bin\mplayer, descomprimimos ahi MPlayer, libfaac.dll y todos los ejecutables de FFMPEG, los DLL de codecs binarios de MPlayer los copiamos en C:\wamp\bin\mplayer\codecs

Si usas algun otro paquete de servidor (Xampp, EsasyPHP, etc.), solo ajusta las rutas y listo.

Adicionalmente, tambien pueden descargar algun skin de MPlayer, aunque realmente no es necesario, prefiero Media Player Classic para ver todos los videos, es mas rapido.

Si descargaron ffmpeg_php hay que habilitar la extension en php.ini, copiar php_ffmpeg.dll a C:\wamp\bin\php\php5.3.0\ext y los otros dll en c:\windows\system32; ademas, tambien habria que buscar pthreadGC2.dll para copiarlo ahi mismo.

Insisto en que esta extension ya no es tan util, a menos que se haya compilado con soporte para zlib o no podra leer videos con encabezados comprimidos, como algunos de Quicktime.

De cualquier forma, para garantizar que todo va bien, reiniciamos el servidor (Wamp o el que uses) y ya estamos listos para comenzar a probar.

En el siguiente mensaje pongo codigo PHP para realizar la conversion.
__________________
- León, Guanajuato
- GV-Foto
  #11 (permalink)  
Antiguo 18/09/2011, 03:37
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 13 años, 5 meses
Puntos: 2236
Respuesta: [Aporte] Convertir videos con ffmpeg en background

1. Para poder probar tanto en local como en produccion, guardo en variables las rutas de los programas y archivos necesarios.

Código PHP:
Ver original
  1. if($_SERVER['SERVER_NAME'] == 'localhost') {
  2.     $ffmpeg = 'c:/wamp/bin/mplayer/ffmpeg.exe';
  3.     $flvtool = 'c:/wamp/bin/mplayer/flvtool2.exe';
  4.     $srcdir = '/servidor/pruebas/tests/original';
  5.     $cnvdir = '/servidor/pruebas/tests/converted';
  6.  
  7.     // Tratando de mostrar info conforme avanza el proceso
  8.     // Esto generalmente me causa errores en Ubuntu
  9.     // Por eso lo tengo solo para el servidor local
  10.     @apache_setenv('no-gzip', 1);
  11.     @ini_set('zlib.output_compression', 0);
  12.     @ini_set('implicit_flush', 1);
  13.     for ($i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
  14. } else {
  15.     // En ubuntu no necesito la ruta absoluta para los programas
  16.     $ffmpeg = 'ffmpeg';
  17.     $flvtool = 'flvtool2';
  18.     $srcdir = '/ruta_del_sitio/htdocs/tests/original';
  19.     $cnvdir = '/ruta_del_sitio/htdocs/tests/converted';
  20. }
  21. // Por si vamos a agregar marca de agua (probado solo en Windows)
  22. $watermark = "$srcdir/watermark2.png";
  23.  
  24. // Directorio para generar imagenes de vista previa
  25. $preview_dir = "$cnvdir/preview";
  26.  
  27. // Sample rates soportados por FLV
  28. $samples = array(44100, 22050, 11025);

Bien, ya teniendo lista la configuracion, leemos los archivos, ya sea de base de datos o, en este caso, del directorio de pruebas:

Código PHP:
Ver original
  1. // Leer archivos en directorio original
  2. // No use glob porque esto ya lo tenia
  3. $files = array();
  4. $sdir = opendir($srcdir);
  5. while($file = readdir($sdir)) {
  6.     if($file != '.' && $file != '..' && end(explode('.', $file)) != 'png') {
  7.         $files[] = $file;
  8.     }
  9. }
  10.  
  11. echo 'Preparando para convertir: ' . count($files) . " videos\n------------\n";

Ok, iniciamos con lo bueno, solo pido de favor no criticar el enredo de codigo, porque iba parchando un script muy viejo sobre la marcha y... siendo solo pruebas... pues hay que hacerlo rapido.

Nota, para poder ver los avances, despues de cada echo hay que agregar flush();

Código PHP:
Ver original
  1. foreach($files as $file) {
  2.     $newext = '.flv';
  3.     $preext = '.jpg';
  4.     $parts = explode('.', $file);
  5.     $curext = '.' . end($parts);
  6.  
  7.     // Las dos lineas siguientes son solo por "compatibilidad" con el codigo de produccion
  8.     unset($parts[count($parts) - 1]);
  9.     $curvid = implode('.', $parts);
  10.  
  11.     $file_orig = "$srcdir/$curvid$curext";
  12.     $file_final = "$cnvdir/$curvid$newext";
  13.     $file_pre = "$preview_dir/$curvid$preext"; // Vista previa
  14.     $file_th = "$preview_dir/{$curvid}.th$preext"; // Agregue esto para crear miniaturas
  15.  
  16.     echo "Preparando para convertir $file_orig to $file_final\n";
  17.  
  18.     //  Obtener información del video... recordando que php_ffmpeg me dio problemas
  19.     // Simplemente hacemos que ffmpeg nos de algunos datos
  20.     // para pasarlos por preg_match
  21.     exec("$ffmpeg -i $file_orig 2>&1", $output);
  22.     $output = implode("\n", $output);
  23.     $duration = $frameRate = $audioRate = $audioBitr = 0;
  24.     if(preg_match('/Duration: (.*?),/', $output, $matches)) {
  25.         $duration = $matches[1];
  26.         $duration_array = explode(':', $duration);
  27.         $duration = ($duration_array[0] * 3600) + ($duration_array[1] * 60) + $duration_array[2];
  28.     }
  29.     if (preg_match('/([0-9\.]+)\stbr/', $output, $matches)) {
  30.         $frameRate = $matches[1];
  31.     }
  32.     if(preg_match('/bitrate: ([0-9]+) kb\/s/', $output, $matches)) {
  33.         $audioBitr = $matches[1];
  34.     }
  35.     if(preg_match('/Audio:.+?([0-9]+) Hz/', $output, $matches)) {
  36.         $audioRate = $matches[1];
  37.     }
  38.  
  39.     if($duration == 0) {
  40.         // No obtuvimos duracion, el resto de datos podemos "calcularlos", pero este no
  41.         echo "----------------\nFormato de video no reconocido: $file_orig\nDuracion: $duration\nFrame Rate: $frameRate\nAudio Sample: $audioRate\nAudio Bit: $audioBitr\n\n";
  42.         continue;
  43.     }
  44.  
  45.     // Verificamos que todo sea soportado en FLV
  46.     $oldrate = '';
  47.     if(!in_array($audioRate, $samples)) {
  48.         $oldrate = "/$audioRate";
  49.         $audioRate = 22050;
  50.     }
  51.     if(!isset($audioBitr) || !$audioBitr || $audioBitr < 1) {
  52.         $audioBitr = $audioRate;
  53.     }
  54.     echo "---- Duración: $duration segundos\n---- Frame Rate: $frameRate fps";
  55.     echo "---- Audio Bit Rate: $audioBitr\n---- Audio Sample Rate: $audioRate$oldrate";
  56.  
  57.     // Ojo, esto tuve que hacerlo para probar, solo me funciono en Windows
  58.     // Hace mas complicado el codigo, pero necesitaba poder omitirlo para Linux
  59.     $newWater = "-vf \"movie=$watermark [img]; [in] [img] overlay=0:0:1 [movie]; [movie] setdar=3:2\"";
  60.  
  61.     // Los WMV son mas latosos, asi que por separado y conservando la misma calidad (?) ( -sameq )
  62.     if(strtolower($curext) == '.wmv') {
  63.         $ffmpeg_cmd = "$ffmpeg -i $file_orig -sameq -acodec libmp3lame -ar 22050 -ab 96000 -deinterlace -nr 500 -s 450x300 -aspect 4:3 -r 20 -g 500 -me_range 20 -b 270k -f flv -y $newWater $file_final";
  64.     } else {
  65.         // El resto de formatos con una calidad entre 65 y 70% ( -qscale 10 )
  66.         $ffmpeg_cmd = "$ffmpeg -i $file_orig -qscale 10 -acodec libmp3lame -ar  $audioRate -ab $audioBitr -f flv -s 450x300 $newWater $file_final";
  67.     }
  68.  
  69.     echo "-- Comando para convertir: $ffmpeg_cmd\n";
  70.     exec("$ffmpeg_cmd 2>&1", $output);
  71.  
  72.     // Verificamos que se haya generado el video
  73.     if(!file_exists($file_final)) {
  74.         echo "\n\n------ $fecha CONVERSION FALLO, archivo no creado\nOriginal: [$file_orig]\nDestino: [$file_final]\n" . implode("\n", $output) . "\n";
  75.         continue;
  76.     }
  77.     // Se genero el archivo, pero sin informacion?
  78.     if(file_exists($file_final) && filesize($file_final) < 1) {
  79.         unlink($file_final);
  80.         echo "\n\n------ $fecha CONVERSION FALLO, archivo creado con cero bytes\nOriginal: [$file_orig]\nDestino: [$file_final]\n" . implode("\n", $output) . "\n";
  81.         continue;
  82.     }
  83.  
  84.     // Parece que todo va bien... inyectamos meta datos FLV
  85.     $ffmpeg_cmd = "$flvtool -U $file_final";
  86.     echo "-- FLVtool injection: $ffmpeg_cmd\n";
  87.     exec("$ffmpeg_cmd 2>&1", $output);
  88.  
  89.     // Preparamos para crear miniatura e imagen de vista previa
  90.     // Para el primer metodo, con itoffset, se requiere la posicion en numero entero
  91.     $itoffset = ceil($duration / 2);
  92.     // Para el segundo metodo, lo necesitamos en formato hh:mm:ss
  93.     $thumb_position = sec2hms(ceil($duration / 2));
  94.  
  95.     // Primero la miniatura
  96.     $ffmpeg_cmd2 = "$ffmpeg  -itsoffset -$itoffset  -i $file_final -vcodec mjpeg -vframes 1 -an -f rawvideo -s 100x68 $file_th";
  97.     echo "-- Crear thumbnail (1): $ffmpeg_cmd2\n";
  98.     exec("$ffmpeg_cmd2 2>&1", $output);
  99.     if(file_exists($file_th) && filesize($file_th) < 1) {
  100.         // Si no se genero correctamente, lo eliminamos
  101.         unlink($file_th);
  102.     }
  103.     if(!file_exists($file_th)) {
  104.         // No se genero, probamos el segundo metodo
  105.         // Aclaro que esto lo tengo desde la primera version del aporte
  106.         // Y no ha llegado el caso de probarlo...
  107.         // Tal vez lo haga manualmente cuando tenga tiempo
  108.         $ffmpeg_cmd2 = "ffmpeg -i $file_final -ss $thumb_position -t 00:00:01 -s 100x68 -r 1 -f image2 $file_th";
  109.         echo "-- Crear thumbnail (2): $ffmpeg_cmd2\n";
  110.         exec("$ffmpeg_cmd2 2>&1", $output);
  111.     }
  112.     // Es exactamente el mismo proceso para la imagen de vista previa
  113.     // Solo cambiamos el tamaño para que sea igual que el video: -s 450x300
  114.     // Y reemplazamos la variable $file_th por $file_pre
  115.  
  116.     echo "$curvid fue convertido correctamente!!!\n\n";
  117. }
  118. echo "Proceso finalizado.\n";

Notas:
- La funcion sec2hms() es la misma que aparece en el primer mensaje, asi que no tiene caso repetirla.
- En Windows todo trabaja como debe ser, probando videos 3gp, mov, m4v, mp4, wmv, avi y flv.
- Si quieren cambiar la calidad del video generado, el parametro -qscale puede tener valores entre 1 (maxima calidad) y 31 (lo mas bajo)... dejandolo en 10 creo que tiene una excelente relacion tamaño de archivo/calidad.
- Lo de la marca de agua no pude hacerlo funcionar en linux porque mi version ya no tiene soporte (Ubuntu 6.06 LTS) y el unico codec/filtro que no pude instalar es el requerido para esto (avfilter-lavf)... si alguien puede instalar todo sin problemas le agradeceria cualquier comentario sobre el tema, para irme preparando... pronto cambiaremos el servidor.

Como decia un gran amigo mio: Capri, c'est fini
__________________
- León, Guanajuato
- GV-Foto
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 10 personas




La zona horaria es GMT -6. Ahora son las 09:06.