接上篇文章中的使video标签可以播放WebRTC格式视频,但没有具体说明该如何获取WebRTC的MediaStream对象,以及如何和后端去进行配合来处理播放,下面是详细的步骤。
-
获取用户媒体权限 :首先,我们需要使用
navigator.mediaDevices.getUserMedia()
方法请求用户的媒体设备权限。这个方法返回一个Promise
,它解析为一个MediaStream
对象。 -
处理
Promise
:一旦用户授予了权限,Promise
将被解析,并且你可以使用返回的MediaStream
对象。 -
注意事项 :在我们使用
navigator.mediaDevices.getUserMedia()
方法是会遇到navigator.mediaDevices
为undefined,这是由于浏览器的安全策略导致,目前只支持以下三种情况
- 地址为localhost:// 访问时
- 地址为https:// 时
- 为文件访问file:///
详细内容可以参考 MediaDevices.getUserMedia() - Web API 接口参考 | MDN
具体解决方法为:
- 创建HTTPS服务器,用HTTPS协议的方式发送请求。(需要申请证书)
- 修改chrome浏览器的安全策略:
a. 在chrome浏览器的地址栏中输入: chrome://flags/#unsafely-treat-insecure-origin-as-secure,将该 flag 切换成 enable 状态;
b. 在输入框中填写需要开启的域名或地址,如果有多个,则以逗号分隔;
c. 重启浏览器后生效。
如果有其他更好的解决办法,欢迎补充。
此时,我们就可以通过以下方式获取MediaStream对象
javascript
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(function(stream) {
// stream为一个 MediaStream 对象
// 把stream赋值给视频标签,就可以使video标签播放webRtc
var video = document.querySelector('video');
video.srcObject = stream;
video.onloadedmetadata = function(e) {
video.play();
};
})
.catch(function(err) {
console.log("发生错误: " + err.name);
});
上述代码只是简单的请求了音频和视频权限。经过用户同意,就会创建一个MediaStream
对象。然后,这个对象被赋给一个<video>
元素的srcObject
属性,以便在网页上显示视频。要真正的实现与后台之间进行连接还需要使用RTCPeerConnection
WebAPI。
php
const init = async (video: HTMLVideoElement) => {
// 创建一个新的 RTCPeerConnection 实例
const peerConnection = new RTCPeerConnection()
// 创建一个 SDP offer
const offer = await peerConnection.createOffer({
// 是否接受音频
offerToReceiveAudio: true,
// 是否接受视频
offerToReceiveVideo: true,
})
// 设置本地描述为 SDP offer
peerConnection.setLocalDescription(offer);
// 当远程流就绪时,将其赋给 video 元素的 srcObject 属性
peerConnection.ontrack = function (event) {
if (video) {
video.srcObject = event.streams[0];
}
};
// 通过 fetch 发送 SDP offer 到指定的 URL(接口地址),并获取返回的 SDP answer
const sdp: string = await fetch(url as string, { headers: { ...getHeader() }, method: 'post', body: offer.sdp }).then((res) => res.text());
// 设置远程描述为 SDP answer
peerConnection.setRemoteDescription({
type: 'answer',
sdp: sdp
})
}
上面代码通过使用RTCPeerConnection
对整个建立连接封装为一个方法,该方法需要传入一个video,从而将与后台建立的连接所获取到的媒体流在video
中进行播放。
RTCPeerConnection
的详细内容参考 RTCPeerConnection - Web API 接口参考 | MDN