PyIlnstallerによって単一実行ファイル化したアプリケーションでpydubを利用したい
TkInterを用いてGUIを表示するPythonファイル(myapp.py)をPyInstallerによって単一実行ファイル(myapp.app)にしました。そのmyapp.pyでPydubを利用しようとしましたが、次のように実行したところ、エラーがログに出力されました。
myapp.py内でのPydubのコード
segument = pydub.AudioSegment.from_file(file_path)
エラー
[Error 2]No such file or directory: 'ffprobe': 'ffprobe'
調べると、Pydubではffmpegをsubprocessで利用しているようでした。
ちなみに、myapp.pyをそのまま実行すれば、エラーは出ません
環境
MacOS 10.15.7
Python 3.6
PyInstaller 3.6
FFmpeg 4.3.1
Pydub 0.24.1
試したこと①
myapp.py内でffmpegやffprobeをsubprocessモジュールを用いて実行しているので、PyInstallerでこれらのファイルをmyapp.appにバンドルしています。そのためmyapp.app/Contents/MacOS/内にffmpegやffprobeのバイナリファイルがあります。そこでこれらのファイルパスをPydubに教えることで解消できるのではないかと考えました。
pydubのGitHub
pydubをgitで確認すると、以下のような記述がありました。
pydub/audio_segment.py
class AudioSegment(object): # --略-- converter = get_encoder_name() # either ffmpeg or avconv # --略--pydub/utils.py
# --略-- def get_encoder_name(): """ Return enconder default application for system, either avconv or ffmpeg """ if which("avconv"): return "avconv" elif which("ffmpeg"): return "ffmpeg" else: # should raise exception warn("Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work", RuntimeWarning) return "ffmpeg" # --略--
そこでpydub.AudioSegmentクラスのconverterを設定してあげれば良いと考え、先述したコードの前に次のコードを追加しましたが、同じエラーが表示され解決できませんでした。(APP_PATHはmyapp.appのパスの文字列)
pydub.AudioSegment.converter = APP_PATH + '/Contents/MacOS/ffmpeg' # 追加
segument = pydub.AudioSegment.from_file(file_path)
また、pydub/audio_segment.pyのAudioSegmentクラス内に次のようなメソッドがありましたが、使い方がわかりませんでした。
pydub/audio_segment.py
class AudioSegment(object): #--略-- # TODO: remove in 1.0 release # maintain backwards compatibility for ffmpeg attr (now called converter) @classproperty def ffmpeg(cls): return cls.converter @ffmpeg.setter def ffmpeg(cls, val): cls.converter = val # --略--
試したこと②
sys.path.appendを用いてpydubにffmpegやffprobeのパスを教えようとしましたが、同じエラーが表示され、解決できませんでした。
sys.path.append(APP_PATH + '/Contents/MacOS/ffmpeg')
sys.path.append(APP_PATH + '/Contents/MacOS/ffprobe')