1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

iOS15.1 WebRTCを利用した通話中にカメラのオン・オフ切り替えでSafariが動かない

Last updated at Posted at 2021-12-03

現象

iOS 15.1 Safari (確認したところiOSのChromeでも) を利用して、WebRTCのコネクションを張ったあとの通話中などに、カメラのオン・オフを切り替えると、画面がリロードされ、ブラウザがクラッシュ(?)し、通話が切れるなどの不具合があります。

コードを変えてないにも関わらず、最新OSでのお問い合わせが多発したため、最初自分のコードを疑い、getUserMediaの実装方法が悪いのだと思い込んで、かなり調べても理由がわからなかったのですが、webkitのバグ報告にたどりつき、こちらの対応できました。

不具合内容はこちら
https://bugs.webkit.org/show_bug.cgi?id=232006

記事を読むと、H.264のコーデックを利用していると不具合がおきるらしく、コメントがあるように、他のビデオコーデックVP9を利用してみる事にしました。
現象、H.264を利用してWebRTCのサービス提供は不可能に近く、Appleのアップデートを待つしかない。

利用環境

NTTコミュニケーションズが提供している WebRTCのサービス「SkyWay」を利用しています。
SkyWayでは、通話のコーデックを、H.264、V8、V9の3種類から選択できます。
peer.callmediaConnection.answer時にパラメータとして、videoCodecが指定でき、指定していないと問題のH.264が、defaultになっています。

コードサンプル

<!DOCTYPE HTML>
<html lang="ja" prefix="og: http://ogp.me/ns#">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <script type="text/javascript" src="//cdn.webrtc.ecl.ntt.com/skyway-latest.js"></script>
</head>
<body>
<video id="remote_video" autoplay playsinline style="width:360px"></video><br>
<video id="my_video" muted="true" autoplay playsinline style="width: 360px; transform: scaleX(-1);"></video><br>
<button id="camera">camera off</button><br>
<div id="my_peer_id"></div>
<input type="text" id="peer_id"></input>
<button id="call" style="display: none">call</button><br>
</body>

<script>
    window.__SKYWAY_KEY__ = "SKYWAY_API_KEY";
    let localStream;
    navigator.mediaDevices.getUserMedia({audio: true, video: true})
    .then(function (stream) {
        localStream = stream;
        const localVideo = document.getElementById('my_video');
        localVideo.srcObject = stream;
        localVideo.play();
    });

    const camera_button = document.getElementById('camera');
    camera_button.addEventListener('click', () => {
        const enabled = localStream.getVideoTracks()[0].enabled;
        localStream.getVideoTracks()[0].enabled = !enabled;
        camera_button.innerHTML = enabled ? 'camera on' : 'camera off'; 
    });

    const call_button = document.getElementById('call');
    call_button.addEventListener('click', () => {
        const peer_id = document.getElementById('peer_id').value;
        let conn = peer.call(peer_id, localStream, {
            videoCodec: 'VP9',
        });
        
        conn.on("stream", (stream) => {
            const remoteVideo = document.getElementById('remote_video');
            remoteVideo.srcObject = stream;
            remoteVideo.play();
        });
    });
    
    const peer = new Peer({
        key: window.__SKYWAY_KEY__,
        debug: 0,
    });

    peer.on('open', () => {
        call_button.style.display = "block";
        const my_peer_id = document.getElementById('my_peer_id');
        my_peer_id.innerHTML = peer.id;
    });

    peer.on("call", (mediaConnection) => {
        mediaConnection.answer(localStream, {
            videoCodec: 'VP9',
        });

        mediaConnection.on("stream", (stream) => {
            const remoteVideo = document.getElementById('remote_video');
            remoteVideo.srcObject = stream;
            remoteVideo.play();
        });
    });
</script>
</html>
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?