Получение Информации FFProbe С Помощью Python
Я пытаюсь понять это навсегда (я новичок в программировании), и я не могу понять это.
Я пытаюсь создать скрипт, который будет тестировать файл, и дать мне вывод, из которого я могу получить информацию, такую как "аудио формат", который я могу поместить в имя файла. Однако я даже не могу заставить скрипт возвращать любую информацию о файле. Я наткнулся на стену при вставке входного файла...
поэтому на данный момент мне просто нужна помощь, чтобы выплюнуть информацию основываясь на 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('.')]
2 ответов
несколько проблем в коде
- список args для Popen имеет последний аргумент как
-i filename
который является синтаксической ошибкой use'-i '+filename
вместо -
shell=True
обычно не требуется и является излишним бременем.
кроме того, что он, кажется, работает, вы не видите выход после исправления #1 ?
Edit: похоже, у вас возникли проблемы с командной строкой ffprobe, поэтому я установил ее и внес необходимые изменения are
- мой ffprobe (ffprobe 0.7.3-4:0.7.3-0ubuntu0.11.10.1) похоже, не принимает
-i
флаг, входной файл просто передается как последний аргумент. - вам нужно пройти
-logelevel
и вариант loglevequiet
как отдельные аргументы, т. е.[..., '-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
вот техника, я думаю, что она проста в использовании и проста в разборе (протестирована с ffmpeg 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>