以前、ESP32を使ってGoogle Home Miniに音声を出力させましたので、今回は同じことがRaspberry Pi Pico Wでもできないかと試行錯誤を重ねた結果、無事に音声を出力させることができました。その過程を備忘録としてまとめておきます。
1.接続図
2.Google Home miniにMP3を再生させるコード
import ssl
import json
import socket
import struct
import network
import time
import machine
from machine import Pin
def calc_variant(value):
byte_list = []
while value > 0x7F:
byte_list += [value & 0x7F | 0x80]
value >>= 7
return bytes(byte_list + [value])
def play_url(url, host):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, 15, 1)
sock.settimeout(30)
sock.connect((host, 8009))
sock = ssl.wrap_socket(sock)
sock.write(b'\x00\x00\x017\x08\x00\x12\x08sender-0\x1a\nreceiver-0"(urn:x-cast:com.google.cast.tp.connection(\x002\xf0\x01{"type": "CONNECT", "origin": {}, "userAgent": "PyChromecast", "senderInfo": {"sdkType": 2, "version": "15.605.1.3", "browserVersion": "44.0.2403.30", "platform": 4, "systemVersion": "Macintosh; Intel Mac OS X10_10_3", "connectionType": 1}}')
sock.write(b'\x00\x00\x00g\x08\x00\x12\x08sender-0\x1a\nreceiver-0"#urn:x-cast:com.google.cast.receiver(\x002&{"type": "GET_STATUS", "requestId": 1}')
sock.write(b'\x00\x00\x00e\x08\x00\x12\x08sender-0\x1a\nreceiver-0"\'urn:x-cast:com.google.cast.tp.heartbeat(\x002 {"type": "PING", "requestId": 2}')
sock.read(struct.unpack(">I", sock.read(4))[0])
sock.read(struct.unpack(">I", sock.read(4))[0])
sock.write(b'\x00\x00\x00x\x08\x00\x12\x08sender-0\x1a\nreceiver-0"#urn:x-cast:com.google.cast.receiver(\x0027{"type": "LAUNCH", "appId": "CC1AD845", "requestId": 3}')
transport_id = sock.read(struct.unpack(">I", sock.read(4))[0]).split(b'"transportId"')[1].split(b'"')[1]
sock.write(b'\x00\x00\x01Q\x08\x00\x12\x08sender-0\x1a$%s"(urn:x-cast:com.google.cast.tp.connection(\x002\xf0\x01{"type": "CONNECT", "origin": {}, "userAgent": "PyChromecast", "senderInfo": {"sdkType": 2, "version": "15.605.1.3", "browserVersion": "44.0.2403.30", "platform": 4, "systemVersion": "Macintosh; Intel Mac OS X10_10_3", "connectionType": 1}}' % transport_id)
sock.write(b'\x00\x00\x00~\x08\x00\x12\x08sender-0\x1a$%s" urn:x-cast:com.google.cast.media(\x002&{"type": "GET_STATUS", "requestId": 4}' % transport_id)
payload = json.dumps({
"media": {
"contentId": url,
"streamType": "BUFFERED",
"contentType": "audio/mp3",
"metadata": {}
},
"type": "LOAD",
"autoplay": True,
"customData": {},
"requestId": 5,
"sessionId": transport_id.decode()
})
msg = (b'\x08\x00\x12\x08sender-0\x1a$%s" urn:x-cast:com.google.cast.media(\x002' % transport_id) + calc_variant(len(payload)) + payload.encode()
sock.write(struct.pack(">I", len(msg)) + msg)
sock.read(struct.unpack(">I", sock.read(4))[0])
sock.read(struct.unpack(">I", sock.read(4))[0])
sock.read(struct.unpack(">I", sock.read(4))[0])
sock.close()
# Wi-Fi 接続
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("あなたのSSID", "あなたのパスワード")
while not wlan.isconnected() and wlan.status() >= 0:
time.sleep(1)
# ボタンとLED設定
button16 = Pin(16, Pin.IN, Pin.PULL_UP)
button17 = Pin(17, Pin.IN, Pin.PULL_UP)
button18 = Pin(18, Pin.IN, Pin.PULL_UP)
button19 = Pin(19, Pin.IN, Pin.PULL_UP)
led = Pin('LED', Pin.OUT)
playing = False
while True:
if button16.value() == 0 and not playing:
playing = True
led.on()
play_url('https://nyanpass.com/nyanpass.mp3', 'Google Home miniのIPアドレス')
led.off()
playing = False
elif button17.value() == 0 and not playing:
playing = True
led.on()
play_url('再生したいMP3のアドレス', 'Google Home miniのIPアドレス')
led.off()
playing = False
elif button18.value() == 0 and not playing:
playing = True
led.on()
play_url('再生したいMP3のアドレス', 'Google Home miniのIPアドレス')
led.off()
playing = False
elif button19.value() == 0 and not playing:
playing = True
led.on()
play_url('再生したいMP3のアドレス', 'Google Home miniのIPアドレス')
led.off()
playing = False
time.sleep(0.1)
3.Google Home miniにTextを喋らせるコード
ソースコードはNoteにて有料で公開します('ω')
コメント
コメントを投稿