よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

Pythonで音声ファイルの再生(失敗編termux)

Pythonで音声ファイルを再生するにはどうするのでしょ?
AndroidスマホのtermuxでPythonからやりたいのだが失敗しまくる記録。PCならすぐできそうですが…

画像や動画処理ならPillowOpenCVのように「これ使っとけ」的な鉄板ライブラリがありますけど、音声ファイルは検索すると色々出てきます。

検索結果順にざっと並べると、pygamepyaudiovlcaplaympg321winsoundpydub、etc.

vlcaplaympg321Python用ライブラリではなくコマンドらしいので、termuxで使えればPythonからはsubprocessを通しての利用となる。
winsoundWindows用のライブラリ。Androidスマホで動かしたいので今回は使えない。



実行環境


Androidスマホ
termux
Python3.7
JupyterNotebook

目次


pyaudio失敗編


Androidスマホpyaudioライブラリのインストールが出来なかった。

https://shizenkarasuzon.hatenablog.com/entry/2018/12/31/145510 の写経させて頂きました。投稿時大学受験を控えた高校生のブログだそうです。

import numpy as np
import wave 
import pyaudio
import matplotlib.pyplot as plt

def PlayWavFie(Filename = "sample.wav"):
    try:
        wf = wave.open(Filename, "r")
    except FileNotFoundError: #ファイルが存在しなかった場合
        print("[Error 404] No such file or directory: " + Filename)
        return 0
        
    # ストリームを開く
    p = pyaudio.PyAudio()
    stream = p.open(format=p.get_format_from_width(wf.getsampwidth()),
                    channels=wf.getnchannels(),
                    rate=wf.getframerate(),
                    output=True)

    # 音声を再生
    chunk = 1024
    data = wf.readframes(chunk)
    while data != '':
        stream.write(data)
        data = wf.readframes(chunk)
    stream.close()
    p.terminate()


if __name__ is "__main__":
    PlayWavFie("sample.wav") 

termuxでpip install pyaudioを試みるも失敗。
検索した限りC言語でビルドが云々かんぬんと。
下のURLにQ&Aでやり取りされている中の一番下にインストールの方法が書いてあるが、手間が掛かるし初心者向けではない。参考まで https://github.com/termux/termux-packages/issues/2962
一旦放置で。



pydub失敗編


Androidスマホにpydubライブラリのインストールは難なく出来たが、実行時にエラーが出た。

https://algorithm.joho.info/programming/python/pydub-play/ の写経させて頂きました。

まずはpydubをインストール。
(JupyterNotebookのマジックコマンドを使ってます。)

%pip install pydub
Collecting pydub
  Downloading https://files.pythonhosted.org/packages/79/db/eaf620b73a1eec3c8c6f8f5b0b236a50f9da88ad57802154b7ba7664d0b8/pydub-0.23.1-py2.py3-none-any.whl
Installing collected packages: pydub
Successfully installed pydub-0.23.1
Note: you may need to restart the kernel to use updated packages.

pydubのインストールはできた。
続けて音声ファイルの再生を行う。

from pydub import AudioSegment
from pydub.playback import play

# 音声ファイルの読み込み
sound = AudioSegment.from_file("input.mp3", "mp3")

# 再生
play(sound)
/data/data/com.termux/files/home/python3.7/lib/python3.7/site-packages/pydub/utils.py:179: RuntimeWarning: Couldn't find ffplay or avplay - defaulting to ffplay, but may not work
  warn("Couldn't find ffplay or avplay - defaulting to ffplay, but may not work", RuntimeWarning)



--------------------------------------------

FileNotFoundErrorTraceback (most recent call last)

<ipython-input-2-c26d40624fe1> in <module>
      6 
      7 # 再生
----> 8 play(sound)


~/python3.7/lib/python3.7/site-packages/pydub/playback.py in play(audio_segment)
     69         return
     70 
---> 71     _play_with_ffplay(audio_segment)


~/python3.7/lib/python3.7/site-packages/pydub/playback.py in _play_with_ffplay(seg)
     17     with NamedTemporaryFile("w+b", suffix=".wav") as f:
     18         seg.export(f.name, "wav")
---> 19         subprocess.call([PLAYER, "-nodisp", "-autoexit", "-hide_banner", f.name])
     20 
     21 


