Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >WebRTC研究:MediaStream概念以及定义

WebRTC研究:MediaStream概念以及定义

原创
作者头像
monktan
发布于 2021-12-20 13:06:04
发布于 2021-12-20 13:06:04
3.1K0
举报
文章被收录于专栏:音视频自留地音视频自留地

根据W3C的WebRTC 1.0: Real-time Communication Between Browsers规范,WebRTC的源码中定义了两套主要的C++接口,分别是MediaStreamPeerConnection相关的API。本篇文章主要介绍下MediaStream API中一些概念,方便理解内部代码如何处理。

MediaStream 相关API定义在源码api\media_stream_interface.h中。里面主要涉及这4个概念:sourcesinkmeidatrackmediastream

source与sink

在浏览器中,存在source到sink的媒体管道,source生产媒体资源的,sink负责消费。传统的source一般是些静态资源,例如文件,以及web资源,不随时间改变。对于我们的WebRTC来说,source是动态资源,例如麦克风采集的音频,相机采集的视频,随时间而改变。sink的工作就是将这些source呈现给用户。sink可以是<img><video><audio>这些标签,用于本地渲染,也可以是RTCPeerConnection,将source通过网络传递到远端。在网络流传输中,RTCPeerConnection可同时扮演source与sink的角色,作为sink,可以将获取的source降低码率,缩放,调整帧率等,然后传递到远端,作为source,将获取的远端码流传递到本地渲染。

下面我们以video source举例,说下WebRTC源码中,source与sink定义。

在api\video\video_source_interface.h中,video source定义如下:

代码语言:txt
AI代码解释
复制
template <typename VideoFrameT>
class VideoSourceInterface {
 public:
  virtual ~VideoSourceInterface() = default;
 
  virtual void AddOrUpdateSink(VideoSinkInterface<VideoFrameT>* sink,
                               const VideoSinkWants& wants) = 0;
  // RemoveSink must guarantee that at the time the method returns,
  // there is no current and no future calls to VideoSinkInterface::OnFrame.
  virtual void RemoveSink(VideoSinkInterface<VideoFrameT>* sink) = 0;
};

source可以添加、移除、更新sink,从而将VideoFrame送给对应的sink处理,一个source可对应多个sink。

在video\video_sink_interface.h中,video sink定义如下:

代码语言:txt
AI代码解释
复制
template <typename VideoFrameT>
class VideoSinkInterface {
 public:
  virtual ~VideoSinkInterface() = default;
 
  virtual void OnFrame(const VideoFrameT& frame) = 0;
 
  // Should be called by the source when it discards the frame due to rate
  // limiting.
  virtual void OnDiscardedFrame() {}
};

sink通过OnFrame获取source传递的VideoFrame

MediaStreamTrack与MediaStream

MediaStream API中有两个重要组成:MediaStreamTrack以及MediaStreamMediaStreamTrack对象代表单一类型的媒体流,产生自客户端的media source,可以是音频或者视频,但只能是其中一种,是音频称作audio track,视频的话称作video track,这其实就是我们平时所说的音轨与视频轨。

一个track由source与sink组成。source给track提供数据。

MeidiaStream用于将多个MediaStreamTrack对象打包到一起。一个MediaStream可包含audio trackvideo track。类似我们平时的多媒体文件,可包含音频与视频。

一个MediaStream对象包含0或多个MediaStreamTrack对象。MediaStream中的所有MediaStreamTrack对象在渲染时必须同步。就像我们平时播放媒体文件时,音视频的同步。

简单点说,source 与sink构成一个track,多个track构成MediaStram。

在api\media_stream_interface.h中,MediaStream定义如下:

代码语言:txt
AI代码解释
复制
class MediaStreamInterface : public rtc::RefCountInterface,
                             public NotifierInterface {
 public:
  virtual std::string id() const = 0;
 
  virtual AudioTrackVector GetAudioTracks() = 0;
  virtual VideoTrackVector GetVideoTracks() = 0;
  virtual rtc::scoped_refptr<AudioTrackInterface> FindAudioTrack(
      const std::string& track_id) = 0;
  virtual rtc::scoped_refptr<VideoTrackInterface> FindVideoTrack(
      const std::string& track_id) = 0;
 
  virtual bool AddTrack(AudioTrackInterface* track) = 0;
  virtual bool AddTrack(VideoTrackInterface* track) = 0;
  virtual bool RemoveTrack(AudioTrackInterface* track) = 0;
  virtual bool RemoveTrack(VideoTrackInterface* track) = 0;
 
 protected:
  ~MediaStreamInterface() override = default;
};

MediaStream可以添加移除audio track以及video track。

下面说下MediaTrack的定义,这里我们举例VideoTrack,代码同样位于api\media_stream_interface.h中。

