2012-03-27 46 views
7

我一直試圖解決這個問題永遠現在(我是編程新手),我無法弄清楚。使用Python獲取FFProbe信息

我試圖建立一個腳本來測試這個文件,並給我輸出從那裏我可以得到像「音頻格式」,然後我可以放入文件名。但是,我甚至無法讓腳本返回任何文件信息。我在插入輸入文件時碰到了一堵牆...

所以在這一點上,我只需要幫助讓它吐出基於我所引入的argvs的信息。希望我能夠了解如何從中解析音頻信息。

我的企圖,這似乎是接近:

#!/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('.')] 

回答

8

在你的代碼

  1. 的args列表來POPEN問題很少有最後一個參數爲-i filename這是一個語法錯誤使用'-i '+filename代替
  2. 通常不需要shell=True,這是不必要的負擔。

除了它似乎工作,你沒有看到固定#1後輸出?

編輯:看起來您有ffprobe命令行的問題,所以我安裝了它,你需要有變化

  1. 我ffprobe(ffprobe 0.7.3-4:0.7.3-0ubuntu0.11.10.1 )似乎不接受-i標誌,輸入文件只是作爲最後一個參數傳遞。
  2. 你需要傳遞-logelevel和logleve quiet的選項作爲獨立參數,所以在這裏這些更改後,即[..., '-loglevel', 'quiet',..]

是一個示例腳本

#!/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') 

而且我看到正確的輸出:

==========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

我得到'...'的/ opt/local/bin目錄/ ffprobe: \ n「) – 2012-03-27 20:14:38

+0

@RobinHood這意味着您沒有將正確的參數傳遞給ffprobe,首先嚐試查看如何從命令行正確使用ffprobe,然後將其轉換爲python – 2012-03-27 20:21:32

+0

命令'/opt/local/bin/ffprobe -pretty -i'foo.avi''返回信息;命令'/ opt/local/bin/ffprobe -pretty -i'foo.avi'\ n'不是;但我無法弄清楚究竟是什麼加入了'\ n' – 2012-03-27 20:47:15

1

這裏是技術我認爲它是簡單易用和易於解析(用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)) 

提供的數據來自一個字符串表示,看起來像這樣:

<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

您的XML解析不適用於我(Debian 9,Python 3.5.3,ffprobe 3.2.8-1〜deb9u1)。但是,感謝提示:雖然我將您的代碼轉換爲使用JSON並且正在工作。 – 2017-11-06 14:50:47

+0

感謝您的反饋。你能否說出爲什麼它不適合你?這是一個Python問題還是生成的XML不符合? – 2017-11-30 14:53:04

+0

當我調用你的函數時,return語句給了我一個'AttributeError:module'xml.etree'沒有屬性'ElementTree'' – 2017-12-01 14:21:14