Web前端如何实现录像功能?如何将canvas录制为视频?WebRTC有哪些功能?

12,066次阅读
没有评论

共计 4563 个字符,预计需要花费 12 分钟才能阅读完成。

WebRTC 功能相关的一些例子:https://webrtc.github.io/samples/

WebRTC 相关的 API:https://developer.mozilla.org/zh-CN/docs/Web/API/WebRTC_API

申请媒体权限

1.getUserMedia

MediaDevices.getUserMedia() 会提示用户给予使用媒体输入的许可,媒体输入会产生一个 MediaStream,里面包含了请求的媒体类型的轨道。此流可以包含一个视频轨道(来自硬件或者虚拟视频源,比如相机、视频采集设备和屏幕共享服务等等)、一个音频轨道(同样来自硬件或虚拟音频源,比如麦克风、A/D 转换器等等),也可能是其他轨道类型。

它返回一个 Promise 对象,成功后会 resolve 回调一个 MediaStream 对象。若用户拒绝了使用权限,或者需要的媒体源不可用,promise 会 reject 回调一个 PermissionDeniedError 或者 NotFoundError。

通常使用 navigator.mediaDevices 来获取 MediaDevices

相关文档:https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia

返回的 promise 对象可能既不会 resolve 也不会 reject,因为用户不是必须选择允许或拒绝。

/**
 * 获取媒体设备
 * @param constraints 定义的约束类型
 * @param success 成功的回调
 * @param error 失败的回调
 */
function getUserMedia(constraints, success, error) {if (navigator.mediaDevices.getUserMedia) {
        // 最新的标准 API
        navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error);
    } else if (navigator.webkitGetUserMedia) {
        //webkit 核心浏览器
        navigator.webkitGetUserMedia(constraints, success, error)
    } else if (navigator.mozGetUserMedia) {
        //firfox 浏览器
        navigator.mozGetUserMedia(constraints, success, error);
    } else if (navigator.getUserMedia) {
        // 旧版 API
        navigator.getUserMedia(constraints, success, error);
    }
}

2.constraints

constraints 作为一个 MediaStreamConstraints 对象,指定了请求的媒体类型和相对应的参数。

constraints 的参数是一个包含了 video 和 audio 两个成员的 MediaStreamConstraints 对象,用于说明请求的媒体类型。

// 不带任何参数,获取摄像头和麦克风权限
{audio: true, video: true}

// 指定摄像头分辨率
{
  audio: true,
  video: {width: { min: 1024, ideal: 1280, max: 1920},
    height: {min: 776, ideal: 720, max: 1080}
  }
}

// 强制后置摄像头
{audio: true, video: { facingMode: { exact: "environment"} } }

// 优先使用前置摄像头
{audio: true, video: { facingMode: "user"} }

音频常见约束参数:

  • volume 音量约束
  • sampleRate: 采样率
  • sampleSize: 采样大小,采样的位数
  • echoCancellation: 回音消除
  • autoGaincontrol:增加音量
  • noiseSuppression: 降噪
  • latency:延迟大小
  • channelCount: 切换声道
  • deviceID: 多个音频输入输出设备的进行切换
  • groupId: 同一个物理设备,是一个分组,但是输入和输出的 id 不一样

视频常见约束参数

  • width : 宽度约束
  • height : 高度约束
  • aspectRatio: 比率
  • frameRate: 帧率
  • facingMode:摄像头控制,user: 前置摄像头,environment : 后摄像头,left:前置左摄像头,right:前置右摄像头
  • resizeMode: 采集的画面需不需要裁剪

媒体流

相关概念:

  • MediaStreamTrack
  • MediaStream
  • source
  • sink
  • MediaTrackConstraints

1.MediaStream

MediaStream 是连接 WebRTC API 和底层物理流的中间层,webRTC 将音视频经过 Vocie / Video engine 进行处理后,再通过 MediaStream API 给暴露给上层使用。

MediaStream 接口是一个媒体内容的流.。一个流包含几个轨道,比如视频和音频轨道。

Web 前端如何实现录像功能?如何将 canvas 录制为视频?WebRTC 有哪些功能?

MediaStream

2.MediaStreamTrack

MediaStreamTrack 接口在 User Agent 中表示一段媒体源,比如音轨或视频。

