2008-09-20 7 views
6

Ok, tengo los conceptos básicos del formato de video: hay algunos formatos de contenedor y luego tienes los formatos básicos de video/audio. Me gustaría escribir una aplicación basada en web que determine qué códec de video/audio está usando un archivo.¿Determinado programáticamente el formato de archivo de video?

¿Cuál es la mejor manera de determinar un códec de video mediante programación? ¿Sería mejor utilizar una biblioteca estándar a través de llamadas al sistema y analizar su salida? (por ejemplo, ffmpeg, transcode, etc.)

Respuesta

7

mplayer -identify hará el truco. Simplemente llamando al ffmpeg en un archivo también funcionará: imprimirá automáticamente un conjunto de información al inicio sobre el archivo de entrada, independientemente de lo que le esté diciendo a ffmpeg en realidad.

Por supuesto, si desea hacerlo desde su programa sin una llamada ejecutiva a un programa externo, puede simplemente incluir las bibliotecas avcodec y ejecutar su propia rutina de identificación directamente.

Si bien puede implementar su propia detección, seguramente será inferior a las rutinas existentes dada la enorme cantidad de formatos que admite libav *. Y sería un caso bastante tonto de reinventar la rueda.

El comando "archivo" de Linux también puede hacer el truco, pero la cantidad de datos que imprime depende del formato de video. Por ejemplo, en AVI proporciona todo tipo de datos sobre resolución, FOURCC, fps, etc., mientras que para un archivo MKV solo dice "datos de Matroska", sin decirle nada sobre las partes internas, ni siquiera sobre los formatos de video y audio utilizados.

1

Debe comenzar más adelante en la línea. Necesita conocer el formato de contenedor y cómo especifica el códec.

Así que comenzaría con un programa que identifique el formato del contenedor (no solo desde la extensión, vaya al encabezado y determine el contenedor real).

A continuación, determine qué contenedores admitirá su programa, y ​​coloque las funciones necesarias para analizar los metadatos almacenados en el contenedor, que incluirán los códecs.

-Adam

1

realmente quieres una gran base de datos de los indicadores de identidad binarios para buscar cerca del inicio del archivo. Afortunadamente, su pregunta está etiquetada como "Linux", y esa base de datos ya existe allí; el archivo (1) hará el trabajo por usted.

+0

Esto no es suficiente. archivo le dice un poco, pero no códecs como pide el OP. –

4

He usado FFMPEG en una secuencia de comandos de perl para lograr esto.

$info = `ffmpeg -i $path$file 2>&1 /dev/null`; 
@fields = split(/\n/, $info); 

Y descubra qué elementos de @fields necesita extraer.

0

Recomendaría usar ffprobe y forzar el formato de salida a json. Sería mucho más fácil de analizar. Más simple ejemplo:

$meta = json_decode(join(' ', `ffprobe -v quiet -print_format json -show_format -show_streams /path/to/file 2>&1`)); 

se advirtió que en el caso del archivo dañado obtendrá como resultado null y la alerta dependiendo de la configuración de informes de error.Ejemplo completo con manejo de errores adecuado:

$file = '/path/to/file'; 
$cmd = 'ffprobe -v quiet -print_format json -show_format -show_streams ' . escapeshellarg($file).' 2>&1'; 

exec($cmd, $output, $code); 
if ($code != 0) { 
    throw new ErrorException("ffprobe returned non-zero code", $code, $output); 
} 

$joinedOutput = join(' ', $output); 
$parsedOutput = json_decode($joinedOutput); 
if (null === $parsedOutput) { 
    throw new ErrorException("Unable to parse ffprobe output", $code, $output); 
} 

//here we can use $parsedOutput as simple stdClass 
0

Puede utilizar mediainfo:

sudo apt-get install mediainfo 

Si lo que desea es obtener el códec de vídeo/audio, puede hacer lo siguiente:

$videoCodec = `mediainfo --Inform="Video;%Format%" $filename`; 
$audioCodec = `mediainfo --Inform="Audio;%Format%" $filename`; 

En caso de que quiera capturar más información, puede analizar la salida XML devuelta por mediainfo. Aquí está la función de muestra:

function getCodecInfo($inputFile) 
{ 
    $cmdLine = 'mediainfo --Output=XML ' . escapeshellarg($inputFile); 

    exec($cmdLine, $output, $retcode); 
    if($retcode != 0) 
     return null; 

    try 
    { 
     $xml = new SimpleXMLElement(join("\n",$output)); 
     $videoCodec = $xml->xpath('//track[@type="Video"]/Format'); 
     $audioCodec = $xml->xpath('//track[@type="Audio"]/Format'); 
    } 
    catch(Exception $e) 
    { 
     return null; 
    } 

    if(empty($videoCodec[0]) || empty($audioCodec[0])) 
     return null; 

    return array(
     'videoCodec' => (string)$videoCodec[0], 
     'audioCodec' => (string)$audioCodec[0], 
    ); 
} 
Cuestiones relacionadas