type
status
date
slug
summary
tags
category
icon
password
Edited
Jul 1, 2023 04:18 PM
Created
Jul 1, 2023 03:57 PM
音视频采集基本概念
在正式介绍 JavaScript 采集音视频数据的 API 之前,你还需要了解一些基本概念。这些概念虽然都不难理解,但在后面讲解 API 时都会用到它们,很是重要,所以在这里我还是给你着重汇总和强调下。
- 摄像头。用于捕捉(采集)图像和视频。
- 帧率。现在的摄像头功能已非常强大,一般情况下,一秒钟可以采集 30 张以上的图像,一些好的摄像头甚至可以采集 100 张以上。我们把摄像头一秒钟采集图像的次数称为帧率。帧率越高,视频就越平滑流畅。然而,在直播系统中一般不会设置太高的帧率,因为帧率越高,占的网络带宽就越多。
- 分辨率。摄像头除了可以设置帧率之外,还可以调整分辨率。我们常见的分辨率有 2K、1080P、720P、420P 等。分辨率越高图像就越清晰,但同时也带来一个问题,即占用的带宽也就越多。所以,在直播系统中,分辨率的高低与网络带宽有紧密的联系。也就是说,分辨率会跟据你的网络带宽进行动态调整。
- 宽高比。分辨率一般分为两种宽高比,即 16:9 或 4:3。4:3 的宽高比是从黑白电视而来,而 16:9 的宽高比是从显示器而来。现在一般情况下都采用 16:9 的比例。
- 麦克风。用于采集音频数据。它与视频一样,可以指定一秒内采样的次数,称为采样率。每个采样用几个 bit 表示,称为采样位深或采样大小。
- 轨(Track)。WebRTC 中的“轨”借鉴了多媒体的概念。火车轨道的特性你应该非常清楚,两条轨永远不会相交。“轨”在多媒体中表达的就是每条轨数据都是独立的,不会与其他轨相交,如 MP4 中的音频轨、视频轨,它们在 MP4 文件中是被分别存储的。
- 流(Stream)。可以理解为容器。在 WebRTC 中,“流”可以分为媒体流(MediaStream)和数据流(DataStream)。其中,媒体流可以存放 0 个或多个音频轨或视频轨;数据流可以存 0 个或多个数据轨。
摄像头
getUserMedia 方法
MediaStreamConstraints 参数
上面这个例子表示:视频的帧率最小 20 帧每秒;宽度最小是 640,理想的宽度是 1280;同样的,高度最小是 360,最理想高度是 720;此外宽高比是 16:9;对于音频则是开启回音消除、降噪以及自动增益功能。
全部参数:
音视频设备
MediaDevices,该接口提供了访问(连接到计算机上的)媒体设备(如摄像头、麦克风)以及截取屏幕的方法。实际上,它允许你访问任何硬件媒体设备。而咱们要获取可用的音视频设备列表,就是通过该接口中的方法来实现的。
MediaDeviceInfo,它表示的是每个输入 / 输出设备的信息。包含以下三个重要的属性:
- deviceID,设备的唯一标识;
- label,设备名称;
- kind,设备种类,可用于识别出是音频设备还是视频设备,是输入设备还是输出设备。
需要注意的是,出于安全原因,除非用户已被授予访问媒体设备的权限(要想授予权限需要使用 HTTPS 请求),否则 label 字段始终为空。
另外,label 可以用作指纹识别机制的一部分,以识别是否是合法用户。
获取音视频设备列表
通过调用上面方法就可以获取到媒体输入和输出设备列表,例如: 麦克风、相机、耳机等。
拍照(捕获)
此处的localVideoRef为获取到摄像头的stream的video元素
录制
基础知识
WebRTC 录制音视频流之后,最终是通过 Blob 对象将数据保存成多媒体文件的;而 Blob 又与 ArrayBuffer 有着很密切的关系。那 ArryaBuffer 与 ArrayBufferView 又有什么联系呢?接下来,我们就了解一下这 3 种二进制数据类型,以及它们之间的关系吧。
- ArrayBuffer
ArrayBuffer 对象表示通用的、固定长度的二进制数据缓冲区。因此,你可以直接使用它存储图片、视频等内容。
但你并不能直接对 ArrayBuffer 对象进行访问,类似于 Java 语言中的抽象类,在物理内存中并不存在这样一个对象,必须使用其封装类进行实例化后才能进行访问。
也就是说, ArrayBuffer 只是描述有这样一块空间可以用来存放二进制数据,但在计算机的内存中并没有真正地为其分配空间。只有当具体类型化后,它才真正地存在于内存中。如下所示:
或
在上面的例子中,一开始生成的 buffer 是不能被直接访问的。只有将 buffer 做为参数生成一个具体的类型的新对象时(如 Uint32Array 或 DataView),这个新生成的对象才能被访问。
- ArrayBufferView
ArrayBufferView 并不是一个具体的类型,而是代表不同类型的 Array 的描述。这些类型包括:Int8Array、Uint8Array、DataView 等。也就是说 Int8Array、Uint8Array 等才是 JavaScript 在内存中真正可以分配的对象。
以 Int8Array 为例,当你对其实例化时,计算机就会在内存中为其分配一块空间,在该空间中的每一个元素都是 8 位的整数。再以 Uint8Array 为例,它表达的是在内存中分配一块每个元素大小为 8 位的无符号整数的空间。
通过这上面的描述,你现在应该知道 ArrayBuffer 与 ArrayBufferView 的区别了吧?ArrayBufferView 指的是 Int8Array、Uint8Array、DataView 等类型的总称,而这些类型都是使用 ArrayBuffer 类实现的,因此才统称他们为 ArrayBufferView。
- Blob
Blob(Binary Large Object)是 JavaScript 的大型二进制对象类型,WebRTC 最终就是使用它将录制好的音视频流保存成多媒体文件的。而它的底层是由上面所讲的 ArrayBuffer 对象的封装类实现的,即 Int8Array、Uint8Array 等类型。
Blob 对象的格式如下:
其中,array 可以是ArrayBuffer、ArrayBufferView、Blob、DOMString等类型 ;option,用于指定存储成的媒体类型。
录制本地音视频
方法
接收录制数据
下载录制文件
共享桌面
getDisplayMedia()
与 getUserMedia() 类似 (只有在 PC 下才能抓取桌面)
接下来的使用和 getUserMedia() 一样
录制桌面
其实和前面的录制是一样的,只需要把record的stream换成共享桌面的steam即可
参考链接
- 极客 从0打造音视频直播系统
- 作者:JinSo
- 链接:https://jinso365.top/article/webrtc-simple
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。