golang-webrtc 初体验

golang-webrtc 初体验

本站专注于rtc、ai领域,为此我们会持续更新各类webrtc服务,解析webrtc源码,理解webrtc原理,分享给各个学习的同志。

我们选择ion-sfu


git clone https://github.com/ionorg/ion-sfu.git

下载git,下载webrtc项目代码

我们启动json-rpc方式

执行


go build ./cmd/signal/json-rpc/main.go && ./main -c config.toml

启动服务后,我们需要p2p进行连接

这里我们得写前端js服务。

创建webrtc-peerConnection 对象


const peerConnection = new RTCPeerConnection({
  iceServers: [
    {
      urls: 'stun:stun.l.google.com:19302',
    },
    {
      urls: 'turn:numb.viagenie.ca',
      username: 'user@example.org',
      credential: 'password',
    },
  ],
});

peerConnection.addEventListener('icecandidate', (event) => {
  // 发送ICE候选项到ion-sfu服务器
  if (event.candidate !== null) {
    const candidateMessage = {
      type: 'candidate',
      candidate: event.candidate,
    };
    socket.send(JSON.stringify(candidateMessage));
  }
});


加入房间

将PeerConnection加入到指定的房间中,并通过MediaStreamTrack API创建本地音视频流。然后,将本地音视频流添加到PeerConnection中。



// 加入房间
const offerMessage = {
  type: 'join',
  room: 'myroom',
};
socket.send(JSON.stringify(offerMessage));

// 创建音视频流
const localStream = await navigator.mediaDevices.getUserMedia({
  audio: true,
  video: true,
});

// 将音视频流添加到PeerConnection中
localStream.getTracks().forEach((track) => {
  peerConnection.addTrack(track, localStream);
});


然后接收远程视频流

通过ion-sfu服务器从其他客户端接收音视频流,并使用WebRTC API将其添加到本地PeerConnection中。


socket.addEventListener('message', async (event) => {
  const message = JSON.parse(event.data);

  switch (message.type) {
    case 'offer':
      // 处理SDP协商
      const offer = new RTCSessionDescription(message.sdp);
      await peerConnection.setRemoteDescription(offer);

      // 创建应答并发送给ion-sfu服务器
      const answer = await peerConnection.createAnswer();
      await peerConnection.setLocalDescription(answer);

      const answerMessage = {
        type: 'answer',
        sdp: answer.sdp,
      };
      socket.send(JSON.stringify(answerMessage));
      break;

    case 'candidate':
      // 处理ICE候选项
      const candidate = new RTCIceCandidate(message.candidate);
      await peerConnection.addIceCandidate(candidate);
      break;

    case 'join':
      // 处理新的客户端加入房间
      break;

    case 'leave':
      // 处理其他客户端离开房间
      break;
    
    case 'publish':
      // 处理其他客户端发布音视频流
      const remoteStream = new MediaStream();
      message.tracks.forEach((trackId) => {
        const remoteTrack = peerConnection.getReceiverById(trackId).track;
        remoteStream.addTrack(remoteTrack);
      });
      
      // 将远程音视频流添加到HTML video元素中
      const remoteVideo = document.createElement('video');
      remoteVideo.srcObject = remoteStream;
      remoteVideo.autoplay = true;
      document.body.appendChild(remoteVideo);
      break;

    default:
      break;
  }
});



在实际应用中,还需要进行其他设置和安全性措施,如限制访问、添加SSL证书、配置媒体流加密等。因此,建议根据具体需求分配恰当的特权,并限制不必要的访问