使用ffmpeg作为Python子进程的简单示例,并且“签入”对转换 [英] Simple example of using ffmpeg as a Python subprocess, and "checking in" on the conversion
问题描述
我正在寻找将大型电影目录从一种格式转换为另一种格式,并检查转换的状态。我在Python编程。
I'm looking to convert a large directory of movies from one format to another, and to check in on the status of the conversion. I'm programming in Python.
这样的东西:
>> m = MovieGenerator()
>> m.convertMovie('/path/to/movie/movie1.avi')
>> print m.status
>> 35 frames completed
这是可能的(或推荐)?有没有人有一个如何使用ffmpeg作为子进程的工作示例?
Is this possible (or recommended)? Does anyone have a working example of how to use ffmpeg as a subprocess?
一旦转换发生,有没有办法检入转换(例如,已经完成了多少帧?)
Once the conversion is happening, is there any way to "check in" on the status of the conversion (for example, how many frames have been completed?)
推荐答案
对于大型电影目录,我会使用 multiprocessing.Pool
,设置一个池工作。然后使用子进程
转换文件。我使用以下脚本来批量执行AVI到MKV转换:
For a large directory of movies, I'd use multiprocessing.Pool
, to set up a pool workers. Each then converts files using subprocess
. I use the following script to do AVI to MKV conversion in batches:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Author: R.F. Smith <rsmith@xs4all.nl>
#
# To the extent possible under law, Roland Smith has waived all copyright and
# related or neighboring rights to avi2mkv.py. This work is published from the
# Netherlands. See http://creativecommons.org/publicdomain/zero/1.0/
"""Convert all AVI files found in the direcory trees named on the command line
to Theora/Vorbis streams in a Matroska container."""
import base64
import os
import sys
import subprocess
from multiprocessing import Pool, Lock
globallock = Lock()
def tempname(ext):
"""Create a name for a temporary file in the /tmp firectory.
Keyword arguments:
ext -- the extension (without .) to give to the file.
"""
return '/tmp/' + base64.b64encode(os.urandom(12), '__') + '.' + ext
def findavi(dirlist):
"""Find AVI files and returns their names in a list.
Keyword arguments:
dirlist -- a list of directories to seach in
"""
result = []
for dirname in dirlist:
for root, dirs, files in os.walk(dirname):
for name in files:
if name.endswith('.avi'):
result.append(root + '/' + name)
return result
def output(txt):
"""Print while holding a global lock."""
globallock.acquire()
print txt
globallock.release()
def process(fname):
"""Use ffmpeg2theora and mkvmerge to convert an AVI file to Theora/Vorbis
streams in a Matroska container.
Keyword arguments:
fname -- name of the file to convert
"""
ogv = tempname('ogv')
args = ['ffmpeg2theora', '--no-oshash', '-o', ogv, '-v', '7', fname]
args2 = ['mkvmerge', '-o', fname[:-3] + 'mkv', ogv]
bitbucket = open('/dev/null')
try:
output("Converting {} to {}.".format(fname, ogv))
subprocess.check_call(args, stdout=bitbucket, stderr=bitbucket)
output("Starting merge for {}.".format(ogv))
subprocess.check_call(args2, stdout=bitbucket, stderr=bitbucket)
os.remove(ogv)
output("Conversion of {} completed.".format(fname))
except:
output("ERROR: Converting {} failed.".format(fname))
bitbucket.close()
def main(argv):
"""Main program.
Keyword arguments:
argv -- command line arguments
"""
if len(argv) == 1:
path, binary = os.path.split(argv[0])
print "Usage: {} [directory ...]".format(binary)
sys.exit(0)
avis = findavi(argv[1:])
p = Pool()
p.map(process, avis)
p.close()
if __name__ == '__main__':
main(sys.argv)
这篇关于使用ffmpeg作为Python子进程的简单示例,并且“签入”对转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!