第十五章 音频和视频媒体的支持

媒体流(MediaStream)

媒体流(MediaStream)是一个重要概念,它代表着音频和视频数据的流。媒体流可以包含一个或多个音频轨道(AudioTrack)和视频轨道(VideoTrack),这些轨道可以同时捕获和播放音频和视频内容。

下面是一些关于媒体流的详解和概念性知识点:

  1. 媒体轨道(MediaTrack):媒体轨道是媒体流的组成部分,用于表示音频或视频内容。一个媒体流可以包含一个或多个音频轨道和视频轨道。音频轨道捕获和传输音频数据,视频轨道捕获和传输视频数据。
  2. 媒体流捕获(MediaStream Capture):媒体流捕获是指从设备(如摄像头、麦克风)中获取音频和视频数据,并生成媒体流的过程。通过使用getUserMedia()方法,可以请求用户授权访问设备,并获取包含音频和视频轨道的媒体流。
  3. 媒体流播放(MediaStream Playback):媒体流播放是指将媒体流中的音频和视频数据进行实时播放的过程。可以通过将媒体流关联到HTML5的<video>元素的srcObject属性上,或将媒体流传递给其他WebRTC连接的对等方来实现媒体流的播放。
  4. 媒体流的控制:媒体流提供了一些方法和属性来控制音频和视频轨道的行为,例如启用/禁用轨道、调整音量、获取当前时间等。通过操作媒体流和轨道,可以实现音频和视频的控制和处理。
  5. 媒体流的传输:WebRTC使用媒体流来在对等连接之间传输音频和视频数据。通过将媒体流添加到RTCPeerConnection对象中的轨道中,并使用WebRTC的信令机制交换媒体流的描述信息(SDP),可以在对等连接之间建立音视频通信。
  6. 媒体流的事件:媒体流和媒体轨道可以触发各种事件,以便应用程序可以对其进行监听和响应。例如,可以监听媒体流的onaddtrack事件以在添加新轨道时执行操作,或者监听轨道的onended事件以在轨道结束时执行操作。

总之,媒体流是WebRTC中用于捕获、传输和播放音频和视频数据的重要概念。通过使用媒体流,可以实现实时的音视频通信和多媒体应用程序,如视频会议、音视频聊天和实时流媒体等。

在处理媒体流时,以下是一些常用的 Web API:

  1. MediaDevices API:通过 navigator.mediaDevices 对象可以访问媒体设备,如摄像头和麦克风。它提供了获取媒体流的方法,如 getUserMedia()
  2. MediaStream API:MediaStream 表示一个媒体流,可以通过 getUserMedia() 方法获取。它包含音频和/或视频轨道,可以通过操作 MediaStream 来控制媒体流的播放和录制。
  3. MediaRecorder API:MediaRecorder 允许你在浏览器中录制媒体流(如音频或视频)。它提供了开始、暂停和停止录制的方法,并且可以将录制的内容保存为文件或进行实时传输。
  4. MediaElement API:HTMLMediaElement 是媒体元素的 DOM 接口,例如 <audio><video> 元素。它提供了控制媒体播放、暂停、音量、播放速度等的方法和属性。
  5. WebRTC API:WebRTC(Web实时通信)是一组浏览器 API,用于实现实时音视频通信。它包括 RTCPeerConnectionRTCDataChannelRTCRtpSender 等接口,用于建立点对点的音视频连接并进行数据传输。
  6. Canvas API:CanvasRenderingContext2D 提供了在 <canvas> 元素上绘制和处理图像、视频等的方法和属性。你可以使用它来从视频流中捕捉帧、进行图像处理,或在画布上渲染实时图像。

获取用户的设备(摄像头,麦克风)

使用getUserMedia

这是 navigator.mediaDevices 对象的一个方法,用于请求用户授权访问媒体设备并获取媒体流(MediaStream)对象。通过传递适当的约束条件(constraints),可以指定所需的媒体类型、分辨率、帧率等。

兼容性如下:

第十五章 音频和视频媒体的支持

这个 API 的基本使用如下:

const isSupportMediaDevicesMedia = () => {  
    return !!(navigator.getUserMedia || (navigator.mediaDevices && navigator.mediaDevices.getUserMedia));};
    if (isSupportMediaDevicesMedia()) {  
        // 兼容性  
        navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;  
        // 配置  
        const mediaOption = { audio: true, video: true };  
        navigator.mediaDevices    
        .getUserMedia(mediaOption)    
        .then((stream) => {      
            console.log([Log] stream-->, stream);    
        })    
     .catch((err) => {      
         console.error([Log] 获取摄像头和麦克风权限失败-->, err);    
       });
    } else {  
        if (navigator.userAgent.toLowerCase().match(/chrome/) && location.origin.indexOf('https://') < 0) {    
            console.log('chrome下获取浏览器录音功能,因为安全性问题,需要在localhost或127.0.0.1或https下才能获取权限');  
        } else {    
            console.log('无法获取浏览器录音功能,请升级浏览器或使用chrome');  
        }
    }