/data/data/com.termux/files/usr/lib/python3.7/subprocess.py in call(timeout, *popenargs, **kwargs)
    321     retcode = call(["ls", "-l"])
    322     """
--> 323     with Popen(*popenargs, **kwargs) as p:
    324         try:
    325             return p.wait(timeout=timeout)


/data/data/com.termux/files/usr/lib/python3.7/subprocess.py in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, encoding, errors, text)
    773                                 c2pread, c2pwrite,
    774                                 errread, errwrite,
--> 775                                 restore_signals, start_new_session)
    776         except:
    777             # Cleanup if the child failed starting.


/data/data/com.termux/files/usr/lib/python3.7/subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, start_new_session)
   1518                         if errno_num == errno.ENOENT:
   1519                             err_msg += ': ' + repr(err_filename)
-> 1520                     raise child_exception_type(errno_num, err_msg, err_filename)
   1521                 raise child_exception_type(err_msg)
   1522 


FileNotFoundError: [Errno 2] No such file or directory: 'ffplay': 'ffplay'

またもや撃沈。
ffplayが見つからんぞ?と。なんですの、そのffplayとは。



ffplayを検索すると、ffmpegというものがやたら出てくる。
こちら https://tmg0525.hatenadiary.jp/entry/2018/05/24/211022 によると、pydubを使うにはffmpegをインストールしなければならないと書かれている。
また、ffplayffmpegをインストールすれば自動的にインストールされるとも。
我が輩のtermuxでapt listコマンドを実行すると、ffmpeg[installed,automatic]と表示されているのでインストール済みなのだろうが、なぜか動きませんねぇ。



ところでffmpegとは何なのか。マルチメディアの鉄板ライブラリっぽい。音声や動画の変換を何でもこなせる。「これ知らんやつはモグリ」だそうです。覚えとこ。

肝心のffplayがよく分からんので、pydubも一旦放置。

winsound番外編


Androidスマホで動かしたいので、このWindows用ライブラリは使えません。後日参考の為に記録しておく。

こちらを写経させて頂きました。 https://techacademy.jp/magazine/20870

import winsound

with open('sample.wav', 'rb') as f:
    data = f.read()

winsound.PlaySound(data, winsound.SND_MEMORY)
 

シンプル。



pygame失敗編


pygameは2Dゲームを作るPython用定番ライブラリとのこと。音声ファイル専用ではないが試してみます。 こちらのサイトを写経させて頂きました。 https://algorithm.joho.info/programming/python/pygame/#toc7

%pip install pygame
Collecting pygame
  Using cached https://files.pythonhosted.org/packages/0f/9c/78626be04e193c0624842090fe5555b3805c050dfaa81c8094d6441db2be/pygame-1.9.6.tar.gz
[31m    ERROR: Command errored out with exit status 1:
     command: /data/data/com.termux/files/home/python3.7/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/data/data/com.termux/files/usr/tmp/pip-install-1ru1oywg/pygame/setup.py'"'"'; __file__='"'"'/data/data/com.termux/files/usr/tmp/pip-install-1ru1oywg/pygame/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /data/data/com.termux/files/usr/tmp/pip-install-1ru1oywg/pygame/pip-egg-info
         cwd: /data/data/com.termux/files/usr/tmp/pip-install-1ru1oywg/pygame/
    Complete output (12 lines):


    WARNING, No "Setup" File Exists, Running "buildconfig/config.py"
    Using UNIX configuration...

    /data/data/com.termux/files/usr/bin/sh: 1: sdl-config: not found
    /data/data/com.termux/files/usr/bin/sh: 1: sdl-config: not found
    /data/data/com.termux/files/usr/bin/sh: 1: sdl-config: not found

    Hunting dependencies...
    WARNING: "sdl-config" failed!
    Unable to run "sdl-config". Please make sure a development version of SDL is installed.
    ----------------------------------------[0m
[31mERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.[0m
Note: you may need to restart the kernel to use updated packages.

pygameのインストール失敗。
GUIを使いそうなPythonライブラリのインストールはtermuxでは大概失敗する。



音声ファイル再生用のコードを写経しておきます。

import pygame.mixer
import time

# メイン
def main():
    pygame.mixer.init(frequency = 44100)    # 初期設定
    pygame.mixer.music.load("test.mp3")     # 音楽ファイルの読み込み(wavファイルも読み込み可能)
    pygame.mixer.music.play(1)              # 音楽の再生回数(1回) ※-1を指定するとループ
    time.sleep(100)                         # 音楽の再生時間
    pygame.mixer.music.stop()               # 再生の終了


if __name__ == '__main__':
    main()



vlc


vlcはあらゆるOSでほぼ全ての動画と音声ファイルに対応した高機能な無料のメディアプレイヤーだそうです。
参考 https://appli-world.jp/posts/5180
インストール方法と使い方 https://applica.info/vlc-media-player-how-to-use



termuxでapt listコマンドを実行すると表示される一覧にvlcが載っているのでインストールできそうではあるが、動かし方が分からないのでこれも一旦放置。



aplay、mpg321不明


Androidとtermuxに対応しているのか不明。放置。



termux-media-playerコマンド成功編


失敗続きです。そろそろ再生成功したい。
インチキしてtermuxのメディア再生コマンドを使う。
termux-media-player play 音声ファイル名とコマンド打つとファイルが再生された。
停止するにはtermux-media-player stopコマンド。

Pythonで動かすにはsubprocessを使えばいいだろう。方法は省略。参考まで。



さいごに


音声ファイルを再生すべくAndroidスマホでtermuxからPythonライブラリを幾つか試したが、ことごとく粉砕された。
これが動画ファイルとなると、GUIを動かす難易度が我が素人レベルでは太刀打ち出来ないのでほぼ不可能。コマンドをsubprocessで使うならどうにかできるかも。



参考にさせて貰ったサイトの方々に感謝申し上げます。ありがとうございました。
今回の玉砕日記は以上です。