通过WebRTC简单实现媒体共享

发布时间 2023-11-10 11:17:52作者: jiang_xin_yu

通过WebRTC简单实现媒体共享

媒体协商

  1. 在设置本地描述符(offer/answer)前,我们总是需要将媒体添加到连接中,只有这样在描述符中才能包含需要共享的媒体信息,除非你不需要共享媒体。
  2. 在实际应用中,我们通常没办法让两个客户端直接通信,进行媒体协商。因此我们通常需要一个双方都可以访问的中间服务器交换彼此的属性描述符这个服务器称之为信令服务器。建议使用websocket。
 //以下代码并没用实现如何接收和发送描述符,这里只展示了接收到对应信息后应该如何设置。接收和发送属性描述符应该由具体业务决定
const pc = new RTCPeerConnection();

  //这里是共享屏幕的方法
    function screenSharing(){
        navigator.mediaDevices.getDisplayMedia({
                video: true,
                audio: true
            }).then((stream) => {
                //将本地流添加到连接器中
                stream.getTracks().forEach((track) => {
                    pc.addTrack(track, stream);
                });
                //createOffer
                pc.createOffer()
                    .then(async (desc) => {
                        //设置本地描述
                        await this.pc.setLocalDescription(desc);
                        //发送offer
                        //发送offer代码省略,你可以使用如何方式将offer发送到另一个客户端

                    }).catch((err) => {
                        //这里是错误处理
                    });

            }).catch((err) => {
                //这里是错误处理
            });
    }

            //接送到远程的answer后调用
            function setRemoteAnswer(Answer){
                  pc.setRemoteDescription(new RTCSessionDescription(Answer));
            }
            //接收到远程的offer后调用
            function setRemoteOffer(Offer) {
                pc.setRemoteDescription(new RTCSessionDescription(data.desc))
                            .then(() => {
                                pc.createAnswer().then((desc) => {
                                   pc.setLocalDescription(desc)
                                        .then(() => {
                                           //这里是发送answer应答  
                                           //发送answer代码省略,你可以使用如何方式将answer发送回offer发送的客户端
                                        })
                                })
                            })
            }

            //创建pc的实例后调用
            function setRemoteMedia(){
                pc.ontrack = (e) => {
                    //这里是处理接收的远程媒体。这个示例表示将媒体流在id为remoteVideo 的video元素中播放
                    //在用户没有和页面有互操作前,可能无法直接播放
                    let video = document.getElementById("remoteVideo") as HTMLVideoElement;
                    video.srcObject = e.streams[0];
                    video.onloadedmetadata = (e) => {
                        video.play();
                    }
                }

            }

            //创建pc的实例后调用
            function setRemoteMedia(){
               pc.onicecandidate = (e: RTCPeerConnectionIceEvent) => {
                    //这里会在协商完成后发送ice候选
                    //发送ice代码省略
                }

            }
            //收到ice候选后的调用
            function SetRemoteIce(candidate){
                pc.addIceCandidate(new RTCIceCandidate(candidate))
                            .then(() => {
                              //这里成功设置了ice候选
                 })
            }

更详细信息可参考一下文档

  1. 信令与视频通话
  2. RTCPeerConnection