获取媒体流中的 Track:

  • MediaStream.addTrack(),存储传入参数 MediaStreamTrack 的一个副本。如果这个轨道已经被添加到了这个媒体流,什么也不会发生; 如果目标轨道为“完成”状态(也就是已经到尾部了),一个 INVALID_STATE_RAISE 异常会产生。
  • MediaStream.getTracks(),返回流中所有的 MediaStreamTrack 列表。
  • MediaStream.getAudioTracks(),返回流中 kind 属性为 ”audio” 的 MediaStreamTrack 列表。顺序是不确定的,不同浏览器间会有不同,每次调用也有可能不同。
  • MediaStream.getTrackById(),返回给定 ID 的轨道。如果没有参数或者没有指定 ID 的轨道,将返回 null。如果有几个轨道有同一个 ID,将返回第一个。
  • MediaStream.getVideoTracks(),返回流中 kind 属性为 ”video” 的 MediaStreamTrack 列表。顺序是不确定的,不同浏览器间会有不同,每次调用也有可能不同。
  • MediaStream.removeTrack(),移除作为参数传入的 MediaStreamTrack。如果这个轨道不在 MediaStream 对象中什么也不会发生;如果目标轨道为“完成”状态,一个 INVALID_STATE_RAISE 异常会产生。

相关操作方法:

  • MediaStreamTrack.getConstraints(),获取相关的约束参数
  • MediaStreamTrack.applyConstraints(),应该一个新的约束参数
  • MediaStreamTrack.getSettings()
  • MediaStreamTrack.getCapabilities()
  • MediaStreamTrack.clone()
  • MediaStreamTrack.stop()

媒体录制

1.MediaRecorder

MediaRecorder 是 MediaStream Recording API 提供的用来进行媒体轻松录制的接口,他需要通过调用 MediaRecorder() 构造方法进行实例化。

MediaStream Recording API 由一个主接口 MediaRecorder 组成,这个接口负责的所有工作是从 MediaStream 获取数据并将其传递给你进行处理。数据通过一系列 dataavailable 事件传递,这些数据已经成为你创建 MediaRecorder 时所声明的格式。

// 录制完毕,数据可用时触发的事件
MediaRecorder.ondataavailable= dataavailable(e) => {const blob = new Blob([e.data], {'type': 'video/mp4'})
    const fd = new FormData();
    fd.append("video", blob);
    ...
}

2. 录制过程

  1. 建立一个 MediaStream 或者 HTMLMediaElement (以  或  元素的形式 ) 来充当媒体数据的源。
  2. 创建一个 MediaRecorder 对象,指定源以及任何有需求的的选项 (比如容器的 MIME 类型或它轨道所需的比特率).
  3. 给 dataavailable 事件设置 MediaRecorder.ondataavailable 事件处理函数; 会在数据可利用时候调用。
  4. 一旦媒体源播放,你已经准备好录制,使用 MediaRecorder.start() (en-US) 开始录制。
  5. dataavailable 事件处理函数正如你所愿的在每次数据准备好时调用; 这个事件有一个值为包含媒体数据的 Blob 类型的 data 属性。你可以强制 dataavailable 事件发生,因此会给你传递最新的声音以至于可以让你过滤、保存或者做一些其他的事情。
  6. 当源媒体停止播放时候,录制自动结束。
  7. 你可以随时结束录制通过使用 MediaRecorder.stop().

3. 将媒体流显示到 video 元素

HTMLMediaElement 接口的 srcObject 属性设定或返回一个对象,这个对象提供了一个与 HTMLMediaElement 关联的媒体源,这个对象通常是 MediaStream。

var mediaStream = HTMLMediaElement.srcObject
HTMLMediaElement.srcObject = mediaStream

// 如果不支持上述接口
HTMLMediaElement.src = URL.createObjectURL(mediaStream);

4. 将 video 的画面绘制到 canvas

const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');

// 绘制 video 当前显示的画面
context.drawImage(videoNode, 0, 0, canvas.width, canvas.height);

5.captureStream

captureStream([frameRate]) 方法返回的 CanvasCaptureMediaStream 是一个实时视频捕获的画布。

  • frameRate 设置双精准度浮点值为每个帧的捕获速率。如果未设置,则每次画布更改时都会捕获一个新帧。如果设置为 0,则会捕获单个帧。
// 获取所需要截取媒体流的 canvas element
var canvasElt = document.querySelector('canvas');

// 截取到媒体流
var stream = canvasElt.captureStream(25); // 25 FPS

提示 Tips

可通过该功能对视频进行处理然后导出

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2023-03-18发表,共计4563字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)