代码语言:txt
AI代码解释
复制
class VideoTrackInterface : public MediaStreamTrackInterface,
                            public rtc::VideoSourceInterface<VideoFrame> {
 public:
  // Video track content hint, used to override the source is_screencast
  // property.
  // See https://crbug.com/653531 and https://w3c.github.io/mst-content-hint.
  enum class ContentHint { kNone, kFluid, kDetailed, kText };
 
  // Register a video sink for this track. Used to connect the track to the
  // underlying video engine.
  void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
                       const rtc::VideoSinkWants& wants) override {}
  void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override {}
 
  virtual VideoTrackSourceInterface* GetSource() const = 0;
 
  virtual ContentHint content_hint() const;
  virtual void set_content_hint(ContentHint hint) {}
 
 protected:
  ~VideoTrackInterface() override = default;
};

可以看到VideoTrack由video source与video sink组成。

pc\video_track.cc中,我们看下MediaTrack接口的一些具体实现:

代码语言:txt
AI代码解释
复制
void VideoTrack::AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
                                 const rtc::VideoSinkWants& wants) {
  RTC_DCHECK(worker_thread_->IsCurrent());
  VideoSourceBase::AddOrUpdateSink(sink, wants);
  rtc::VideoSinkWants modified_wants = wants;
  modified_wants.black_frames = !enabled();
  video_source_->AddOrUpdateSink(sink, modified_wants);
}
 
void VideoTrack::RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
  RTC_DCHECK(worker_thread_->IsCurrent());
  VideoSourceBase::RemoveSink(sink);
  video_source_->RemoveSink(sink);
}

由于VideoTrack由video source与video sink组成,所以对VideoTrack进行AddOrUpdateSink操作时,其实就是让VideoTrack的source进行AddOrUpdateSink

示例

为了更好地理解上述概念,我们举个例子说明。下图home client中,摄像机产生视频video source。source的宽高设置分别是800以及600像素。home client 中三个MediaStream包含的track使用该摄像机视频作为source,此时就有三个video track了。三个video track分别连接三个不同的sink:<video>标签A,<video>标签B以及一个peer connection C。<video>A与<video>B分别对source的视频进行缩放处理后渲染到本地浏览器界面中。peer connection C作为sink把该video source 推流到remote client。在remote client,两个media stream使用peer connection作为source,连接到两个<video>sink(Y与Z),进行本地渲染。

image.png
image.png

参考

1 Media Capture and Streams.https://www.w3.org/TR/mediacapture-streams/.

2 WebRTC 1.0: Real-time Communication Between Browsers.http://w3c.github.io/webrtc-pc/.

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
暂无评论
推荐阅读
编辑精选文章
换一批
WebRTC:一个视频聊天的简单例子
在前面的章节中,已经对WebRTC相关的重要知识点进行了介绍,包括涉及的网络协议、会话描述协议、如何进行网络穿透等,剩下的就是WebRTC的API了。
猿哥
2019/08/06
3.1K0
Webrtc及WEB端音视频设备获取及流处理
注意本文和之前Electron获取设备的文章有重合,但是也不是一样的,因为在Electron中我们不但能用HTML的API,也能使用Electron的API,但是WEB中就有局限了,在WEB中就实现不了直接分享主屏幕,必须用户选择。
码客说
2022/09/23
2.8K0
Webrtc及WEB端音视频设备获取及流处理
Webrtc实时通信的构建流程:PeerConnection对等通信的实现方式
webrtc是一个实时通讯技术,很简单的应用在web浏览器中应用实时通讯技术,包括音视频通话。在使用webrtc技术时,浏览器端都已经基本封装好,只要调用相应的api,就可实现简单的通话,其中一个主要对象就是RTCPeerConnection 支持音频和视频媒体数据通信。本文我们就分享一下一套完整的对等通信是如何实现的。
TSINGSEE青犀视频
2021/05/13
2.4K0
Webrtc混音接口使用
  通过使用AddSource接口添加不同的音频流,然后通过调用Mix接口进行混音操作,其中AudioFrame* audio_frame_for_mixing是混音数据。
