2019年终总结&小半年流媒体服务器开发经验总结

2023-05-16

2019年终总结&小半年流媒体服务器开发经验总结

文章目录

  • 2019年终总结&小半年流媒体服务器开发经验总结
    • 19年开发小结
      • 流媒体服务框架设计
      • 登录服开发
      • ffmpeg音视频合成服务开发
    • 流媒体服务开发小结
      • rtp处理
      • 视频的合成&音视频缓冲区
      • 音视频编码
    • 音视频部分功能演示
      • 首先5个推流客户端
      • 5对流的登录
      • 流的位置交换
      • 流删除
      • 流登录


时间转瞬即逝,转眼间19年已经过去了,却没见自己心智有多大提升,期望2020年能有一个崭新的自己。

19年因为发展原因,从嵌入式转行做互联网了,干了一年突然转行,自己也很纠结这么做对不对,但我想得很清楚我只是想做自己想做的事情,从事自己想做的工作。

虽然意想不到的的是后期的工作并不算真正意义上的后端工作,用到的后端技术并不多,主要时间挣扎在了流媒体的开发,音视频的编解码,滤波、硬件加速、rtp、音视频格式(aac、pcm、h264)、另外主管选择了开源的ffmpeg库、都偏向于流媒体开发,于是本着边学边工作的心理过了今年。。

19年开发小结

流媒体服务框架设计

基于公司项目需求设计流媒体服务器,考虑到扩展性,分离了业务与音视频处理,便于后期音视频处理服务能做水平扩展,同时还能更替音视频处理方案。

登录服开发

基于公有协议栈,管理用户登录、缓存、出入房间动态等等、迎合docker特点、单独用户数据库缓存。

ffmpeg音视频合成服务开发

主要包括音视频相关内容的开发,也是开发投入时间最长的服务,主要经历了以下过程。

1)、最初基于ffmpeg的h264软解实现服务demo.

2)、然后尝试基于英特尔vaapi硬件加速驱动做h264硬解,对解码视频帧做软件overlay滤波进行音视频合成,再做vaapi硬编码。
优点是此流程软件实现上会更为简洁快速,也比较稳定。
但是后面发现系统会时不时crash。从系统日志上没有找到相关日志,于是进行了长期的软件模块排除法检查问题原因,做了解码、解码+滤波、滤波+编码等单元模块组挂机测试,仍然无法找到系统crash问题原因。
同时也在微软的github仓库提交了bug/issue,但是回复较慢。

3)、起初怀疑是vaapi驱动问题,于是尝试使用英特尔qsv硬件加速驱动硬解,对解码视频帧做硬件overlay_qsv滤波进行音视频合成,再做qsv硬编码。
优点是音视频处理全交付于gpu处理,省下大片cpu时间。缺点是硬件帧上下文关系密切,做视频自动切换上,需要做更多软件处理,编码上略微复杂。
可惜系统crash问题依然存在。

4)、ffmpeg原生工具命令行测试系统crash问题,发现确实有这个问题,而且更换很多个ffmpeg版本都会出现,只是概率可能会有浮动:快的几分钟到几小时crash、慢的一星期可能不会出现,但是不改任何参数再次尝试依然可能crash.

5)、移植音视频服务从linux到windows系统下、经过长期测试windows下运行intel加速方案确实没有系统宕机问题了、同时因为登录服基于muduo库实现,移植复杂,改将登录服打包进docker容器运行。

6)、完善及优化音视频服务框架及功能。包括:添加适当rtp缓存解决公网环境udp包波动问题、添加音视频同步机制、增加相应业务功能接口。

7)、移植到微服务框架,进一步增强程序扩展性。

流媒体服务开发小结

音视频合成服务简要组成模块如下
在这里插入图片描述

rtp处理

rtp手解,没有用ffmpeg的avformat库,这样我更便于管理网络处理部分。

需要注意的是udp在公网上可能存在网络抖动问题,开一块rtp缓存消抖,按seq做最小堆。我直接用的golang的heap包实现。

然后将音频包和视频包按相对时间戳,做堆排序放进一块rtp缓存里(av_rtp_handler),这样是为了方便做音视频同步,记录第一个到达的rtp包时间戳、后续rtp的相对时间加上timestamp的增量换算来的时钟,然后用来标志这个包的相对时间。
例如 h264 90000的时钟 、 30的帧率 、 : 假如第一包为3000时间戳增量 那么本包相对时间假定为 3000 / 90000 = 33.33333ms, 假如下一包增量也是3000,第二包相对时间就是33.3+33.3 = 66.6ms依此类推。

