我希望将大型电影目录从一种格式转换为另一种格式,并检查转换的状态。我用Python编程。
这样的事情:
>> m = MovieGenerator()
>> m.convertMovie('/path/to/movie/movie1.avi')
>> print m.status
>> 35 frames completed
这可能(或推荐)吗?有没有人有一个如何使用ffmpeg作为子进程的工作示例?
转换发生后,是否有任何方法可以检查"关于转换的状态(例如,已经完成了多少帧?)
答案 0 :(得分:4)
对于大型电影目录,我会使用multiprocessing.Pool
来设置池工作者。然后每个人使用subprocess
转换文件。我使用以下脚本批量进行AVI到MKV的转换:
#!/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)