LoginSignup
5
4

More than 1 year has passed since last update.

Pythonでmp3のバックグラウンド再生する方法

Last updated at Posted at 2019-06-17

pydubの動作チェック

今回製作したへんてこなモジュール?はLinuxで実行して動作確認しております。そのため、WindowsやMacからでは動作しない可能性があります。使う前にpydubが動作可能であるかテストしてみてください。

pydubの動作確認
from pydub import AudioSegment
from pydub.playback import play
audio = AudioSegment.from_mp3("audio.mp3")
play(audio)

適当なaudio.mp3を同じフォルダにおいて実行して音が鳴ればおkです。
もちろんpydubやsimpleaudioは事前にpip経由等でインストールしておいてください。

背景

pyaudioはwavしか再生できず、pydubはmp3が読み込めるがバックグラウンド再生を指定することが出来ない。
調べた所pygameが使えるということだが、使い方が悪いのか再生が重たくノイズが入ってうまく再生できなかった。

解決法

pydubのソースを読んでみると、中でsimpleaudioで再生してwaitしているみたいなので、これをなくせばバックグラウンド再生ができる。ということで、pydubとsimpleaudioを適当に組み合わせたらうまいこといろいろ再生できる環境が作れそうだということがわかりました。

というわけで、mp3やwavファイルなどのコーデックにも対応して、なおかつバイナリデータからバックグラウンドも再生できる単純なクラスを書いてみました。

結果

pydubとsimpleaudioを組み合わせた結果、以下のようなものを作ればいろいろと対応できそうです。

# バイナリデータを読み込む場合の一時ファイル用
from tempfile import NamedTemporaryFile

from pydub import AudioSegment
import simpleaudio

class SoundPlayer:
    """SoundPlayer module."""

    @classmethod
    def play(cls, filename, audio_format="mp3", wait=False, stop=False):
        """Play audio file."""

        if stop:
            simpleaudio.stop_all()

        seg = AudioSegment.from_file(filename, audio_format)
        playback = simpleaudio.play_buffer(
            seg.raw_data,
            num_channels=seg.channels,
            bytes_per_sample=seg.sample_width,
            sample_rate=seg.frame_rate
        )

        if wait:
            playback.wait_done()

    @classmethod
    def play_from_buffer(cls, audio_content, audio_format="mp3", wait=False, stop=False):
        """Play from buffer."""
        with NamedTemporaryFile() as fd:
            fd.write(audio_content)
            # Revert head of file. It is neccesary to play audio.
            fd.seek(0)
            cls.play(fd.name, audio_format=audio_format, wait=wait, stop=stop)

使い方

mp3ファイルを再生する

SoundPlayer.play(file_name)

wavファイルを再生する

SoundPlayer.play(file_name, audio_format="wav")

バイナリデータのmp3を再生する

たとえばgoogleのAPIから返された音声データはmp3のバイナリで変数に代入されて帰ってくるので
そのままでは再生できない。そのため一時ファイルに一度書き出せば再生できる。

SoundPlayer.play_from_buffer(audio_content)

再生中の音を止めてから再生する

SoundPlayer.play(file_name, stop=True)

再生が終わるまでまつ

SoundPlayer.play(file_name, wait=True)

おわりに

pydubにバックグラウンド再生のオプションが搭載されればこのようなものはいらなくなりますが、いつになるやら。同じようなことで困ってる方がいましたら何かの参考になれば幸いです。

How to play mp3 background in Python

5
4
9

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4