カメラストリーム管理の詳細

カメラを切り替える際は、既存のストリームを完全に停止してから、新しいストリームを開始する必要があります。リソースの競合を防ぐため、段階的にストリームを解放します。
// カメラストリームを停止
async function stopCurrentStream() {
    if (currentStream) {
        // すべてのトラックを停止
        currentStream.getTracks().forEach(track => {
            track.stop();
        });
        // ビデオ要素のsrcObjectをクリア
        const video = document.getElementById('video');
        if (video && video.srcObject) {
            video.srcObject = null;
        }
        currentStream = null;
        // ストリームが完全に解放されるまで待機
        await new Promise(resolve => setTimeout(resolve, 100));
    }
}
1 トラックの停止: `getTracks()`でストリーム内のすべてのトラックを取得し、`stop()`を呼び出して停止します。
2 srcObjectのクリア: ビデオ要素の`srcObject`を`null`に設定します。これにより、ビデオ要素とストリームの関連付けを解除します。
3 待機時間: ストリームが完全に解放されるまで、100ミリ秒待機します。これにより、リソースの競合を防ぎます。
// 新しいストリームの開始
const constraints = {
    video: {
        width: { ideal: 640 },
        height: { ideal: 480 },
        deviceId: { exact: deviceId } // デバイスIDを指定
    }
};
const stream = await navigator.mediaDevices.getUserMedia(constraints);
currentStream = stream;
// 既存のsrcObjectをクリアしてから新しいストリームを設定
video.srcObject = null;
await new Promise(resolve => setTimeout(resolve, 50));
video.srcObject = stream;
重要なポイント: 新しいストリームを設定する前に、既存の`srcObject`を`null`にクリアし、50ミリ秒待機してから新しいストリームを設定します。これにより、確実にストリームが切り替わります。