rtp时间的同步 : av_rtp_handler里所有rtp包都带了我一个换算出来的相对时间戳的、 只需要将音视频的包做一次最小堆插入、每次取堆顶时间戳最小的rtp包即可、 是音频包就丢进音频解码器、视频包就丢进视频解码器。

视频的合成&音视频缓冲区

我想了很久音视频进行合成结构后发现有一个很重要的东西、那就是音视频帧的缓冲区、而且这个缓冲区真的很重要、它能做到以下效果:

1、控制帧率

2、解决多路流的音视频帧抖动问题

1、 通过一个定时器、你能很方便的控制帧率、例如隔33ms往合成器发送一组音视频帧进行合成即可。修改帧率你只需要更改定时器的种子值。

2、消抖、每路流到达的时间肯定是不稳定的、可能通道3一下子除了了5包数据、一下子来了10帧数据、而其他路还只有1到2帧或者没有、但是你要保持实时性肯定不能把所有帧全部保存下来、所以你必须控制每路的缓冲大小得把挤出来的非I帧删掉、注意是非I帧不然可能会花屏。

然后就是音视频合成、音频用amix、视频用overlay、

视频帧合成麻烦在qsv有一个硬件帧上下文、qsvframecontext每次做屏幕的自动切换、或者屏幕位置交换、需要重新生成filter、而你就需要费工夫去更新这个qsvframecontext 极为麻烦、后面想到的方法是设计一张ffmpeg filter输入的映射

就是在不该ffmpeg滤波器描述符的情况下、而是直接交换filter的输入位置。

一个草图将就下: 相当于 就是打乱正当的输入顺序、做一张映射、这样子不用更改filter的描述符即可做滤波器的切换,要便利极多!

音频合成没什么好说的、就是每路的输出可能不能包含自己的通道声音、不然可能存在回音、可以弄个集合记录需要合成的流输入id的集合、合成的时候把自己的id去掉再合成就行了,还有不同编码合成可以做重采样来保证filter输入的一致性。

音视频编码

编码好像没什么重点东西、打包的时候打上个合适的时间戳即可。

音视频部分功能演示

因为csdn限制了gif的大小为5m,博客园好像是10m,所以用ffmpeg压缩了大小和帧率,比较模糊。

首先5个推流客户端

用了两个demo视频
测试用推流工具: https://github.com/ailumiyana/streaming
5条命令行一直往新建音视频服务的音视频端口发rtp数据
在这里插入图片描述

5对流的登录

配置登录流的地址,流标识依次为 “ai“, “lu”, “mi”, “ya”, “na“
同时自动合成一条流,并用ffplay播放出来。

流的位置交换

演示中
流0和流1交换了几次位置
流0和流4交换了几次位置

流删除

依次删除 用户 “ai“, “lu”, “mi”, “ya”, 四条流

流登录

再次将 “ai“, “lu”, “mi”, “ya”, 四条流登录回去

这里演示了上文流媒体服务的几个基本功能,其他还包括设置固定展示流合成数量(例如只展示2个画面)、单条流音频开关、加水印等等。 其实都只需要切换下滤波器即可,对ffmpeg而言就是一个 filter 描述符。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2019年终总结&小半年流媒体服务器开发经验总结 的相关文章

