JusTalk_compleate / static /register_record.js
buletomato25
adduser
f742eba
raw
history blame
4.72 kB
let mediaRecorder;
let audioChunks = [];
let userCount = 0; // 追加されたメンバー数を保持
let isRecording = false; // 録音中かどうかを判定するフラグ
let currentRecordingButton = null; // 現在録音中のボタンを保持
let userNames = [];
function toggleRecording(button) {
button.classList.toggle("recording");
}
async function startRecording(button) {
if (isRecording && currentRecordingButton !== button) return; // 他の人が録音中なら何もしない
isRecording = true; // 録音中に設定
currentRecordingButton = button; // 録音中のボタンを記録
try {
const stream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
mediaRecorder = new MediaRecorder(stream, { mimeType: "audio/webm" });
audioChunks = [];
mediaRecorder.ondataavailable = (e) => audioChunks.push(e.data);
mediaRecorder.onstop = () => {
sendAudioChunks(audioChunks, button); // ボタン情報を渡す
audioChunks = [];
isRecording = false; // 録音停止後はフラグを戻す
currentRecordingButton = null; // 録音ボタンを解除
};
mediaRecorder.start();
toggleRecording(button);
} catch (err) {
console.error("マイクアクセスに失敗しました:", err);
isRecording = false; // エラー発生時もフラグを戻す
currentRecordingButton = null;
}
}
function stopRecording(button) {
if (!isRecording) return; // 録音中でない場合は停止しない
mediaRecorder.stop();
toggleRecording(button);
}
function handleRecording(e) {
const button = e.target.closest(".record-button");
if (button) {
if (isRecording && currentRecordingButton !== button) {
// 他の人が録音中なら反応しない
return;
}
if (mediaRecorder && mediaRecorder.state === "recording") {
stopRecording(button);
} else {
startRecording(button);
}
}
}
function sendAudioChunks(chunks, button) {
// 引数に button を追加
const audioBlob = new Blob(chunks, { type: "audio/wav" });
const reader = new FileReader();
reader.onloadend = () => {
const base64String = reader.result.split(",")[1]; // Base64エンコードされた音声データ
const form = button.closest("form");
const nameInput = form.querySelector('input[name="name"]');
const name = nameInput ? nameInput.value : "unknown"; // 名前がない
fetch("/upload_base_audio", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ audio_data: base64String, name: name }),
})
.then((response) => response.json())
.then((data) => {
// エラー処理のみ残す
if (data.error) {
alert("エラー: " + data.error);
console.error(data.details);
}
// 成功時の処理(ボタンの有効化など)
else {
console.log("音声データ送信成功:", data);
userNames.push(name);
// 必要に応じて、ここでUIの変更(ボタンの有効化など)を行う
// 例: button.disabled = true; // 送信ボタンを無効化
// 例: button.classList.remove("recording"); //録音中のスタイルを解除
}
})
.catch((error) => {
console.error("エラー:", error);
});
};
reader.readAsDataURL(audioBlob);
}
document.getElementById("add-btn").addEventListener("click", () => {
const newItem = document.createElement("div");
newItem.className = "flex items-center gap-3 flex-wrap";
newItem.innerHTML = `
<form
action="/submit"
method="POST"
class="flex items-center space-x-2 w-full sm:w-auto"
onsubmit="event.preventDefault();"
>
<input
type="text"
name="name"
placeholder="名前を入力"
class="flex-1 px-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 bg-gray-700 text-white"
/>
<button type="button" class="record-button" aria-label="音声録音開始">
<div class="record-icon"></div>
</button>
</form>
`;
newItem.addEventListener("click", handleRecording);
document.getElementById("people-list").appendChild(newItem);
userCount++; // 新しいメンバーを追加するたびにカウントを増やす
});