<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>音楽プレイヤー</title>
<link rel="stylesheet" href="music_player.css">
</head>
<body>
<div class="container">
<h1>音楽プレイヤー</h1>
<p id="nowPlaying">選択された曲: なし</p>
<button id="initBtn">🎵 音楽再生を有効にする</button>
<audio id="audioPlayer" controls></audio>
</div>
<script>
const audioPlayer = document.getElementById("audioPlayer");
const nowPlaying = document.getElementById("nowPlaying");
const initBtn = document.getElementById("initBtn");
const sePlayer = new Audio();
// ★★★ 音楽サーバーのIPアドレスは、あなたのPCのIPに合わせてください ★★★
const musicServerHost = 'http://192.168.1.138:8890';
// ★★★ 司令塔サーバーのIPはあなたの環境に合わせてください ★★★
const conn = new WebSocket('ws://172.17.54.116:8804/');
let currentFileUrl = "";
const silentMp3 = "data:audio/mp3;base64,//uQxAAAAAAAAAAAAAAAAAAAAAAAWGluZwAAAA8AAAACAAACcQCA//////////8AAA==";
initBtn.addEventListener("click", () => {
audioPlayer.src = silentMp3;
audioPlayer.play().then(() => {
console.log("Autoplayが許可されました");
audioPlayer.pause(); audioPlayer.src = "";
initBtn.disabled = true; initBtn.style.display = "none";
}).catch(err => console.error("初期再生失敗", err));
});
conn.onmessage = ev => {
let msg;
try { msg = JSON.parse(ev.data); } catch { return; }
switch (msg.type) {
case "select":
currentFileUrl = msg.url;
audioPlayer.src = currentFileUrl;
nowPlaying.textContent = "曲選択中...";
console.log("曲読み込み:", currentFileUrl);
break;
case "play":
if (!currentFileUrl) return;
audioPlayer.play().catch(err => console.error("再生失敗:", err));
nowPlaying.textContent = "▶ 再生中...";
break;
case "pause":
audioPlayer.pause();
nowPlaying.textContent = "⏸ 一時停止中";
break;
case "stop":
audioPlayer.pause();
audioPlayer.currentTime = 0;
nowPlaying.textContent = "⏹ 停止中";
break;
case "announce":
if (!audioPlayer.paused) {
audioPlayer.pause();
console.log("挙手があったため再生を一時停止しました。");
}
if (msg.queue && msg.queue.length > 0) {
const firstRaiser = msg.queue[0];
nowPlaying.innerHTML = `🤚<br>${firstRaiser.group} の ${firstRaiser.name}さんの回答です!`;
}
break;
case "correct":
audioPlayer.pause();
audioPlayer.currentTime = 0;
sePlayer.src = `${musicServerHost}/SE/correct.mp3`;
sePlayer.play();
const rawFilename = decodeURIComponent(msg.answer);
const cleanTitle = rawFilename.replace(/^\d+_/, '').replace(/\.\w+$/, '');
nowPlaying.innerHTML = `⭕ 正解!<br>答え: ${cleanTitle}`;
break;
case "incorrect":
audioPlayer.pause();
sePlayer.src = `${musicServerHost}/SE/incorrect.mp3`;
sePlayer.play();
nowPlaying.textContent = `❌ 不正解...`;
break;
// ▼▼▼【追加】曲名提示の処理 ▼▼▼
case "show_answer":
audioPlayer.pause();
audioPlayer.currentTime = 0;
const answerFilename = decodeURIComponent(msg.answer);
const answerTitle = answerFilename.replace(/^\d+_/, '').replace(/\.\w+$/, '');
nowPlaying.innerHTML = `💡 正解は...<br>${answerTitle}`;
break;
}
};
conn.onopen = () => console.log("WebSocket 接続成功!");
conn.onerror = (e) => console.error("WebSocket エラー:", e);
conn.onclose = () => {
nowPlaying.textContent = "サーバーとの接続が切れました";
console.log("WebSocket 切断");
};
</script>
</body>
</html>