2008-09-20 17 views
6

Ok, ich bekomme die Grundlagen des Videoformats - es gibt einige Containerformate und dann hast du Core Video/Audio Formate. Ich möchte eine webbasierte Anwendung schreiben, die bestimmt, welchen Video/Audio-Codec eine Datei verwendet.Programmgesteuertes Bestimmen des Videodateiformats?

Wie kann ich am besten einen Videocodec ermitteln? Wäre es am besten, eine Standardbibliothek über Systemaufrufe zu verwenden und seine Ausgabe zu parsen? (zB ffmpeg, transcodieren, etc?)

Antwort

7

mplayer -identify wird den Trick tun. Wenn Sie einfach nur ffmpeg für eine Datei aufrufen, wird automatisch eine Reihe von Informationen am Anfang über die Eingabedatei gedruckt, unabhängig davon, was Sie ffmpeg tatsächlich tun möchten.

Natürlich, wenn Sie es von Ihrem Programm ohne einen exec-Aufruf an ein externes Programm tun möchten, können Sie einfach die avcodec-Bibliotheken hinzufügen und seine eigene Identifizierungsroutine direkt ausführen.

Während Sie Ihre eigene Erkennung implementieren könnten, wird sie sicherlich den Routinen unterlegen, angesichts der absolut enormen Anzahl von Formaten, die libav * unterstützt. Und es wäre ein ziemlich alberner Fall, das Rad neu zu erfinden.

Linux "Datei" Befehl kann auch den Trick tun, aber die Menge der Daten, die es ausgibt, hängt vom Videoformat ab. Zum Beispiel gibt es auf AVI alle Arten von Daten über Auflösung, FOURCC, fps usw., während für eine MKV-Datei nur "Matroska-Daten" stehen, die nichts über die Interna oder sogar die verwendeten Video- und Audioformate sagen.

1

Sie müssen weiter unten auf der Linie beginnen. Sie müssen das Containerformat und die Angabe des Codecs kennen.

Also würde ich mit einem Programm beginnen, das das Containerformat identifiziert (nicht nur von der Erweiterung, gehen Sie in die Kopfzeile und bestimmen den echten Container).

Dann herauszufinden, welche Container Ihr Programm unterstützt, und fügen Sie die Funktionen zum Parsen der Metadaten in den Container, die die Codecs enthalten.

-Adam

1

Sie wollen wirklich eine große Datenbank von binären Identifizierung Marker für in der Nähe der Anfang der Datei zu suchen. Glücklicherweise ist Ihre Frage mit "Linux" getaggt, und eine solche Datenbank existiert bereits dort; Datei (1) wird die Arbeit für Sie erledigen.

+0

Das geht nicht weit genug. Datei sagt Ihnen ein wenig, aber nicht Codecs wie das OP fragt nach. –

4

Ich habe FFMPEG in einem Perl-Skript verwendet, um dies zu erreichen.

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

Und einfach herausfinden, welche Elemente in @fields Sie extrahieren müssen.

0

Ich würde empfehlen, ffprobe zu verwenden und das Ausgabeformat auf json zu erzwingen. Es wäre so viel einfacher zu analysieren. Einfachstes Beispiel:

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

Seien Sie gewarnt, dass im Falle einer beschädigten Datei, die Sie null als Ergebnis und Warnung je nach Fehlermeldungen Einstellungen erhalten.Komplettes Beispiel mit der richtigen Fehlerbehandlung:

$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

Sie Mediainfo verwenden:

sudo apt-get install mediainfo 

Wenn Sie nur wollen, Video/Audio-Codec zu erhalten, können Sie wie folgt vorgehen:

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

Falls Sie weitere Informationen erfassen möchten, können Sie die von mediainfo zurückgegebene XML-Ausgabe analysieren. Hier ist Beispielfunktion:

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], 
    ); 
}