WebRTC屏幕共享/线上教学 小Dome

完整代码 直接复制html打开使用
实现本地屏幕 和远端屏幕

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>123</title>
</head>
<body>
<div class="video-container">
    <h2>本地捕获的屏幕共享流</h2>
    <video id="srcVideo" playsinline controls muted loop class="srcVideo">

    </video>
</div>
<div class="video-container">
    <h2>远端传输过来的屏幕共享流渲染</h2>
    <video id="shareStreamVideo" playsinline autoplay muted class="shareStreamVideo"></video>
</div>


</body>

<script>
    const srcVideo = document.getElementById('srcVideo');
    const shareStreamVideo = document.getElementById('shareStreamVideo');

    let srcStream;
    let shareStream;
    // 定义捕获流的参数
    let displayMediaOptions = {
        video: {
            width: {max: 1280},
            height: {max: 720},
            frameRate: {ideal: 15}
        }
    }
    /*
    捕获屏幕流可以使用navigator.mediaDevices.getDisplayMedia(displayMediaOptions)方法获取,
    此方法为异步方法,会将屏幕流包装成一个Promise对象,解析Promise后会返回一个MediaStream对象,
    我们可以从这个对象中取出视频或者音频Track进行流传输
     */
    navigator.mediaDevices.getDisplayMedia({ video: true }).then(stream => {
        srcStream = stream;
        srcVideo.srcObject = stream;
        srcVideo.play();
        // 传输流
        call();
    });

    function setVideoTrackContentHints(stream, hint) {
        const track = stream.getVideoTracks()[0];
        if ('contentHint' in track) {
            track.contentHint = hint;
            if (track.contentHint !== hint) {
                console.log('Invalid video track contentHint: \'' + hint + '\'');
            }
        } else {
            console.log('MediaStreamTrack contentHint attribute not supported');

        }
    }

    function call() {
        // 克隆流
        shareStream = srcStream.clone();
        // "detail"设置清晰度优先(也可使用"text"),如果需要设置流畅度优先,使用"motion"
        setVideoTrackContentHints(shareStream, 'detail');
        // 建立PeerConnection
        establishPC(shareStreamVideo, shareStream);
    }

    function establishPC(videoTag, stream) {
        // 创建两个PeerConnection模拟两个客户端,pc1相当于本地,pc2相当于远端
        const pc1 = new RTCPeerConnection(null);
        const pc2 = new RTCPeerConnection(null);
        pc1.onicecandidate = e => {
            // 可以理解为通知pc2连接pc1的地址
            onIceCandidate(pc1, pc2, e);
        };
        // 可以理解为通知pc1接pc2地址
        pc2.onicecandidate = e => {
            onIceCandidate(pc2, pc1, e);
        };
        //  将需要传输的流添加给PeerConnection
        stream.getTracks().forEach(track => pc1.addTrack(track, stream));
        // 设置offer和answer,可理解为通知两边另一边的编解码等媒体信息
        pc1.createOffer({ video: true }).then(desc => {
                pc1.setLocalDescription(desc)
                    .then(() => pc2.setRemoteDescription(desc))
                    .then(() => pc2.createAnswer())
                    .then(answerDesc => onCreateAnswerSuccess(pc1, pc2, answerDesc))
                    .catch(onSetSessionDescriptionError);
            })
            .catch(e => console.log('Failed to create session description: ' + e.toString()));
        //  远端接收到流,交给video去播放
        pc2.ontrack = event => {
            if (videoTag.srcObject !== event.streams[0]) {
                videoTag.srcObject = event.streams[0];
            }
        };

    }

    function onSetSessionDescriptionError(error) {
        console.log('Failed to set session description: ' + error.toString());
    }

    function onCreateAnswerSuccess(pc1, pc2, desc) {
        pc2.setLocalDescription(desc)
            .then(() => pc1.setRemoteDescription(desc))
            .catch(onSetSessionDescriptionError);
    }

    function onIceCandidate(pc, otherPc, event) {
        otherPc.addIceCandidate(event.candidate);
    }

</script>

</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值