前提・実現したいこと
TkInterを用いてGUIを表示するPythonファイル(myapp.py)をPyInstallerによって単一実行ファイル(myapp.app)にしました。そのmyapp.pyでPydubを利用しようとしましたが、エラーがログに出力されました。
発生している問題・エラーメッセージ
[Error 2]No such file or directory: 'ffprobe': 'ffprobe'
myapp.py内でのPydubのコード
Python
1segument = pydub.AudioSegment.from_file(file_path)
試したこと①
myapp.py内でffmpegやffprobeをsubprocessモジュールを用いて実行しているので、PyInstallerでこれらのファイルをmyapp.appにバンドルしています。そのためmyapp.app/Contents/MacOS/内にffmpegやffprobeのバイナリファイルがあります。そこでこれらのファイルパスをPydubに教えることで解消できるのではないかと考えました。
Pudubの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')
環境
MacOS 10.15.7
Python 3.6
PyInstaller 3.6
FFmpeg 4.3.1
Pydub 0.24.1
(追記)回答してくださった方のアドバイスを聞いて試したこと
確認事項
- tkinterなしで問題は再現しますか
- pyinstallerを使わない場合に問題が再現するのか
- converterのファイルパスの確認
1・2の確認事項
- tkinterなしpyinstallerなし→正常
- tkinterありpyinstallerなし→正常
- tkinterなしpyinstallerあり→正常?
- tkinterありpyinstallerあり→今回のエラー
このようになったのですが、tkinterなしpyinstallerありでの確認に関しては、実際の状況と全く同じ状況を作れませんでした。このエラーが出る前に単一実行ファイルを作る際のエラーが出ていました。その解決に用いた方法がtkinterなしだとエラーが出ます。
そのため次のコマンドのように実行した結果、正常に動きました。
tkinterなしpyinstallerありでのpyinstallerのコマンドとその実行
console
1pyinstaller --windowed audio_play_test.py 2open dist/audio_play_test/audio/audio_play_test
audio_play_test.py
python
1import sounddevice 2import pydub 3import time 4import numpy 5 6video_path = "/---/sample.mp4" 7segment = pydub.AudioSegment.from_file(video_path) 8samples = numpy.array(segment.get_array_of_samples().tolist(),dtype="int16").reshape(-1,segment.channels) 9sounddevice.play(samples, segment.frame_rate) 10time.sleep(30)
ここまで試した時点でかなり時間がたってしまい、締め切りも迫っていることから根本的な解決を諦め、違う方法をとることにしました。もともと動画ファイルの音声を再生することが目的であったため、subprocessでffmpegを実行し、waveファイルを作成してsinmpleaudioで再生することで実装しました。解答していただいた方には申し訳ないのですが、また時間のある時にこの問題の解決に取り組みたいと思います。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。