Vue + WebRTC 实现音视频直播(附自定义播放器样式) (2)

参考https://www.jianshu.com/p/43957ee18f1a,查看Peer Connection建立连接的流程。
参考 https://developer.mozilla.org/zh-CN/docs/Web/API/RTCPeerConnection 查看RTCPeerConnection 支持的接口

createOffer() 方法: 主动与其他peer建立P2P连接,把自己的SDP信息整理好,通过signaling server转发给其他peer。
在上面的代码中,通过向后端发送POST请求,实现信令交换。

that.pc.addTransceiver("video"); that.pc.addTransceiver("audio");

指明同时接收音频和视频。

that.pc.ontrack = function(event){ }

该方法进行音视频的接收,使用接收到的数据创建video和audio元素。
只对pc状态进行监听无法监听到实际视频可以播放的状态,因此需要对video添加监听方法:

el.oncanplay = () => { that.isLoading = false; // 播放状态设置为true that.isPlaying = true; that.getVideoDuration(); };

在video可以播放时,才将loading状态取消,并开始获取video时长。

3.3 控制音视频的JS代码

获取视频播放时长方法:

getVideoDuration() { var video = document.getElementsByTagName("video")[0]; // 如果没有获取到视频元素 if (!video) { return; } let that = this; video.addEventListener("timeupdate", () => { that.currentTime = getTime(video.currentTime); }); var getTime = function (time) { let hour = Math.floor(time / 3600) < 10 ? "0" + Math.floor(time / 3600) : Math.floor(time / 3600); let min = Math.floor((time % 3600) / 60) < 10 ? "0" + Math.floor((time % 3600) / 60) : Math.floor((time % 3600) / 60); var sec = Math.floor(time % 60) < 10 ? "0" + Math.floor(time % 60) : Math.floor(time % 60); return hour + ":" + min + ":" + sec; }; }

控制音频/视频同步暂停的方法:

playOrPauseVideo() { var video = document.getElementsByTagName("video")[0]; var audio = document.getElementsByTagName("audio")[0]; if (this.isPlaying) { video.pause(); audio.pause(); } else { // audio video.play(); audio.play(); } this.isPlaying = !this.isPlaying; }

全屏方法

onClickFullScreen() { let dialogElement = document.getElementById("dialog-wrap"); dialogElement.webkitRequestFullScreen(); } 3.4 样式

样式部分较为简单,值得注意的有以下几点:

隐藏原有视频控制条,便于对控制条进行自定义

video::-webkit-media-controls { /* 去掉全屏时显示的自带控制条 */ display: none !important; }

扩大hover热区,视频下半部分(高度为400px部分)悬浮显示控制条
(不设置为全部部分是因为如果设置为全部部分,则全屏状态无法隐藏控制条)
以下完整样式表(scss):

$controlFontColor: rgb(136 141 150); $backgroundColor: rgba(0, 0, 0, 0.8); $height: 60px; .el-dialog .el-dialog__body { padding: 0 !important; margin-bottom: 0 !important; width: unset !important; } .video-onloading { min-height: 500px; background-color: $backgroundColor; span { width: 100%; display: block; line-height: 500px; text-align: center; color: $controlFontColor; i { margin-right: 5px; } i::before { font-size: 17px; } } } .cover { bottom: 0px; height: 300px; position: absolute; width: 100%; z-index: 2; &:hover, &:focus, &:focus-within { .controls { display: flex; } } } .controls { width: 100%; height: $height; line-height: $height; font-size: 15px; display: none; z-index: 2; background-color: $backgroundColor; color: $controlFontColor; position: absolute; bottom: 0 justify-content: space-between; & > [class^="el-icon-"] { &::before { font-size: 26px; line-height: $height; padding: 0 15px; cursor: pointer; } } .playStatus { width: 64px; height: $height; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } #currentTime { width: 140px; height: $height; text-align: center; } .control-resolution { line-height: $height; .el-input__inner { background: $backgroundColor; } .el-input { width: 95px; } input { border: none; font-size: 15px !important; color: $controlFontColor; &::-webkit-input-placeholder { color: $controlFontColor; } } } #fullScreen { width: 32px; height: 32px; position: relative; top: 16px; } } 总结

本次的前端业务WebRTC只做了浅显的了解和应用,只应用了接收流,还没有用到推流,WebRTC还有更多用法,比如实现实时视频通话、语音通话等,也许以后的业务中会用到,所以以这篇博客做一个入门记录~

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsxxjf.html