我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Golang如何实现RTP音视频传输

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Golang如何实现RTP音视频传输

今天小编给大家分享一下Golang如何实现RTP音视频传输的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

引言

在 Coding 之前我们先来简单介绍一下 RTP(Real-time Transport Protocol), 正如它的名字所说,用于互联网的实时传输协议,通过 IP 网络传输音频和视频的网络协议。

由音视频传输工作小组开发,1996 年首次发布,并提出了以下使用设想。

  • 简单的多播音频会议

使用 IP 的多播服务进行语音通信。通过某种分配机制,获取多播组地址和端口对。一个端口用于音频数据的,另一个用于控制(RTCP)包,地址和端口信息被分发给预期的参与者。如果需要加密,可通过特定格式进行加密。

  • 音视频会议

如果在会议中同时使用音视频媒体,那么它们是作为单独的 RTP 会话传输。音频,视频两个媒体分别使用不同的 UDP 端口对传输单独的 RTP 和 RTCP 数组包,多播地址可能相同,可能不同。进行这种分离的动机是如果参与者只想接受一种媒体,可以进行选择。

  • Mixer 和 Translator

我们需要考虑这样一种情况,在某个会议中,大多数人处于高速网络链路中,而某个地方的一小部分人只能低速率连接。为了防止所有人使用低带宽,可以在低带宽区域放置一个 RTP 级的中继器 Mixer。Mixer 将接收的音频报文重新同步为发送方 20 ms 恒定间隔,重建音频为单一流,音频编码为低速带宽的音频,然后转发给低速链路上的带宽数据包流。

  • 分层编码

多媒体应用程序应该能调节传输速率以匹配接收者容量或适应网络拥塞。可以将调节速率的任务通过将分层编码和分层传输系统相结合来实现接收器。在基于 IP 多播的 RTP 上下文中,每个 RTP 会话均承载在自己的多播组上。然后,接收者可以只通过加入组播组合适的子集来调整接收带宽。

RTP 数据包头部字段

只有当 Mixer 存在时,才会存在 Cclass="lazy" data-src 标识符列表。这些字段具有以下含义。前 12 个 8 位组在每一个包中都有。

  • version (V): 2 bits

RTP 版本。

  • 填充 (P): 1 bit

如果设置了填充位,包中包含至少一个填充 8 位组,其他填充位不属于 Payload。

  • 扩展 (X): 1 bit

如果设置了扩展位则存在。

  • Cclass="lazy" data-src 数量(CC): 4 bits

Cclass="lazy" data-src 数量包含在固定头中,Cclass="lazy" data-src 标识符数量。

  • 标记 (M): 1 bit

标记由配置文件定义。用于标记数据包流中例如帧边界之类的重要事件。

  • payload 类型(PT): 7 bits

该字段指出 RTP 有效载荷格式,由应用程序进行解释。接收者必须忽略无法理解的有效载荷类型的数据包。

  • 序列号: 16 bits

每次 RTP 数据包发送时增加,可能用于接收者检测包丢失并且恢复包序列。

  • 时间戳: 32 bits

该字段反映了 RTP 数据包中第一个 8 位组的采样时刻。

  • Sclass="lazy" data-src: 32 bits

标识同步源,这个标识符应该选择随机,在同一个 RTP 对话的两个同步源应该有不同的同步标识。

  • Cclass="lazy" data-src 列表:0 到 15 项, 其中每项 32 bits

该字段表示对该 payload 数据做出贡献所有 Sclass="lazy" data-src。

Golang 的相关实现

RTP 的实现有一些,不过通过 Go 实现有一些好处。

  • 易于测试

这里的易于测试不仅仅是体现在容易书写,能够快速通过源码,函数直接生成相应测试函数。而且更重要的是能够提供相应的基准测试,提供计时,并行执行,内存统计等参数供开发者进行相应调整。

  • 语言层面强大的 Web 开发能力

能够基于语言层面快速的对例 JSON 解析,字段封装 。无需引入三方库。

  • 性能较为优异

相比于 Python,Ruby 等解释型语言快,比 node, erlang 等语言更易书写。如果服务中需要用并发,内置关键字 go 就可以快速起多个 goroutine。

Go 社区的RTP有 RTP 相关实现,对应的测试也比较全面,简单介绍一下。

