WebRTC播放组件之 srs.sdk.js 利用与详述

打印 上一主题 下一主题

主题 534|帖子 534|积分 1602

1、简介

webrtc流媒体的播放,本质上也是基于建立端到端的RTC连接、接收推送过来的视频流数据的过程。webrtc流地址本质上就具有很强的规则性,此中包含信令服务器地址、基本参数等。
SRS(Simple Real-Time Media Server)是一个强大的开源的流媒体服务器, webrtcs视频流的播放自己就是一个订阅(播放)的过程,因此 SRS 源码中自然包含播放的代码,即 srs.sdk.js
srs.sdk.js 是基于 SRS 实时视频服务器、对欣赏器支持的 WebRTC 基础功能的封装。


  • github 地址
2、利用

2.1、引入

   

  • 从官网下载好 srs.sdk.js 文件,将此文件放入项目中的静态文件夹;
  • 通过 CDN 方式引入,即 例: <script src="./static/webrtc/srs.sdk.js"></script>
  • 暴露出实现函数 SrsRtcPlayerAsync 
  2.2、函数说明


  • 通过构造函数 SrsRtcPlayerAsync 实例化出对象(本文用 sdk 定义),
  • 对象的属性:pc -- RTCPeerConnection() 实例化对象;stream -- 实例化MediaStream()对象
  • 对象的方法:play() -- 初始化播放的代码;close() -- 关闭播放的方法
2.3、基本实当代码

下面是基本的实当代码,在 vue 中的写法
  1.     <video
  2.         width="100%"
  3.         height="100%"
  4.         autoplay
  5.         muted
  6.         class="screen-full-db"
  7.         :id="`webrtc-video-${uid}`"
  8.     ></video>
复制代码
  1.             // 获取实例化对象,参数传入失败回调函数
  2.             this.sdk = new SrsRtcPlayerAsync(this.sdkInitError);
  3.             // 监听 webrtc 建立状态
  4.             this.sdk.pc.addEventListener("iceconnectionstatechange", data => {
  5.                 if (data.target.iceConnectionState == "disconnected") {
  6.                     this.$emit("disconnected");
  7.                 }
  8.             });
  9.             // 将获取的视频流 给 video 的 srcObject
  10.             $(`#webrtc-video-${this.uid}`).prop("srcObject", this.sdk.stream);
  11.             // 初始化代码
  12.             try {
  13.                 // play() 初始化播放代码,参数:webrtc流地址
  14.                 this.sdk.play(this.src).then(
  15.                     res => {}
  16.                 )
  17.             } catch (error) {
  18.                 // 错误回调
  19.             }
  20.             // 关闭播放器
  21.             this.sdk.close();
复制代码
再简化一下:
  1.         let sdk = new SrsRtcPlayerAsync(sdkInitErrorCallback);
  2.         $(`#webrtc-video-id`).prop("srcObject", sdk.stream);
  3.         sdk.play(src)
复制代码
基本实现就基本完成了,十分的简单轻便。

3、源码简述

   这一部分会源码进行基本的介绍,源码也是十分的普通易懂。
   3.1、基本布局

  1.         function SrsRtcPlayerAsync() {
  2.             var self = {};
  3.             // Close the player.
  4.             self.play = async function (url) { }
  5.             // The callback when got remote track.
  6.             // Note that the onaddstream is deprecated, @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/onaddstream
  7.             self.ontrack = function (event) {}
  8.             // Internal APIs.
  9.             self.__internal = {}
  10.             self.pc = new RTCPeerConnection(null);
  11.             // Create a stream to add track to the stream, @see https://webrtc.org/getting-started/remote-streams
  12.             self.stream = new MediaStream();
  13.             // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ontrack
  14.             self.pc.ontrack = function (event) {}
  15.             return self;
  16.         }
复制代码
  函数的基本布局没什么好讲的,重要留意一个小tip,通过实例化去 new 这个函数,函数有返回值且为引用类型,实例化对象就是返回的对象。
  3.2、play 方法

重要看 play 方法具体怎样实现:
  1.             self.play = async function (url) {
  2.                 var conf = self.__internal.prepareUrl(url);
  3.                 self.pc.addTransceiver("audio", { direction: "recvonly" });
  4.                 self.pc.addTransceiver("video", { direction: "recvonly" });
  5.                 //self.pc.addTransceiver("video", {direction: "recvonly"});
  6.                 //self.pc.addTransceiver("audio", {direction: "recvonly"});
  7.                 var offer = await self.pc.createOffer();
  8.                 await self.pc.setLocalDescription(offer);
  9.                 var session = await new Promise(function (resolve, reject) {
  10.                     // @see https://github.com/rtcdn/rtcdn-draft
  11.                     var data = {
  12.                         api: conf.apiUrl, tid: conf.tid, streamurl: conf.streamUrl,
  13.                         clientip: null, sdp: offer.sdp
  14.                     };
  15.                     console.log("Generated offer: ", data);
  16.                     const xhr = new XMLHttpRequest();
  17.                     xhr.onload = function () {
  18.                         if (xhr.readyState !== xhr.DONE) return;
  19.                         if (xhr.status !== 200 && xhr.status !== 201) return reject(xhr);
  20.                         const data = JSON.parse(xhr.responseText);
  21.                         console.log("Got answer: ", data);
  22.                         return data.code ? reject(xhr) : resolve(data);
  23.                     }
  24.                     xhr.open('POST', conf.apiUrl, true);
  25.                     xhr.setRequestHeader('Content-type', 'application/json');
  26.                     xhr.send(JSON.stringify(data));
  27.                 });
  28.                 await self.pc.setRemoteDescription(
  29.                     new RTCSessionDescription({ type: 'answer', sdp: session.sdp })
  30.                 );
  31.                 session.simulator = conf.schema + '//' + conf.urlObject.server + ':' + conf.port + '/rtc/v1/nack/';
  32.                 return session;
  33.             };
复制代码

  • 一开始调用 __internal 对象中 prepareUrl 方法,通过 webrtc 流地址分析得到信令服务器URL地址,从而完成媒体协商。前面说过webrtc的流地址是规则性很强的,在SRS的源码内里体现了。这里如果信令服务器不是通过webrtc地址获取的,可以自行在代码中修改。
  • 获取当地SDP,开始媒体协商请求,拿到远程SDP,并设置。
  • 返回SDP信息。
3.3、ontrack

  1.             self.pc.ontrack = function (event) {
  2.                 if (self.ontrack) {
  3.                     self.ontrack(event);
  4.                 }
  5.             };
  6.             self.ontrack = function (event) {
  7.                 // https://webrtc.org/getting-started/remote-streams
  8.                 self.stream.addTrack(event.track);
  9.             };
复制代码
pc.ontrack 回调事件监听媒体流数据,并添加track到stream。
webrtc 播放还可以利用 jswebrtc.js 库,可看:WebRTC播放组件之 jswebrtc 利用与详述

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

海哥

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表