Last active
February 6, 2017 16:26
-
-
Save degarashi/ce35dff85156fee974e4070b7672072a to your computer and use it in GitHub Desktop.
FFMpegを使って指定ディレクトリの動画ファイルから音声部分を一括抽出
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
# FFMpegを使って指定ディレクトリの動画ファイルから音声部分を一括抽出するプログラム | |
# ------------------: 使い方:--------------------------- | |
# python3 extract_audio.py (ディレクトリのパス) (抽出対処の拡張子 mp4など) [remove] | |
# removeをつけると抽出した後に元ファイルを削除する | |
import glob | |
import shlex | |
import subprocess | |
import re | |
import os | |
import sys | |
class UnknownError(BaseException): | |
"""FFMpegからの出力が解析できなかった時などの不明なエラー""" | |
def __init__(self, fn): | |
self.fn = fn | |
def __str__(self): | |
return "UnknownError: while reading file=" + self.fn | |
class UnknownFormat(BaseException): | |
"""FFMpegから返されたフォーマット文字列が未知だった時など""" | |
def __init__(self, fn, fmt): | |
self.fn = fn | |
self.fmt = fmt | |
def __str__(self): | |
return "UnknownFormat: while reading file=" + self.fn + ", format=" + self.fmt | |
# FFMpegが出力したストリーム情報から音声フォーマット文字列の抽出 | |
re0 = re.compile(r"Stream\s+#\d:\d.*\s+Audio:\s+(\w+)(,|\s)") | |
# ファイルパスから拡張子の直前までを取り出す | |
re1 = re.compile(r"([/\\\w\s]+)\.") | |
# FFMpegのバイナリ名 | |
FFMpeg = "ffmpeg" | |
param = sys.argv | |
if len(param)<3: | |
# 引数足りない時は呼び出し例を表示して終了 | |
print("usage: python3 extract_audio.py path(ex. ./Directory) extension(ex. mp4) [remove]") | |
quit() | |
param_dir = param[1] | |
param_ext = param[2] | |
param_rem = True if len(param)>=4 and param[3].lower()=="remove" else False | |
# 音声フォーマットとコンテナの対応表。必要に応じて追加する | |
FormatToContainer = { | |
"aac": "m4a", | |
"vorbis": "ogg" | |
} | |
# 相対パスを絶対パスへ変換 | |
if(not os.path.isabs(param_dir)): | |
param_dir = os.path.abspath(param_dir) | |
param_dir = os.path.join(param_dir, "*." + param_ext) | |
files = glob.glob(param_dir) | |
for fn in files: | |
ret = subprocess.Popen([FFMpeg, "-i", fn], stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
# FFMpegにファイルを入力しただけだとstderrに詳細が返ってくる | |
s = "" | |
for line in ret.stderr: | |
s += line.decode() | |
# 返って来た文字列から音声フォーマットを特定し、対応するコンテナ形式を取得 | |
fmtstr = re0.search(s) | |
if fmtstr: | |
fmt = fmtstr.group(1).lower() | |
if fmt in FormatToContainer: | |
container = FormatToContainer[fmt] | |
else: | |
# 対応するコンテナ形式がマップに登録されておらぬ | |
raise UnknownFormat(fn, fmt) | |
else: | |
# 音声フォーマットがわからぬ | |
raise UnknownError(fn) | |
# 出力先パスに拡張子を付加してFFMpegへ突っ込む | |
m = re1.search(fn) | |
output = fn[m.start(1):m.end(1)] + "." + container | |
cmd = FFMpeg + ' -i "' + fn + '" -vn -acodec copy "' + output + '"' | |
subprocess.call(shlex.split(cmd)) | |
# Removeフラグが指定されていればここでファイルを削除 | |
if param_rem: | |
os.remove(fn) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment