質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

1087閲覧

raspberry piを使ってボタンが押されたらランダムで音楽再生される方法

horisuke3232

総合スコア109

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/08/31 14:17

編集2017/09/03 14:28

raspberry piを使ってボタンが押されたらリストの中の音楽がランダムで再生される物を作っています。

現在下記のコードでボタンが押されたらリストの中の音楽がランダムで再生されるところまでは行ったのですが、続けてボタンを押してしまうと重ねて音楽が再生されてしまいます。

プログラミングを習いたてでまだ応用が効かずこちらに質問させていただきました。

python

1#!/usr/local/bin/python 2# -*- coding: utf-8 -*- 3 4from __future__ import print_function 5 6import RPi.GPIO as GPIO 7import os 8import time 9import random 10import shlex 11import subprocess 12 13# Pin Number 14PIN = 19 15 16GPIO.setmode(GPIO.BCM) 17GPIO.setup(PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) 18last_pin_status = 0 19 20SONG_DIR = '/home/pi/Music/' 21SONG_LIST = ['song1.wav', 'song2.wav'] 22 23 24def play_song(): 25 song = random.choice(SONG_LIST) 26 song_path = os.path.join(SONG_DIR, song) 27 command = 'aplay %s' % (song_path) 28 print(command) 29 subprocess.Popen(shlex.split(command)) 30 31 32while True: 33 pin_status = GPIO.input(PIN) 34 if last_pin_status == 1 and pin_status == 0: 35 play_song() 36 37 last_pin_status = pin_status 38 time.sleep(0.1) 39 40GPIO.cleanup() 41 42

再度ボタンが押されたら

1 再生している音楽を停止する
2 リストの中からランダムで再生する

という2つの条件を入れれば良いと考えて、まずボタンが押されたら音楽を停止するために
if last_pin_status == 1 and pin_status == 0:
play_song()
の後に
if last_pin_status == 1 and pin_status == 0:
stop_song()
を入れました。

python

1 if last_pin_status == 1 and pin_status == 0: 2 play_song() 3 if last_pin_status == 1 and pin_status == 0: 4 stop_song()

こちらで試したところ、停止するどころか、重ねて音楽も再生されませんでした。

どこが問題なのでしょうか?


def stop_songを定義していませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ボタンの状態を保持しているステータスはありますが、
曲の再生状況を保持しているステータスが無いので現在の再生状況がわからないのが問題でしょうね。

Python、殆ど書いたことないんですけど、これでイケるんじゃないかと思います。
(一応確認ですが、def stop_song() は定義してあるんですよね?)

Python

1last_pin_status = 0 2is_playing = False # ← 再生ステータス(bool型) 3 4 : 5 6while True: 7 pin_status = GPIO.input(PIN) 8 9 if last_pin_status == 1 and pin_status == 0: 10 11 if is_playing: # 再生ステータスの検査 12 stop_song() 13 14 else: 15 play_song() 16 17 is_playing = not(is_playing) # 再生ステータスの反転 18 19 last_pin_status = pin_status 20 time.sleep(0.1) 21 22GPIO.cleanup()

投稿2017/08/31 14:43

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/08/31 14:48

subprocess.Popen() って、新しいプロセスを立ち上げるインターフェイスみたいなので、 旧コードの場合、ボタン押して離される度にどんどん複数の新プロセスが立ち上がってそのプロセスごとに曲を再生してしまう、って事でしょうね、きっと。
退会済みユーザー

退会済みユーザー

2017/08/31 14:54 編集

だから、stop_song() 内で、さっき立ち上げた別プロセスを終了する方法を知っているのかな?って事が次に問題になりそうな気がしています。
退会済みユーザー

退会済みユーザー

2017/09/01 00:35

夜中に起きたので書いた回答ですが、「停止するどころか、重ねて音楽も再生“されません”でした。」だったんですね。で、コードを読み直してみたら、当然そうなりますね。last_pin_status と pin_status の値が変わる前に play_song() して stop_song() していますから。 そうすると、最低限 stop_song() は記述され機能していることを期待してよさそうですね。
MasahikoHirata

2017/09/04 15:44

丁寧な回答お疲れ様です。非常に良いと考えます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問