Pythonでffmpegを実行するプログラムを作成
Pythonでファイルを渡し、ffmpegを実行するプログラムを作った。
ソース:myFFmpeg.py
#! /usr/bin/python #coding:utf-8 import sys,os import command_generate from collections import OrderedDict # main処理 def main(): # コマンド引数と引数の個数を取得 argv = sys.argv argc = len(argv) # 引数の個数が2個以下(プログラム名を含む)ならUsageを出力して終了 if (argc < 2): print "Usage: # %s inputfile" % argv[0] quit() for inputFile in argv[1:]: ffmpeg_convert(inputFile) # ffmpeg変換処理 def ffmpeg_convert(inputFile): # 入力ファイルを取得し、basename、ファイル名を取得し、出力ファイル名を作成 inputBaseName = os.path.basename(inputFile) fileName = inputBaseName.split(".")[0] outputBaseName = fileName + ".mp4" outputFile = "/var/www/epgrec/video/mp4/" + outputBaseName # ffmpegの2パスログファイル名を作成 ffmpegPassLogFile = "/tmp/pass2_" + fileName + ".log" ffmpegLogFile = "/var/log/ffmpeg/" + fileName + ".log" # ffmpegのpreset位置 ffmpegPresetFile = "/usr/local/share/ffmpeg/libx264-hq-ts.ffpreset" # ファイル名をダブルクォーテーションでくくる inputFile = '"' + inputFile + '"' outputFile = '"' + outputFile + '"' ffmpegPassLogFile = '"' + ffmpegPassLogFile + '"' ffmpegLogFile = '"' + ffmpegLogFile + '"' ffmpegPresetFile = '"' + ffmpegPresetFile + '"' # 1passか2passを指定 ffmpegPass = 1 # FFmpeg FFMPEG = "ffmpeg" # 1passのオプション作成 ffmpegArgs = OrderedDict([ ("-y",""), ("-i",inputFile), ("-threads","2"), ("-cmp","chroma"), ("-flags","+ilme+ildct"), ("-deinterlace",""), ("-top","-1"), ("-fpre",ffmpegPresetFile), ("-vcodec","libx264"), ("-b:v","1280k"), ("-s","hd720"), ("-pass",str(ffmpegPass)), ("-passlogfile",ffmpegPassLogFile), ("-f","mp4"), ("-acodec","libfaac"), ("-ab","128k"), ("-ar","48000"), # 他の箇所は、("opt","value")となっているが、↓以降は、意味が異なる。 (outputFile,""), # ("value","") ("2>>",ffmpegLogFile), # ("リダイレクト",ファイル) ]) command1 = command_generate.command_generate(FFMPEG,ffmpegArgs) # 2passのエンコードオプション作成 ffmpegPass = 2 ffmpegArgs["-pass"] = str(ffmpegPass) command2 = command_generate.command_generate(FFMPEG,ffmpegArgs) # パスログを消す front = ffmpegPassLogFile[:-1] rear = ffmpegPassLogFile[-1:] repi = "*" ffmpegPassLogFile = front + repi + rear ffmpegArgs = OrderedDict([ ("-f",ffmpegPassLogFile) ]) command3 = command_generate.command_generate("rm",ffmpegArgs) # ffmpeg実行 os.system(command1) os.system(command2) os.system(command3) #----main()---- main()
command_generate.py
#! /usr/bin/python #coding:utf-8 def command_generate(program , argvs): command = program for opt,value in argvs.items(): command += " " + opt + " " + value return command
特殊な処理をしているのは二つくらい。
- ffmpegのオプション作成にOrderedDictを使っている
- パスログを消す時に文字列の間に*を入れている。
まず、1. から説明。
ffmpegをpythonで実行させるのだが、2パスで実行したい。
そのため、ほぼ同じオプションでffmpegを実行する。
そのたびに、リストを作成するのは無駄だと思ったので、マップでkeyをオプション、valueをオプションの引数にし、command_generate.pyにマップを渡し、自動でコマンドの文字列を生成してくれる関数を作った。
ところが、pythonのマップは順番に並んでいなかったため、順番を覚えているマップクラス(OrderedDict)を使った。
その結果、ffmpegArgs["-pass"] = str(ffmpegPass) とするだけで、オプションの一部だけを簡単に変更できるようになった。
不満なのは、オプションの
# 他の箇所は、("opt","value")となっているが、↓以降は、意味が異なる。 (outputFile,""), # ("value","") ("2>>",ffmpegLogFile), # ("リダイレクト",ファイル)
であり、この2つだけ意味が異なる。
処理としては問題ないが、オプションではないので、なんとかしたいところ。
次に、2.
パスログを消す時に、ファイル名の指定として、 "hoge"を"hoge*"というようにhogeの後ろに*を追加したかった。
しかし、pythonの文字列は不変であるため、破壊的な挿入ができなかった。
そこで、わざわざ
# パスログを消す front = ffmpegPassLogFile[:-1] rear = ffmpegPassLogFile[-1:] repi = "*" ffmpegPassLogFile = front + repi + rear
と記述。
破壊的な挿入ができれば楽なのに。
出力先やフォーマットなどが固定だけれど、出力先くらいは指定できるようにしたほうがいいかもしれない。
参考:
OrderedDict - Python Module of the Week
文字列の途中に破壊的に文字列を挿入する - Cacography Society
Pythonコード研究所 ファイルのパス情報を取得する basename dirname abspath