package_test.go (基础测试)

func TestBasic(t *testing.T) {  p := &Packet{}  if err := p.Unmarshal([]byte{}); err == nil {    t.Fatal("Unmarshal did not error on zero length packet")  }  rawPkt := []byte{    0x90, 0xe0, 0x69, 0x8f, 0xd9, 0xc2, 0x93, 0xda, 0x1c, 0x64,    0x27, 0x82, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0x98, 0x36, 0xbe, 0x88, 0x9e,  }  parsedPacket := &Packet{        // 固定头部    Header: Header{      Marker:           true,      Extension:        true,      ExtensionProfile: 1,      Extensions: []Extension{        {0, []byte{          0xFF, 0xFF, 0xFF, 0xFF,        }},      },      Version:        2,      PayloadOffset:  20,      PayloadType:    96,      SequenceNumber: 27023,      Timestamp:      3653407706,      Sclass="lazy" data-src:           476325762,      Cclass="lazy" data-src:           []uint32{},    },        // 有效负载    Payload: rawPkt[20:],    Raw:     rawPkt,  }  // Unmarshal to the used Packet should work as well.  for i := 0; i < 2; i++ {    t.Run(fmt.Sprintf("Run%d", i+1), func(t *testing.T) {      if err := p.Unmarshal(rawPkt); err != nil {        t.Error(err)      } else if !reflect.DeepEqual(p, parsedPacket) {        t.Errorf("TestBasic unmarshal: got %#v, want %#v", p, parsedPacket)      }      if parsedPacket.Header.MarshalSize() != 20 {        t.Errorf("wrong computed header marshal size")      } else if parsedPacket.MarshalSize() != len(rawPkt) {        t.Errorf("wrong computed marshal size")      }      if p.PayloadOffset != 20 {        t.Errorf("wrong payload offset: %d != %d", p.PayloadOffset, 20)      }      raw, err := p.Marshal()      if err != nil {        t.Error(err)      } else if !reflect.DeepEqual(raw, rawPkt) {        t.Errorf("TestBasic marshal: got %#v, want %#v", raw, rawPkt)      }      if p.PayloadOffset != 20 {        t.Errorf("wrong payload offset: %d != %d", p.PayloadOffset, 20)      }    })  }}

基本测试中,利用 Golang 自带的 Unmarshal 快速将 byte 切片转换为相应结构体。减少了相关封包,解包等代码的工作量。在网络传输中,也能够在语言层面直接完成大端,小端编码的转换,减少编码的烦恼。

h.SequenceNumber = binary.BigEndian.Uint16(rawPacket[seqNumOffset : seqNumOffset+seqNumLength])h.Timestamp = binary.BigEndian.Uint32(rawPacket[timestampOffset : timestampOffset+timestampLength])h.Sclass="lazy" data-src = binary.BigEndian.Uint32(rawPacket[sclass="lazy" data-srcOffset : sclass="lazy" data-srcOffset+sclass="lazy" data-srcLength])

其中关于切片的相关操作十分便捷,可以获取数组中的某一段数据,操作比较灵活,在协议数据的传输过程中,通过切片,获取某段数据进行相应处理。

m := copy(buf[n:], p.Payload)p.Raw = buf[:n+m]

在实现完成后,Golang 的子测试能够进行嵌套测试。对执行特定测试用例特别有用,只有子测试完成后,父测试才会返回。

func TestVP8PartitionHeadChecker_IsPartitionHead(t *testing.T) {    checker := &amp;VP8PartitionHeadChecker{}    t.Run("SmallPacket", func(t *testing.T) {        if checker.IsPartitionHead([]byte{0x00}) {            t.Fatal("Small packet should not be the head of a new partition")        }    })    t.Run("SFlagON", func(t *testing.T) {        if !checker.IsPartitionHead([]byte{0x10, 0x00, 0x00, 0x00}) {            t.Fatal("Packet with S flag should be the head of a new partition")        }    })    t.Run("SFlagOFF", func(t *testing.T) {        if checker.IsPartitionHead([]byte{0x00, 0x00, 0x00, 0x00}) {            t.Fatal("Packet without S flag should not be the head of a new partition")        }    })}

以上就是“Golang如何实现RTP音视频传输”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Golang如何实现RTP音视频传输

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Golang如何实现RTP音视频传输

今天小编给大家分享一下Golang如何实现RTP音视频传输的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。引言在 Coding
2023-07-02

Golang与FFmpeg: 实现实时视频流的加密传输技术

要实现实时视频流的加密传输技术,可以使用Golang和FFmpeg的组合。以下是一种可能的实现方法:1. 使用FFmpeg来捕获视频流并进行编码。可以使用FFmpeg提供的命令行工具,或者使用FFmpeg的库来进行编码。可以选择常见的视频编
2023-10-08

Qt音视频开发之音频播放QAudioOutput如何实现

这篇文章主要介绍了Qt音视频开发之音频播放QAudioOutput如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Qt音视频开发之音频播放QAudioOutput如何实现文章都会有所收获,下面我们一起来看
2023-07-05

Golang与FFmpeg: 实现视频流媒体的分段传输技术

Golang与FFmpeg可以结合使用,来实现视频流媒体的分段传输技术。首先,需要使用FFmpeg来对视频文件进行分段处理。可以使用FFmpeg的命令行工具来实现,也可以使用FFmpeg的库来进行编程实现。下面是一个使用FFmpeg命令行工
2023-10-08

Python如何实现视频中添加音频工具

这篇文章主要介绍Python如何实现视频中添加音频工具,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!环境依赖ffmpeg环境安装,可以参考:windows ffmpeg安装部署ffmpy安装:pip install
2023-06-21

Golang与FFmpeg: 如何实现音频混音和提取

要在Golang中实现音频混音和提取,我们可以使用FFmpeg库。FFmpeg是一个开源的多媒体框架,可以处理音频、视频和其他多媒体数据。首先,您需要在您的Golang项目中导入FFmpeg库。可以使用go get命令从GitHub上获取F
2023-10-08

Golang与FFmpeg: 如何实现音频混音和分离

在Golang中使用FFmpeg可以实现音频混音和分离。下面是一个简单的示例代码:gopackage mainimport ("fmt""os""os/exec")func main() {// 音频混音mixAudio()// 音频分离s
2023-10-20

golang如何实现大文件传输

在 Golang 中,可以使用 io 和 os 包来实现大文件的传输。以下是一种可能的实现方式:首先,需要创建一个服务器端和一个客户端,它们之间可以通过网络进行通信。服务器端的代码如下:package mainimport ("io""
2023-10-21

Thinkphp5实现图片、音频和视频文件的上传功能

本篇文章为大家展示了Thinkphp5实现图片、音频和视频文件的上传功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。首先是同步上传,最为基础的上传的方式,点击表单提交之后跳转那种。
2023-06-15

C#如何使用NAudio实现音频可视化

小编给大家分享一下C#如何使用NAudio实现音频可视化,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!预览:捕捉声卡输出:实现音频可视化, 第一步就是获得音频采样
2023-06-15

Qt+Quick如何实现播放音乐和视频

这篇文章主要介绍了Qt+Quick如何实现播放音乐和视频的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Qt+Quick如何实现播放音乐和视频文章都会有所收获,下面我们一起来看看吧。MediaPlayer 是 Q
2023-07-05

C++ Qt如何实现音视频播放功能

这篇文章将为大家详细讲解有关C++ Qt如何实现音视频播放功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。由于最近着手的Qt项目需要视频播放 自己做的时候踩了很多坑 避免以后踩坑 故在此记
2023-06-21

前端音频可视化Web Audio如何实现

这篇文章主要介绍“前端音频可视化Web Audio如何实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“前端音频可视化Web Audio如何实现”文章能帮助大家解决问题。实现思路首先画肯定是用can
2023-07-05

Golang与FFmpeg: 如何实现音频降噪和音量调节

要实现音频降噪和音量调节,可以通过调用FFmpeg库来处理音频文件。在Golang中,可以使用CGO来调用C语言的FFmpeg库。首先,确保已经安装了FFmpeg,并且在系统环境变量中配置了FFmpeg的路径。然后,可以使用CGO来调用FF
2023-10-08

Golang如何实现文件传输功能

今天小编给大家分享一下Golang如何实现文件传输功能的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。借助TCP完成文件的传输
2023-07-05

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录