WebRTC音视频录制实战 七、第三节 WebRTC采集屏幕数据

今天我学习一下通过WebRTC捕获桌面,其实这个功能在我们日常的直播系统中,基本上都必备的一个功能。

首先我们来看一下获取桌面的API

getDisplayMedia

 

基本格式

var promise = navigator.mediaDevices.getDisplayMedia(constraints);

constraints可选

constraints中约束与getUserMedia函数中的一致。

下面我们来实践一下:

这个功能在chrome中是实验性的项目,所以只有对最新的项目开放。

在实战之前我们要打开浏览器,做一下设置

chrome://flags/#enable-experimental-web-platform-features

client.js

'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();
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
webrtc是一种开源的实时通信技术,可以直接在网页浏览器中进行音视频通话和数据传输。它使用了现代Web浏览器中的原生API,包括音视频采集和编码、网络传输和协议、解码和渲染等功能,实现了实时的音视频互动。 这本PDF《webrtc音视频实时互动技术》详细介绍了webrtc的原理、技术栈和应用场景。首先,它介绍了webrtc的基本原理,包括媒体捕获和处理、流媒体媒体传输和网络连接、媒体处理和渲染等核心模块的工作流程。通过深入理解这些原理,读者可以更好地掌握webrtc实时通信的底层机制。 其次,这本PDF还详细介绍了webrtc的技术栈,包括音视频采集和编码、实时流传输和协议、网络传输和连接、解码和渲染等几个关键方面。它提供了详细的代码示例和实际应用案例,帮助读者更好地理解和应用这些技术。 最后,这本PDF还探讨了webrtc在实际应用中的场景和挑战。它介绍了webrtc在视频会议、在线教育、远程医疗等领域的应用,并提供了相应的解决方案和优化技巧。同时,它还讨论了webrtc在网络环境、设备兼容性和安全性方面的挑战,为读者提供了解决这些问题的方法和建议。 总之,《webrtc音视频实时互动技术》这本PDF提供了全面而深入的webrtc实时通信技术知识,帮助读者理解webrtc的原理和技术,并能够应用于实际场景中。无论是对webrtc技术感兴趣的开发者,还是希望在实时音视频通信领域应用webrtc的用户,都会从这本PDF中获得丰富的知识和实用的经验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值