Open metroluffy opened 5 years ago
直播目前而言并非是一个很陌生的概念,也有很多应用场景,如在线教育。 在线教育的场景中讲师可以通过直播视频同时为用户讲课,将教室搬到了没有地域束缚的线上,同时在线听课人数可以千百倍于传统课堂。直播模式用户接受度强,将传统课堂上的反馈、交互、答疑搬到线上。 推流一般会选择更稳定的客户端进行直播,例如OBS等软件。但这类软件使用起来相对比较复杂,对硬件设备要求高,部分客户用起来成本较大,因此可以使用浏览器进行直播(Web 直播),在直播外亦可以将PPT课件使用、讨论、答疑这样的交互搬到浏览器内。目前能够进行推流的方案中,Flash算是性价比较高的方案,兼容性不错,实现起来也简单,基本如下: 1.从摄像头、麦克风获取媒体信息
// 初始化麦克风 _mic = Microphone.getMicrophone();// default microphone // 其他操作,如回音消除,需要硬件支持,Flash有API可以检测 // Microphone.getEnhancedMicrophone() // 设置编码器,这里要注意CDN分发平台对音频编码的支持程度 _mic.codec = "Speex"; // 一些附加的事件 // 初始化摄像头 _cam = Camera.getCamera(); // default camera // 其他操作,如设置带宽及质量、设置帧间隔等 // _cam.setKeyFrameInterval(num); //设置帧间隔 // 设置好解码器 _videoCodec = new H264VideoStreamSettings(); _videoCodec.setProfileLevel(H264Profile.BASELINE, "3"); // 一些附加的事件,如摄像头活动状态 // 可以把视频流挂到页面播放器里边去 player.attachCamera(_cam);
2.建立连接,推流到CDN
_outstream = new NetStream(_connection);// 建立流连接 // 将本地获取的音视频流挂上去 _outstream.attachCamera(_cam); _outstream.attachAudio(_mic); _outstream.videoStreamSettings = _videoCodec; _outstream.publish();
主要的代码如上,具体实现Adobe AS文档里也有。这里只是客户端推流到服务端,将内容下发到用户还是依赖于CDN分发平台的。 Flash的问题在于即将被停止维护,一些浏览器如FireFox更是不支持了,当然在国内应该还能蹦跶好久,360、QQ都是支持的。HTML5已经广受支持,因此可以使用一些新的API来做到一样的事情,具体步骤还是和上面一样。获取音视频流,可以通过WebRTC一系的MediaStream(aka getUserMedia) API完成,推流到服务端,可以使用WebSocket以二进制的形式传输,到了服务端就好办了,可以通过Ws下发,也可以用FFmpeg 以rtmp到分发平台下发,这里讲下后者: 1.获取音视频流,使用ws推流到服务端
// client.js const mediaSource = new MediaSource(); const constraints = { audio: { echoCancellation: {exact: true} }, video: { width: 1280, height: 720 } }; const stream = await navigator.mediaDevices.getUserMedia(constraints); ws = new WebSocket('ws://localhost:1080');// 建立 ws.addEventListener('open', e => { let options = { mimeType: 'video/webm;codecs=h264', // 编码格式 audioBitsPerSecond: 44100, // 44.1kHz videoBitsPerSecond: 3000000 // 3000k 画质 }; try { mediaRecorder = new MediaRecorder(stream, options);//进行媒体录制,把流变成二进制数据 } catch (e) { console.error('Exception while creating MediaRecorder:', e); return; } mediaRecorder.ondataavailable = () => { if (event.data && event.data.size > 0) { ws.send(event.data); } }; mediaRecorder.start(10); // collect 10ms of data });
2.ffmpeg rtmp推流
// server.js ws.on('connection', (ws) => { const ffmpeg = spawn('ffmpeg', [ // 从 stdin 中读入视频数据 '-i', '-', // 视频转码 // 由于视频已经是 H.264 编码,可以直接复制 // 若需要转码则填 libx264 '-vcodec', 'copy', // 音频转码 '-acodec', 'aac', // 输出为 flv 格式 '-f', 'flv', // RTMP 服务器 // RTMP_SERVER // 生成本地文件 'liveRecord.flv' ]); ws.on('message', (msg) => { // 收到时 msg 的类型是 Buffer ffmpeg.stdin.write(msg); }); });
ws有更稳定的socket.io,nodejs 也有node-fluent-ffmpeg,实现起来还是比较简单。缺点是这些API支持度不是很好,兼容性也有问题,毕竟不是用户都用Chrome、FireFox这样的浏览器。 搭建一个稳定的能承载从客户端收流的服务端成本也挺高的,因此可以把这个服务端用Electron打包起来以插件的方式放到客户端,从客户端直接推流到CDN。 就测试的demo而言,效果比flash好一些,flash推流延时基本是15-30s间,上述方案网络好的情况可以到8-10s。
但是。。。有了Electron还要浏览器上做文章?可以把这些一股脑的功能打包到一起,一个直播客户端由此诞生,相较于OBS等,可以符合产品设想,使用复杂度也可以降下来。缺点也挺明显,不是每个电脑都安装了。Electron的优点就不絮叨了,各有个的好处吧。
直播目前而言并非是一个很陌生的概念,也有很多应用场景,如在线教育。 在线教育的场景中讲师可以通过直播视频同时为用户讲课,将教室搬到了没有地域束缚的线上,同时在线听课人数可以千百倍于传统课堂。直播模式用户接受度强,将传统课堂上的反馈、交互、答疑搬到线上。 推流一般会选择更稳定的客户端进行直播,例如OBS等软件。但这类软件使用起来相对比较复杂,对硬件设备要求高,部分客户用起来成本较大,因此可以使用浏览器进行直播(Web 直播),在直播外亦可以将PPT课件使用、讨论、答疑这样的交互搬到浏览器内。目前能够进行推流的方案中,Flash算是性价比较高的方案,兼容性不错,实现起来也简单,基本如下: 1.从摄像头、麦克风获取媒体信息
2.建立连接,推流到CDN
主要的代码如上,具体实现Adobe AS文档里也有。这里只是客户端推流到服务端,将内容下发到用户还是依赖于CDN分发平台的。 Flash的问题在于即将被停止维护,一些浏览器如FireFox更是不支持了,当然在国内应该还能蹦跶好久,360、QQ都是支持的。HTML5已经广受支持,因此可以使用一些新的API来做到一样的事情,具体步骤还是和上面一样。获取音视频流,可以通过WebRTC一系的MediaStream(aka getUserMedia) API完成,推流到服务端,可以使用WebSocket以二进制的形式传输,到了服务端就好办了,可以通过Ws下发,也可以用FFmpeg 以rtmp到分发平台下发,这里讲下后者: 1.获取音视频流,使用ws推流到服务端
2.ffmpeg rtmp推流
ws有更稳定的socket.io,nodejs 也有node-fluent-ffmpeg,实现起来还是比较简单。缺点是这些API支持度不是很好,兼容性也有问题,毕竟不是用户都用Chrome、FireFox这样的浏览器。 搭建一个稳定的能承载从客户端收流的服务端成本也挺高的,因此可以把这个服务端用Electron打包起来以插件的方式放到客户端,从客户端直接推流到CDN。 就测试的demo而言,效果比flash好一些,flash推流延时基本是15-30s间,上述方案网络好的情况可以到8-10s。
但是。。。有了Electron还要浏览器上做文章?可以把这些一股脑的功能打包到一起,一个直播客户端由此诞生,相较于OBS等,可以符合产品设想,使用复杂度也可以降下来。缺点也挺明显,不是每个电脑都安装了。Electron的优点就不絮叨了,各有个的好处吧。