2012-03-27 19 views
7

Ho cercato di capirlo per sempre ora (sono nuovo alla programmazione) e non riesco a capirlo.Ottenere informazioni FFProbe con Python

Sto tentando di creare uno script che metterà alla prova il file e mi fornirà un output da cui posso ottenere informazioni come "Audio Format" che posso quindi inserire nel nome del file. Tuttavia, non riesco nemmeno a ottenere che lo script restituisca informazioni sui file. Ho colpito un muro all'inserimento di un file di input ...

Quindi a questo punto ho solo bisogno di aiuto per farmi sputare informazioni basate sugli argomenti che ho gettato. Speriamo di essere in grado di capire fuori come analizzare le informazioni audio da quello.

Il mio tentativo che sembra essere vicino:

#!/usr/bin/python 
import os, sys, subprocess, shlex, re 
from subprocess import call 
def probe_file(filename): 
    p = subprocess.Popen(['/opt/local/bin/ffprobe', '-show_format', '-pretty', '-loglevel quiet', -i filename], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) 
    print filename 
    print p.communicate() 
[probe_file (f) for f in os.listdir('.') if not f.startswith('.')] 

risposta

8

Pochi problemi nel codice elenco

  1. args per Popen ha ultimo argomento come -i filename, che è una sintassi utilizzo errore '-i '+filename invece
  2. shell=True di solito non è necessario ed è un onere non necessario.

A parte questo sembra funzionare, non vedi l'output dopo aver risolto il numero 1?

Edit: Sembra che si stanno avendo problemi con ffprobe riga di comando, così ho installato e modifiche desiderate sono

  1. mio ffprobe (ffprobe 0.7.3-4: 0.7.3-0ubuntu0.11.10.1) non sembra accettare il flag -i, il file di input è appena passato come ultimo argomento.
  2. è necessario passare -logelevel e possibilità di logleve quiet come argomenti separati cioè [..., '-loglevel', 'quiet',..]

Così, dopo questi cambiamenti Ecco uno script di esempio

#!/usr/bin/python 
import os, sys, subprocess, shlex, re 
from subprocess import call 
def probe_file(filename): 
    cmnd = ['ffprobe', '-show_format', '-pretty', '-loglevel', 'quiet', filename] 
    p = subprocess.Popen(cmnd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    print filename 
    out, err = p.communicate() 
    print "==========output==========" 
    print out 
    if err: 
     print "========= error ========" 
     print err 

probe_file('drop.avi') 

E vedo l'uscita corretta:

==========output========== 
[FORMAT] 
filename=drop.avi 
nb_streams=1 
format_name=avi 
format_long_name=AVI format 
start_time=0:00:00.000000 
duration=0:00:06.066667 
size=660.000 Kibyte 
bit_rate=891.217 Kbit/s 
[/FORMAT] 

========= error ======== 
ffprobe version 0.7.3-4:0.7.3-0ubuntu0.11.10.1, Copyright (c) 2007-2011 the Libav developers 
    built on Jan 4 2012 16:08:51 with gcc 4.6.1 
    configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=amd64 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --enable-shared --disable-static 
    libavutil 51. 7. 0/51. 7. 0 
    libavcodec 53. 6. 0/53. 6. 0 
    libavformat 53. 3. 0/53. 3. 0 
    libavdevice 53. 0. 0/53. 0. 0 
    libavfilter 2. 4. 0/2. 4. 0 
    libswscale 2. 0. 0/2. 0. 0 
    libpostproc 52. 0. 0/52. 0. 0 
Unsupported codec with id 114 for input stream 0 
+0

sto diventando '... '/ opt/local/bin/ffprobe: argomento mancante per l'opzione 'i pippo' \ n ")' –

+0

@RobinHood che significa che non stai passando i parametri corretti a ffprobe, prima prova a vedere come usare correttamente ffprobe dalla riga di comando e poi tradurlo in python –

+0

Il comando '/opt/local/bin/ffprobe -pretty -i 'foo.avi'' restituisce informazioni; il comando '/ opt/local/bin/ffprobe -pretty -i 'foo.avi' \ n' doesnt; ma non riesco a capire cosa diavolo sta aggiungendo il '\ n' –

1

Ecco la tecnica Penso sia semplice da usare e facile da analizzare (testato con ff mpeg 3.x):

import subprocess 
import xml.etree 

def ffprobe(executable, filename): 
    '''Runs ``ffprobe`` executable over ``filename``, returns parsed XML 

    Parameters: 

     executable (str): Full path leading to ``ffprobe`` 
     filename (str): Full path leading to the file to be probed 

    Returns: 

     xml.etree.ElementTree: containing all parsed elements 

    ''' 

    cmd = [ 
     executable, 
     '-v', 'quiet', 
     '-print_format', 'xml', #here is the trick 
     '-show_format', 
     '-show_streams', 
     filename, 
     ] 

    return xml.etree.ElementTree.fromstring(subprocess.check_output(cmd)) 

I dati disponibili viene da una rappresentazione di stringa che assomiglia a questo:

<ffprobe> 
    <streams> 
    <stream index="0" codec_name="h264" codec_long_name="H.264/AVC/MPEG-4 AVC/MPEG-4 part 10" profile="Constrained Baseline" codec_type="video" codec_time_base="1/60" codec_tag_string="avc1" codec_tag="0x31637661" width="560" height="320" coded_width="560" coded_height="320" has_b_frames="0" sample_aspect_ratio="0:1" display_aspect_ratio="0:1" pix_fmt="yuv420p" level="30" color_range="tv" color_space="bt709" color_transfer="bt709" color_primaries="bt709" chroma_location="left" refs="1" is_avc="true" nal_length_size="4" r_frame_rate="30/1" avg_frame_rate="30/1" time_base="1/90000" start_pts="0" start_time="0.000000" duration_ts="498000" duration="5.533333" bit_rate="465641" bits_per_raw_sample="8" nb_frames="166"> 
     <disposition default="1" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0" timed_thumbnails="0"/> 
     <tag key="creation_time" value="2010-03-20T21:29:11.000000Z"/> 
     <tag key="language" value="und"/> 
     <tag key="encoder" value="JVT/AVC Coding"/> 
    </stream> 
    <stream>...</stream> 
    </streams> 
    <format filename="/Users/andre/Projects/qnap/librarian/librarian/data/movie.mp4" nb_streams="2" nb_programs="0" format_name="mov,mp4,m4a,3gp,3g2,mj2" format_long_name="QuickTime/MOV" start_time="0.000000" duration="5.568000" size="383631" bit_rate="551193" probe_score="100"> 
    <tag key="major_brand" value="mp42"/> 
    <tag key="minor_version" value="0"/> 
    <tag key="compatible_brands" value="mp42isomavc1"/> 
    <tag key="creation_time" value="2010-03-20T21:29:11.000000Z"/> 
    <tag key="encoder" value="HandBrake 0.9.4 2009112300"/> 
    </format> 
</ffprobe> 
+0

L'analisi XML non funziona per me (Debian 9, Python 3.5.3, ffprobe 3.2.8-1 ~ deb9u1). Ma grazie per il suggerimento: ho trasformato il tuo codice per usare JSON e sta funzionando. –

+0

Grazie per il feedback. Potresti dirmi perché non funziona per te? È un problema di Python o l'XML generato non è conforme? –

+0

Quando chiamo la tua funzione l'istruzione return mi dà un attributo 'AttributeError: module' xml.etree 'non ha attributo' ElementTree'' –