2024/09/17(火) [n年前の日記]
#1 [python] Pythonでwavファイルをループ再生したい
Windows10 x64 22H2 + Python 3.10.10 64bt を使って、wavファイルをループ再生したい。tkinterを使ってウインドウ表示して、ボタンを押したら、winsound を使って再生開始/停止をしたい。
◎ 経緯 :
自分はPCに、オーディオセレクタ SONY SB-A40 を繋いで、複数のヘッドフォンをその時々で切り替えて使っているのだけど。どうもここ最近接触が悪くて、うっかりすると左側 or 右側の音が鳴ってなかったりする。
ちゃんと左右の音が出ているのか、それっぽいwavファイルをbatファイル経由で鳴らして確認していたけれど、これだとループ再生させたり、途中で強制停止させることができない。
wavファイルをループ再生させつつ、ボタンをクリックしたら停止/再生ができる何かが欲しいなと思えてきた。いやまあ、探せばシンプルな再生アプリが見つかりそうだけど…。
ちゃんと左右の音が出ているのか、それっぽいwavファイルをbatファイル経由で鳴らして確認していたけれど、これだとループ再生させたり、途中で強制停止させることができない。
wavファイルをループ再生させつつ、ボタンをクリックしたら停止/再生ができる何かが欲しいなと思えてきた。いやまあ、探せばシンプルな再生アプリが見つかりそうだけど…。
◎ AIに作ってもらった :
生成AIの Microsoft Copilot に、そういう処理をするPythonスクリプトを作ってもらった。
最初の生成結果はスレッドを使ってループ再生するスクリプトだったのだけど、ウインドウを閉じてもずっとループ再生してダメダメだった。そこで、「スレッドを使うな」だの「winsound.SND_LOOPを使え」だの何度も修正指示を出しみたところ、それらしいスクリプトにしてくれた。
_speakertestpy.pyw
これでいいんじゃないかな…。winsound を使っているから、Windows上でしか動かないけれど…。
_winsound --- Windows 用の音声再生インターフェース - Python 3.10.15 ドキュメント
使っている wavファイルは以下。たしか MUSIC MAKERを使って自作したwavファイルだったような気がするので CC0/Public Domain ってことで。
_speakertest.wav
余談。Google gemini にも作ってもらったけれど、そちらのほうがサンプルスクリプトらしい分かりやすいコードを出してきた。クラスを無理矢理作ったりしないし、各行にコメント文を逐一入れて解説してくれた。生成AIと言っても、生成結果が結構違うのだな…。
最初の生成結果はスレッドを使ってループ再生するスクリプトだったのだけど、ウインドウを閉じてもずっとループ再生してダメダメだった。そこで、「スレッドを使うな」だの「winsound.SND_LOOPを使え」だの何度も修正指示を出しみたところ、それらしいスクリプトにしてくれた。
_speakertestpy.pyw
wavfile = "speakertest.wav" import tkinter as tk from tkinter import filedialog import winsound class LoopPlayer: def __init__(self, root): self.root = root self.root.title("Speaker Test") self.root.geometry("270x130") self.is_playing = False self.file_path = wavfile self.play_button = tk.Button(root, text="Play", command=self.toggle_play) self.play_button.pack(pady=20, ipadx=40, ipady=8) self.file_label = tk.Label(root, text=self.file_path) self.file_label.pack() self.select_button = tk.Button(root, text="Select WAV", command=self.select_file) self.select_button.pack() self.toggle_play() self.root.bind("<Return>", (lambda event: self.toggle_play())) self.root.bind("<KeyPress-space>", (lambda event: self.toggle_play())) def select_file(self): self.file_path = filedialog.askopenfilename(filetypes=[("WAV files", "*.wav")]) if self.file_path: self.file_label.config(text=self.file_path.split("/")[-1]) def toggle_play(self): self.is_playing = not self.is_playing if self.is_playing: self.play_button.config(text="Stop") winsound.PlaySound(self.file_path, winsound.SND_FILENAME | winsound.SND_ASYNC | winsound.SND_LOOP) else: self.play_button.config(text="Play") winsound.PlaySound(None, winsound.SND_FILENAME) if __name__ == "__main__": root = tk.Tk() app = LoopPlayer(root) root.mainloop()
これでいいんじゃないかな…。winsound を使っているから、Windows上でしか動かないけれど…。
_winsound --- Windows 用の音声再生インターフェース - Python 3.10.15 ドキュメント
使っている wavファイルは以下。たしか MUSIC MAKERを使って自作したwavファイルだったような気がするので CC0/Public Domain ってことで。
_speakertest.wav
余談。Google gemini にも作ってもらったけれど、そちらのほうがサンプルスクリプトらしい分かりやすいコードを出してきた。クラスを無理矢理作ったりしないし、各行にコメント文を逐一入れて解説してくれた。生成AIと言っても、生成結果が結構違うのだな…。
◎ batファイルで鳴らすやり方 :
一応メモ。今までは以下のbatファイルで鳴らしてた。再生が終わると Y/N を尋ねてきて、y なら再度再生、n なら終了する。
_speakertest_play.bat
batファイルと言いつつ途中で PowerShell を呼び出してwavファイルを再生してるあたりが…。「だったら最初から PowerShellスクリプトで書けばいいじゃん。何やってんの」と言われそうだけど、PowerShellスクリプトは実行ポリシーを設定しないとそもそも実行できないので、そのあたりで悩んでしまってこうなったような気もする。
_PowerShellの実行ポリシーについて調査(その設定で本当に大丈夫ですか?) #ps1 - Qiita
_PowerShellの実行ポリシー変更 #Windows - Qiita
_speakertest_play.bat
@echo off chcp 65001 :REPLAY setlocal enabledelayedexpansion set WAVFILE=D:\home\Music\speakertest\speakertest.wav echo Play %WAVFILE% PowerShell -c "(New-Object Media.SoundPlayer %WAVFILE%).PlaySync();" endlocal set /p yn_check="Retry ? (y/N): " IF %yn_check:Y=Y%==Y goto REPLAY IF %yn_check:N=N%==N goto END :END
batファイルと言いつつ途中で PowerShell を呼び出してwavファイルを再生してるあたりが…。「だったら最初から PowerShellスクリプトで書けばいいじゃん。何やってんの」と言われそうだけど、PowerShellスクリプトは実行ポリシーを設定しないとそもそも実行できないので、そのあたりで悩んでしまってこうなったような気もする。
_PowerShellの実行ポリシーについて調査(その設定で本当に大丈夫ですか?) #ps1 - Qiita
_PowerShellの実行ポリシー変更 #Windows - Qiita
◎ サウンド設定を呼び出せれば済む話 :
M/B に載ってるサウンド用チップが Realtek Audio なら、設定ダイアログ上に、左右から音が出てるか確認する機能が載っているので、それを使えば済んでしまうのだけど…。どこを辿れば呼び出せるのかよく分からなくて…。
Realtek Audio Console で検索すれば出てくるのかな?
Realtek Audio Console で検索すれば出てくるのかな?
◎ まともなオーディオセレクタが欲しい :
オーディオセレクタ SONY AB-40 は、ステレオミニジャック対応で、4入力/2出力 or 2入力4出力なのだけど。この製品、もう売ってないのだよな…。売ってたとしても、結構なお値段。
代替になるオーディオセレクタが欲しいのだけど、製品ジャンル自体がマイナーなようで、日本メーカはこういう製品をもうどこも作ってない。中国製品の中から探すしか…。
代替になるオーディオセレクタが欲しいのだけど、製品ジャンル自体がマイナーなようで、日本メーカはこういう製品をもうどこも作ってない。中国製品の中から探すしか…。
[ ツッコむ ]
以上、1 日分です。