Qt君
2023/03/17
7860
Webrtc混音接口使用
音视频通信加餐 —— WebRTC一肝到底
最近需要搭建一个在线课堂的直播平台,考虑到清晰度和延迟性,我们一致认为使用 WebRTC 最合适。
杨成功
2022/09/22
1.2K0
音视频通信加餐 —— WebRTC一肝到底
WebRTC | 原理、架构、框架目录、运行机制、核心类、PeerConnection调用过程等详解
架构 整理分为两层: 应用层、核心层 绿色部分是核心部分, 是WebRTC提供的核心功能; 紫色部分是浏览器提供的JS的API层; 即 浏览器对WebRTC核心层的C++ API 做了一层封装
凌川江雪
2020/08/11
6K0
WebRTC | 原理、架构、框架目录、运行机制、核心类、PeerConnection调用过程等详解
webRtc实践总结
场景 业务上有这样的一个场景,这是一个游戏直播会场,需要把手机上面的游戏画面,投屏到大屏幕上面,不仅如此可能还需要加一些其他信息例如比赛信息或者logo赞助等等,只使用设备本身投屏就不能满足现在的述求,说白了在大屏之上我们需要一个自定义的游戏视频画面。 image.png 技术抽象 业务是这样的类似场景,具体实践是使用electron的客户端实现:主窗口采集的视频,投放大屏窗口中。 核心代码功能解析 需要实现两个窗口实例 需要实现视频传输 解决方案 electron是支持获取屏幕实例的api的,并且在不同
吴文周
2022/03/09
1.2K0
webRtc实践总结
Web前端WebRTC攻略(一) 基础介绍
随着互联网高速发展,以及即将到来的5G时代,WebRTC作为前端互动直播和实时音视频的利器,也是将前端开发者们不可错过的学习领域。如果你现在只是听过而已,那你可能要好好学习一番。 01  什么是WebRTC? WebRTC 全称是(Web browsers with Real-Time Communications (RTC) 大概2011年,谷歌收购了 GIPS,它是一个为 RTC 开发出许多组件的公司,例如编解码和回声消除技术。Google 开源了 GIPS 开发的技术,并希望将其打造为行业标准。 收
用户1097444
2022/06/29
2.8K0
Web前端WebRTC攻略(一) 基础介绍
WebRTC 点对点直播
作者:villainthr WebRTC 全称为:Web Real-Time Communication。它是为了解决 Web 端无法捕获音视频的能力,并且提供了 peer-to-peer(就是浏览器
腾讯IVWEB团队
2017/03/13
10.6K0
视频通话进阶:React Hooks和屏幕共享,让你在虚拟世界中畅享面对面的交流
您撰写本文是为了深入研究使用 React 构建具有屏幕共享功能的视频会议应用程序的复杂性。您的目标是强调这项技术的复杂性和变革潜力。
zayyo
2023/10/14
6530
「WebRTC」最新 WebRTC 源码目录结构分析
最近一直在研究 WebRTC源码,发现目前网上分析WebRTC源码的资料非常少。随着Google不断推进WebRTC标准,WebRTC 代码的变化非常大,很多以前的分析文章目前都与最新的代码无法对应上了。
音视频_李超
2020/04/02
4.5K0
「WebRTC」最新 WebRTC 源码目录结构分析
【教程】如何使用Javascript构建WebRTC视频直播?
WebRTC是一个免费的开源项目,它通过简单的API为浏览器和移动应用程序提供实时通信功能。本文将向你展示WebRTC的基本概念和功能,并指导你使用Node.js构建自己的WebRTC视频直播。
TSINGSEE青犀视频
2021/04/12
4.8K0
WebRTC视频数据流程分析
直播回放:https://www.livevideostack.cn/video/online-piasy/
LiveVideoStack
2020/09/14
3.1K0
Safari上使用WebRTC指南
原文:https://webrtchacks.com/guide-to-safari-webrtc/
LiveVideoStack
2021/09/01
3.9K0
融云技术分享:基于WebRTC的实时音视频首帧显示时间优化实践
本文由融云技术团队原创投稿,作者是融云WebRTC高级工程师苏道,转载请注明出处。
JackJiang
2020/09/28
1.4K0
WebRTC技术概览
WebRTC(Web Real-Time Communication)是基于标准化技术的行业性项目,
呱牛笔记
2023/05/02
1.5K0
WebRTC技术概览
实现一个接收多路RTP流,输出一路RTMP流的简单MCU
做转码服务的原型时,看了看MCU的实现,考虑到如果不做转码,可以将多路rtp流直接合成为一路rtmp流输出,这样就相当于实现了多人连麦,并将多人连麦的视频转发直播了,所以做了这个简单的原型实现!
呱牛笔记
2023/05/02
1.2K1
实现一个接收多路RTP流,输出一路RTMP流的简单MCU
用JS轻松实现一个录音、录像、录屏工具库
最近项目遇到一个要在网页上录音的需求,在一波搜索后,发现了 react-media-recorder[1] 这个库。今天就跟大家一起研究一下这个库的源码吧,从 0 到 1 来实现一个 React 的录音、录像和录屏功能。
写代码的海怪
2022/03/29
1.4K0
用JS轻松实现一个录音、录像、录屏工具库
html5使用webrtc例子
以上是 html5 使用 webrtc 的核心代码,其实代码并不复杂,可以运行示例例观察调用流程;但是自己需要实现一个信令服务器。
用户10777220
2024/01/17
3570
前端音视频WebRTC实时通讯的核心
通过上两个系列专栏的学习,我们对前端音视频及 WebRTC 有了初步的了解,是时候敲代码实现一个 Demo 来真实感受下 WebRTC 实时通讯的魅力了。还没有看过的同学请移步:
童欧巴
2020/11/02
2.9K0
前端音视频WebRTC实时通讯的核心
相关推荐
WebRTC:一个视频聊天的简单例子
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档