核心就是 getUserMedia 方法和 mediaOption 这个配置。

mediaOption 配置:

const mediaOption = {  
    audio: true, // true 标识需要获取音频流  
    // 
    video: true, // true 标识需要获取视频流  
    // 指定视频的宽高和帧率  
    video: {    
        width: { min: 980, ideal: 980, max: 1920 }, 
        // min,max 指定一个范围,ideal 表示优先使用的值   
         height: { min: 560, ideal: 560, max: 1080 },    
         frameRate: { ideal: 12, max: 15 }, // 指定帧率    
         deviceId: { exact: '设备id' }, // 多设备的时候,可以通过设备id获取指定的设备    
         facingMode: 'user', //  user:前置摄像头,environment:后置摄像头  
         },
   };

getUserMedia 返回了一个 Promise<MediaStream>MediaStream 就是我们需要媒体流,那么拿到了流就可以干我们想干的事情了。

navigator.mediaDevices.getUserMedia({ audio: true, video: true })
  .then(function(stream) {
    // 在获取媒体流成功后执行操作
  })
  .catch(function(error) {
    // 处理获取媒体流失败的情况
  });
```

有几个注意点:

  1. video 标签的 autoPlay 属性要是 true,这样流才会播放
  2. 用完一定要记得停止,防止 cpu 占用过高
  3. 如果想要静音啥的,直接设置 video 标签相关的属性就好了

获取指定设备

一台电脑可以外接多个音视频设备, getUserMedia 默认是拿默认设备,如何获取所有设备以及获取指定设备的流呢?

使用到的是 enumerateDevices 这个 API,返回的是 Promise<MediaDeviceInfo[]>

MediaDeviceInfo 有如下属性:

  • kind:设备类型,是摄像头还是麦克风,
  • label: 设备名称
  • deviceId: 设备 ID

有了设备 id 就可以用 getUserMedia 获取指定的设备。

navigator.mediaDevices.enumerateDevices()
  .then(function(devices) {
    // 处理设备列表
  })
  .catch(function(error) {
    // 处理获取设备列表失败的情况
  });
```

录制视频

基本使用

录制视频是使用的 MediaRecorder 这个 API,使用方法也很简单

  • 创建一个 MediaRecorder 对象,传入我们获取到的 stream 流,可以使用 mimeType 指定编码类型,默认是 video/webm
  • 监听 dataavailable 事件,类似于 change 事件,会吐出录像数据,数据其实就是二进制的 blob 对象,直接 push 到数组里面就好了
  • 调用 start 方法开始录制,如果不传时间参数,那 dataavailable 只会在 stop 的时候触发一次,传了时间参数,就每间隔时间触发 dataavailable 事件
  • 调用 stop 方法结束录制

编码类型

构造 MediaRecorder 可以传递一个 mimeType 类型,用来指定录制的数据的编码类型,但是我还没弄明白这些类型最终生成的数据有啥区别,建议直接使用 video/webm,因为不管是啥编码类型,MediaRecorder 最终生成的文件只会是 webm 格式

编码类型可以理解成压缩数据的方式,有一些是无损压缩的,有一些是有损的,无损的压缩文件大小就会非常大,这里就不得不提到一些类型了,因为在项目中踩了很多的坑

在本文中,需要了解的视频格式

  • webm: 因为 MediaRecorder 只能录制 webm 格式的数据
  • mp4: web 中比较通用的视频格式

在本文中,需要了解的音频格式

  • webm: 因为 MediaRecorder 只能录制 webm 格式的数据
  • mp3: web 中比较通用的音频格式
  • pcm、wav: wav 在 pcm 文件中加入了一些描述信息,其余和 pcm 完全一致,pcm 是一种无损的音频格式,文件十分巨大,webm 可以不是很麻烦的转成 pcm 格式

这些文件格式的转换是十分复杂的,但并不是不能实现,需要将 blob 数据转成最原始的二进制数组,然后使用对应的编码方案,操作这个二进制数组。

注意点

  1. 浏览器厂商出于对用户安全、隐私等问题的考虑,限制网页在 https 协议下才能正常使用 WebRTC全部功能。为确保使用全部功能,请使用 https 协议访问页面。本地开发可以通过 http://localhost 或者 file:// 协议进行访问。
  2. 系统默认的设备如果被占用了,获取流的时候可能会失败,比如你在会议里面共享桌面,然后在去获取流就可能会失败。
  3. 有些笔记本有一个物理开关,能总控摄像头的访问权限,所以有时候一直是黑屏可以检查一下是不是这个原因。

RA/SD 衍生者AI训练营。发布者:chris,转载请注明出处:https://www.shxcj.com/archives/6540

Like (0)
Previous 2024-09-30
Next 2024-09-30

相关推荐

发表回复

Please Login to Comment
本文授权以下站点有原版访问授权 https://www.shxcj.com https://www.2img.ai https://www.2video.cn