网站首页 > 知识剖析 正文
1. WebRTC 采集api
在WebRTC中有一个api 可以用来获取桌面:getDisplayMedia
var promise = navigator.mediaDevices.getDisplayMedia(constraints);
constraints可选 constraints中约束与getUserMedia函数中的一致。
2. 采集平面数据
采集平面数据:这个功能在chrome中是实验性的项目,所以只有对最新的项目开放。
在实战之前我们要打开浏览器,做一下设置 chrome://flags/#enable-experimental-web-platform-features
如下图所示:
接下来我们看看具体的js代码如下:
C++音视频开发学习资料:点击领取→音视频开发(资料文档+视频教程+面试题)(FFmpeg+WebRTC+RTMP+RTSP+HLS+RTP)
'use strict'
var audioSource = document.querySelector('select#audioSource');
var audioOutput = document.querySelector('select#audioOutput');
var videoSource = document.querySelector('select#videoSource');
// 获取video标签
var videoplay = document.querySelector('video#player');
// 获取音频标签
var audioplay = document.querySelector('audio#audioplayer');
//div
var divConstraints = document.querySelector('div#constraints');
// 定义二进制数组
var buffer;
var mediaRecorder;
//record 视频录制 播放 下载按钮
var recvideo = document.querySelector('video#recplayer');
var btnRecord = document.querySelector('button#record');
var btnPlay = document.querySelector('button#recplay');
var btnDownload = document.querySelector('button#download');
//filter 特效选择
var filtersSelect = document.querySelector('select#filter');
//picture 获取视频帧图片相关的元素
var snapshot = document.querySelector('button#snapshot');
var picture = document.querySelector('canvas#picture');
picture.width = 640;
picture.height = 480;
// deviceInfos是设备信息的数组
function gotDevices(deviceInfos){
// 遍历设备信息数组, 函数里面也有个参数是每一项的deviceinfo, 这样我们就拿到每个设备的信息了
deviceInfos.forEach(function(deviceinfo){
// 创建每一项
var option = document.createElement('option');
option.text = deviceinfo.label;
option.value = deviceinfo.deviceId;
if(deviceinfo.kind === 'audioinput'){ // 音频输入
audioSource.appendChild(option);
}else if(deviceinfo.kind === 'audiooutput'){ // 音频输出
audioOutput.appendChild(option);
}else if(deviceinfo.kind === 'videoinput'){ // 视频输入
videoSource.appendChild(option);
}
})
}
// 获取到流做什么, 在gotMediaStream方面里面我们要传人一个参数,也就是流,
// 这个流里面实际上包含了音频轨和视频轨,因为我们通过constraints设置了要采集视频和音频
// 我们直接吧这个流赋值给HTML中赋值的video标签
// 当时拿到这个流了,说明用户已经同意去访问音视频设备了
function gotMediaStream(stream){
// audioplay.srcObject = stream;
videoplay.srcObject = stream; // 指定数据源来自stream,这样视频标签采集到这个数据之后就可以将视频和音频播放出来
// 通过stream来获取到视频的track 这样我们就将所有的视频流中的track都获取到了,这里我们只取列表中的第一个
var videoTrack = stream.getVideoTracks()[0];
// 拿到track之后我们就能调用Track的方法
var videoConstraints = videoTrack.getSettings(); // 这样就可以拿到所有video的约束
// 将这个对象转化成json格式
// 第一个是videoConstraints, 第二个为空, 第三个表示缩进2格
divConstraints.textContent = JSON.stringify(videoConstraints, null, 2);
window.stream = stream;
// 当我们采集到音视频的数据之后,我们返回一个Promise
return navigator.mediaDevices.enumerateDevices();
}
function handleError(err){
console.log('getUserMedia error:', err);
}
function start() {
// 判断浏览器是否支持
if(!navigator.mediaDevices ||
!navigator.mediaDevices.getDisplayMedia){ // 判断是否支持录屏
console.log('getUserMedia is not supported!');
}else{
// 获取到deviceId
var deviceId = videoSource.value;
// 这里是约束参数,正常情况下我们只需要是否使用视频是否使用音频
// 对于视频就可以按我们刚才所说的做一些限制
/**
* video : {
width: 640, // 宽带
height: 480, // 高度
frameRate:15, // 帧率
facingMode: 'enviroment', // 设置为后置摄像头
deviceId : deviceId ? deviceId : undefined // 如果deviceId不为空直接设置值,如果为空就是undefined
},
*/
var constraints = { // 表示同时采集视频金和音频
video : true,
audio : false
}
// 调用录屏API
navigator.mediaDevices.getDisplayMedia(constraints) // 这样就可以抓起桌面的数据了
.then(gotMediaStream) // 使用Promise串联的方式,获取流成功了
.then(gotDevices)
.catch(handleError);
}
}
start();
// 当我选择摄像头的时候,他可以触发一个事件,
// 当我调用start之后我要改变constraints
videoSource.onchange = start;
// 选择特效的方法
filtersSelect.onchange = function(){
videoplay.className = filtersSelect.value;
}
// 点击按钮获取视频帧图片
snapshot.onclick = function() {
picture.className = filtersSelect.value;
// 调用canvas API获取上下文,图片是二维的,所以2d,这样我们就拿到它的上下文了
// 调用drawImage绘制图片,第一个参数就是视频,我们这里是videoplay,
// 第二和第三个参数是起始点 0,0
// 第四个和第五个参数表示图片的高度和宽度
picture.getContext('2d').drawImage(videoplay, 0, 0, picture.width, picture.height);
}
//
function handleDataAvailable(e){ // 5、获取数据的事件函数 当我们点击录制之后,数据就会源源不断的从这个事件函数中获取到
if(e && e.data && e.data.size > 0){
buffer.push(e.data); // 将e.data放入二进制数组里面
// 这个buffer应该是我们在开始录制的时候创建这个buffer
}
}
// 2、录制方法
function startRecord(){
buffer = []; // 定义数组
var options = {
mimeType: 'video/webm;codecs=vp8' // 录制视频 编码vp8
}
if(!MediaRecorder.isTypeSupported(options.mimeType)){ // 判断录制的视频 mimeType 格式浏览器是否支持
console.error(`${options.mimeType} is not supported!`);
return;
}
try{ // 防止录制异常
// 5、先在上面定义全局对象mediaRecorder,以便于后面停止录制的时候可以用到
mediaRecorder = new MediaRecorder(window.stream, options); // 调用录制API // window.stream在gotMediaStream中获取
}catch(e){
console.error('Failed to create MediaRecorder:', e);
return;
}
// 4、调用事件 这个事件处理函数里面就会收到我们录制的那块数据 当我们收集到这个数据之后我们应该把它存储起来
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start(10); // start方法里面传入一个时间片,每隔一个 时间片存储 一块数据
}
// 3、停止录制
function stopRecord(){
// 6、调用停止录制
mediaRecorder.stop();
}
// 1、录制视频
btnRecord.onclick = ()=>{
if(btnRecord.textContent === 'Start Record'){ // 开始录制
startRecord(); // 调用startRecord方法开启录制
btnRecord.textContent = 'Stop Record'; // 修改button的文案
btnPlay.disabled = true; // 播放按钮状态禁止
btnDownload.disabled = true; // 下载按钮状态禁止
}else{ // 结束录制
stopRecord(); // 停止录制
btnRecord.textContent = 'Start Record';
btnPlay.disabled = false; // 停止录制之后可以播放
btnDownload.disabled = false; // 停止录制可以下载
}
}
// 点击播放视频
btnPlay.onclick = ()=> {
var blob = new Blob(buffer, {type: 'video/webm'});
recvideo.src = window.URL.createObjectURL(blob);
recvideo.srcObject = null;
recvideo.controls = true;
recvideo.play();
}
// 下载视频
btnDownload.onclick = ()=> {
var blob = new Blob(buffer, {type: 'video/webm'});
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.href = url;
a.style.display = 'none';
a.download = 'aaa.webm';
a.click();
}
猜你喜欢
- 2024-11-27 video.js中文文档(三):设置
- 2024-11-27 高级前端进阶:我是如何把 C/C++ 代码跑在浏览器上的?
- 2024-11-27 原生微信小程序video隐藏控件超级方法
- 2024-11-27 浏览器播放rtsp视频流解决方案
- 2024-11-27 第49节 DOM2和DOM3-Javascript-王唯
- 2024-11-27 使用AI CoNR 算法,仅仅利用4张动漫图片——便可以创建舞蹈视频
- 2024-11-27 WebRTC是如何实现音视频的录制
- 2024-11-27 WebAssembly该怎么学第二篇
- 2024-11-27 JAVA全栈CMS系统vue图片/视频上传组件,多图上传及删除功能11
- 2024-11-27 简单易懂的大文件上传教程:Vue3与.NET 6完美结合
- 最近发表
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)