关于srs请看我之前的博客,SRS实现网页和手机端简单直播。
与之不同的是,浏览器推流需要使用werbrtc,因此只需要按srs官网设置即可,WebRTC | SRS (ossrs.net)。回到正题...
一.页面搭建
b站web直播页面是通过video标签元素实现,但是video并不能同时将摄像头、麦克风、屏幕共享等同时出现出来,所以猜测是用的canvas,将不同素材通过画布出现,同时把canvas的放逐到video上。
1.我们要实现这个画布,首先需要使用webrtc(没有接触过的去看官网WebRTC API),在webrtc中,MediaDevices接口提供访问毗连媒体输入的设备,如照相机和麦克风,以及屏幕共享等。它可以使你取得任何硬件资源的媒体数据。
enumerateDevices() 哀求一个可用的媒体输入和输出设备的列表。
getDisplayMedia() 方法提供授权捕捉展示的内容或部门内容(如一个窗口)。
getUserMedia() 会提示用户使用媒体输入的许可,媒体输入会产生一个MediaStream,内里包含了哀求的媒体范例的轨道。此流可以包含一个视频轨道、一个音频轨道,也大概是其他轨道范例。
2.使用canvas标签,npm下载Fabric.js,Fabric.js 简化了很多 Canvas 里的概念,Fabric.js 语法更加简单易用,而且还提供了很多交互类的 api,更重要的是fabric.js操纵canvas自带拖拽拉伸旋转效果。
首先通过fabric.canvas生成一个画布,但由于屏幕共享和摄像头都是视频类,所以可以通过document.createElement('video')创建video元素,并将获取到的MediaStream赋给video.srcObject,之后通过fabric.Image(video),将video中每一帧画面生成,同时还可以设置生成好的画面的宽高以及在哪个位置出现。(其他属性请到Fabric.js官网查看)之后通过fabric.canvas.add即可添加到画布中观看。
- var canvasDom = new fabric.Image(videoEl, {
- top: 0,
- left: 0,
- width,
- height,
- objectCaching: false
- });
复制代码 以此类推,实现以下素材的添加,同时在画布中显示(示例图片中包含摄像头、窗口、图片)
3.生成好画面后,需要将这添加的素材生存起来,并且可以删改。关于这个问题,可以新建数据范例tracks:[],存放素材数据。如下(要根据现实环境更改):
- const mediaVideoTrack = {
- id: id,
- audio: 1,//是否开启音频流
- video: 1,//是否开启视频流
- mediaName: that.mediaName,//素材名称
- type: 'Media',//素材类型(有media、text等)
- track: undefined,//轨道
- trackid: undefined,//轨道id
- stream: undefined,//媒体流
- streamid: undefined,//媒体流id
- canvasDom:canvasDom,//fabric.Image元素
- videoEl:videoEl,//video元素
- volume:80,//音量
- hidden: false,//是否隐藏
- muted: false,//是否静音播放
- scaleInfo: {},//缩放比例
- };
复制代码 实现如下,可以隐藏或出现某个素材,修改仅限修改名称,不可修改内容,删除需要把fabric.canvas中与tracks中类似的删除。
二.推流和拉流功能
推拉流功能是使用WebRTC+SRS实现的,webrtc和srs具体原理不在这里赘述,详情请查百度。
由于SRS中自带简单的信令服务器,所以在使用WebRTC中的RTCPeerConnection时只需交换sdp,设置setLocalDescription和setRemoteDescription,之后按照srs提供的api进行sdp交换来实现媒体流的推送。代码示例(该代码借鉴csdn某大佬(忘记是哪个了 |