随机推荐

  • 点亮LED灯及IAR调试

    点亮LED灯 一开始想先通过简单的点亮一个灯的程序来试一下MCU xff0c 硬件上的原理图如下 xff1a 从这里看出PB4 PB5 PC3 PC4 PC5 PC7都能用 xff0c 还没接外设 xff0c 一开始我选择了 PB5 去外接
  • Vite项目推荐使用的几个插件——开发神器

    Vite 可以使用插件进行扩展 xff0c 这得益于 Rollup 优秀的插件接口设计和一部分 Vite 独有的额外选项 在 Vue3 43 Vite 开发中 xff0c 有下面几个插件帮助 xff0c 无异于锦上添花 xff0c 不失为日
  • linux ROS串口读取的问题

    目的是实现电脑端 xff08 ubuntu系统 xff09 与STM32通过串口建立通讯 xff0c STM32解算与其连接的传感器并将数据传送至电脑端进行编程 我们知道 xff0c 随便一个串口助手即可实现读取STM32串口数据并显示出来
  • 磁力计的基本工作原理

    参考文章地址 xff1a http blog sina com cn s blog 402c071e0102v8ig html 电子罗盘是一种重要的导航工具 xff0c 能实时提供移动物体的航向和姿态 随着半导体工艺的进步和手机操作系统的发
  • Gazebo中的turtlebot2中加入GPS模块

    ubuntu14 04 xff0c ros版本为indigo turtlebot2的仿真环境的学习参考 xff1a http learn turtlebot com 的仿真部分 想用GPS做导航 xff0c gazebo中没有GPS模块 x
  • Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.

    将用户添加到docker用户组 xff0c 避免每次运行docker需要sudo 命令如下 sudo groupadd docker 添加docker用户组 sudo gpasswd a dell 填写你的用户 docker 将登陆用户加入
  • java微信H5支付中遇到的问题都已解决 java代码 和html代码

    1 xff0c 开通账号 xff0c 申请商户账号 打开连接https pay weixin qq com index php partner public home xff08 如图1 xff09 xff08 图1 xff09 2 xff
  • 【leetcode】高频题目整理_数学篇( High Frequency Problems, Math )

    截止至今LeetCode题目总量已经有1582题 xff0c 估计将来每年平均增长300题左右 xff0c 大部分人肯定是刷不完的 xff0c 所以得有选择地刷LeetCode 一种公认的刷题策略是按类别刷题 xff0c 可是每个类别也有许
  • svn拉分支,打标签

    首先在本地打开svn的branch命令 点击右边的打开按钮 右键branch分支创建一个线上文件夹 可以指定某个提交点拉分支
  • docker的image两个id相同名字不同

    今天建立docker容器的时候由于疏忽 xff0c 镜像的名字输错了 xff0c 结果容器创建成功后 xff0c 镜像中出现两个id相同 我们要删除第一个 xff1a docker rmi imageID 是删除口令 这种情况的操作 xff
  • 树莓派Pi OS备份镜像设置自动扩展磁盘,完全基于树莓派原版系统实现方式(镜像备份全流程)

    写入树莓派官方镜像的时候 xff0c 我们会发现当树莓派第一次启动后 xff0c 磁盘空间会自动扩充到整个TF卡 那么当我们自己制作镜像的时候 xff0c 能不能去除未使用的空间 xff0c 制作体积较小的镜像 xff0c 并在该镜像启动时
  • STM8S 红外解码+低功耗处理

    NEC协议 红外遥控的编码目前广泛使用的是 xff1a NEC Protocol 的 PWM xff08 脉冲宽度调制 xff09 和 PhilipsRC 5 Protocol 的 PPM xff08 脉冲位置调制 xff09 xff0c
  • YUV 数据和 Bitmap 互相转换

    YUV 数据和 Bitmap 互相转换 在 Android 的 Camera 应用开发过程中会遇到需要保存预览图像进行分析的情况 xff0c 比如人脸检测或扫描等场景 此时需要将预览的 YUV 数据转为为 Bitmap 保存下来 xff0c
  • Git从入门到熟练第九讲 合并分支和分支冲突

    前言 上一章我们讲解了分支的创建和删除 xff0c 以及对误删分支的恢复操作 xff0c git stash挂起分支修改 在这一讲我们则重点讲解分支合并git merge以及如何解决合并冲突 目录 课前准备 xff1a 9 1 合并分支 9
  • STM32 跳转系统BootLoader

    STM32 跳转系统BootLoader STM32 进入系统 bootLoader 主要有两种方法 xff1a xff08 1 xff09 一种是设置 boot 引脚 xff0c 进入系统 bootLoader xff08 2 xff09
  • 43 freertos任务通知-互斥量串口防止打印乱码

    四十三 freertos任务通知 互斥量串口防止打印乱码 span class token comment span span class token macro property span class token directive ha
  • canal监听mysql实践

    canal监听mysql实践 canal是用java开发的基于数据库增量日志解析 xff0c 提供增量数据订阅 amp 消费的中间件 目前 xff0c canal主要支持了MySQL的binlog解析 xff0c 解析完成后才利用canal
  • 自动驾驶算法学习:多传感器信息融合(标定, 数据融合, 任务融合)

    版权声明 xff1a 本文为博主转载文章 xff0c 遵循 CC 4 0 by sa 版权协议 xff0c 转载请附上原文出处链接和本声明 原文链接 xff1a https blog csdn net orange littlegirl a
  • Linux平台设备和驱动

    一 platform总线 一个现实的linux设备驱动通常需要挂接在一种总线上 xff0c 对于本身依附于PCI xff0c USB xff0c IIC xff0c SPI等的设备而言 xff0c 这自然不是问题 xff0c 但是在嵌入式系
  • 2019年终总结&小半年流媒体服务器开发经验总结

    2019年终总结 amp 小半年流媒体服务器开发经验总结 文章目录 2019年终总结 amp 小半年流媒体服务器开发经验总结19年开发小结流媒体服务框架设计登录服开发ffmpeg音视频合成服务开发 流媒体服务开发小结rtp处理视频的合成 a