JavaScript 展示获取视频流
<!DOCTYPE html>
<html>
<head>
<!-- 设置文档使用的字符编码 -->
<meta charset="UTF-8">
<!-- 设置 viewport 元标签,以确保页面在移动设备上正确显示和缩放 -->
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<!-- 启用苹果移动设备的全屏模式 -->
<meta name="apple-mobile-web-capable" content="yes">
<!-- 页面标题 -->
<title>展示获取视频流</title>
<!-- 页面样式 -->
<style>
/* 设置视频元素样式 */
#videoId {
width: 512px;
height: 256px;
}
/* 按钮样式 */
.button-like-link {
display: inline-block;
padding: 10px 20px;
background-color: #f0f0f0;
border: 1px solid #ddd;
text-decoration: none;
color: #333;
cursor: pointer;
border-radius: 4px; /* 添加圆角 */
transition: background-color 0.3s, color 0.3s; /* 添加过渡效果 */
font-size: 14px;
}
/* 鼠标悬停时的样式 */
.button-like-link:hover {
background-color: #e7e7e7;
color: #000;
}
/* 禁用状态时的样式 */
.button-like-link:disabled {
background-color: #ccc;
color: #999;
cursor: not-allowed;
}
</style>
</head>
<body>
<!-- 控制按钮区域 -->
<div id="controls">
<!-- 开始按钮 -->
<button id="startId" class="button-like-link">开始</button>
<!-- 停止按钮 -->
<button id="stopId" class="button-like-link">停止</button>
<!-- 下载按钮 -->
<a id="downloadId" class="button-like-link" href="javascript:;">下载</a>
</div>
<!-- 视频播放区域 -->
<video controls autoplay="false" id="videoId"></video>
</body>
<script>
let startButton = document.getElementById('startId');
let stopButton = document.getElementById('stopId');
let downloadButton = document.getElementById('downloadId');
// 获取视频元素
let video = document.getElementById('videoId');
// 声明一个全局变量以便在不同的函数中访问媒体流对象
let mediaStream;
// 捕获媒体流
let mediaRecorder;
/**
* 点击开始按钮时,先打开视频设备,然后获取视频设备的媒体流数据,然后收集媒体流数据
* @returns {Promise<void>}
*/
startButton.onclick = async () => {
// 媒体约束对象,指定获取的媒体类型为音频和视频,视频宽高为理想值1280x720,使用用户前置摄像头,帧率为10到15
let constraints = {
audio: true,
video: true
};
// 1. 打开视频设备,获取用户媒体设备的流对象
mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
// 将获取到的媒体设备的流对象,赋值给视频元素的 srcObject 属性
video.srcObject = mediaStream;
// 当媒体元数据已加载时执行的回调函数,开始播放视频
video.onloadedmetadata = () => {
video.play();
};
startButton.style.background = "red";
startButton.style.color = "black";
// 2. 捕获媒体流
mediaRecorder = new MediaRecorder(mediaStream);
mediaRecorder.start();
// console.log(mediaRecorder.state);
// console.log("recorder started");
// 3. 收集录制的数据
let chunks = [];
// 当关闭mediaRecorder.stop()时会触发这个事件
mediaRecorder.ondataavailable = (event) => {
chunks.push(event.data);
// console.log(event.data)
// console.log(chunks)
// 测试,收集到的数据是否可以播放
// MP4 = 带有 H.264 视频编码和 AAC 音频编码的 MPEG 4 文件
// WebM = 带有 VP8 视频编码和 Vorbis 音频编码的 WebM 文件
// Ogg = 带有 Theora 视频编码和 Vorbis 音频编码的 Ogg 文件
//
// 格式 MIME-type
// MP4 video/mp4
// WebM video/webm
// Ogg video/ogg
let blob = new Blob(chunks, {type: "video/ogg; codecs=opus"});
let url = URL.createObjectURL(blob);
video.src = url;
// 更新下载按钮的 href 属性,以便用户可以下载视频
downloadButton.href = url;
downloadButton.download = `${new Date().toLocaleString()}_recorded_video.mp4`;
downloadButton.disabled = false; // 启用下载按钮
};
}
/**
* 停止捕获视频流
*/
stopButton.onclick = () => {
if (mediaStream) {
// 停止所有媒体流上的轨道
mediaStream.getTracks().forEach(track => {
track.stop();
});
// 停止媒体流的捕获
mediaRecorder.stop();
// console.log(mediaRecorder.state);
// 清除视频元素的 srcObject 属性
video.srcObject = null;
startButton.style.background = "";
startButton.style.color = "";
}
}
</script>
</html>
测试验证媒体流传输
前端
关注后解锁
服务端
关注后解锁
引入ASR模型
修改服务端
关注后解锁
引入ASR模型-增量翻译
修改前端
关注后解锁
长按录音
关注后解锁
长按录音-基于模型适配服务端
关注后解锁
以上都是前置条件与基础知识的储备,接下来才是真正的基于
Web实时通信
实现的实时流媒体
传输
WebRTC
全称是Web Real-Time Communication
,网页即时通信
。WebRTC在2011年6月1日开源,并在Google、Mozilla、Opera等各家巨头公司的支持下被纳入W3C 推荐标准,给浏览器和移动应用提供了即时通信的能力。
优势
- 跨平台(Web、Windows、MacOS、Linux、iOS、Android)
- 实时传输
- 音视频引擎
- 免费、免插件、免安装
- 主流浏览器支持
应用场景
- 音视频会议
- 即时通讯工具 IM
- 直播
- 共享远程桌面
- 等等
RTCPeerConnection
使用WebRTC实现实时通信最核心的API就是
RTCPeerConnection
,它代表一个由本地计算机到远端的WebRTC连接,该接口提供了创建、保持、监控及关闭连接的方法的实现,有点类似于socket
。相关的API
- createOffer 创建Offer方法
- setLocalDescription 设置本地SDP描述信息
- peer.onicecandidate 设置完本地SDP描述信息后会触发该方法,打开一个连接,开始运转媒体流
- setRemoteDescription 设置远端的SDP描述信息,由本地发送
- peer.ontrack 设置完远端SDP描述信息后会触发该方法,接收对方的媒体流
- createAnswer 远端创建应答Answer方法
- RTCIceCandidate RTC网络信息,IP、端口等
- addIceCandidate 连接添加对方的网络信息