自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(108)
  • 资源 (4)
  • 收藏
  • 关注

原创 webrtc pacer模块(一) 平滑处理的实现

Pacer起到平滑码率的作用,使发送到网络上的码率稳定。如下的这张创建Pacer的流程图,其中PacerSender就是Pacer,其中PacerSender就是Pacer。这篇文章介绍它的核心子类PacingController及Periodic模式下平滑处理的基本流程。平滑处理流程中还有与带宽探测所关联的流程,在本篇文章中并不涉及。从上图中可以看到,在创建Call对象时,会创建一个,它是Call对象中发送数据的大总管,而也是属于它管理的对象。一个Call对象中一个,一个中一个。

2025-04-11 20:55:54 958

原创 JS中的aynsc和await

虽然async和await通常会在一起被提到,但是最好把它们分开,作为两个概念,更容易理解些。况且使用async也不一定要使用await。

2025-01-03 07:15:56 299

原创 JS中的Promise对象

写一个异步操作常规的方式就是调用异步接口,注册结果回调。异步接口和结果回调的声明形式多种多样,所以也是代码风格也各种各样。js中引入了Promise来统一异步操作的编码流程,规范代码风格。这篇文章描述了我所认为的Promise几个要点。

2025-01-03 07:14:45 677

原创 webrtc音频模块(五) AudioState和AudioDeviceBuffer

AudioState和是音频处理模块的两个功能类。两者没有直接的关系,只是放在这里一起总结。

2024-12-30 07:26:23 653

原创 Webrtc音频模块(四) 音频采集

音频的采集还是封装在音频的采集一样的通过Core Audio API实现,上面的和就是采集接口对象。_dmo是DMO接口对象,是它使用的buffer接口对象,它们也用于采集。webrtc中实现两种模式的音频采集_dmo这篇文章只介绍通过DMO的方式采集音频数据。

2024-12-22 08:14:41 1190

原创 webrtc音频模块(三) windows Core Audio API及声音的播放

在前面介绍了ADM(Audio Device Module),它用于抽象音频设备管理和音频数据采集/播放接口。windows的实现是,它封装了实现了对音频设备的操作。

2024-12-13 16:12:36 1355 1

原创 JS中的原型链与继承

原型链将各个对象链接在一起,但试图访问对象的属性时,不仅在该对象上查找属性,还会在该对象的原型上查找属性,以及原型的原型,依此类推,直到找个一个名字匹配的属性或到达原型链的末尾。这就很像,在链表中查找值,一个一个的节点查找,直到末尾。这个就跟C/C++中通过指针建立的关系很相似,比如,通过指针建立一个链表,一个个地址就是通过指针串连起来,产生关系。JS中原型链最大的作用就是模拟继承,达到代码复用的目的。JS中原型链,本质上就是对象之间的关系,通过。原型对象的内容,以达到代码复用的目的。属性,表示由谁创建。

2024-12-08 17:39:58 1067

原创 JS中的this

函数是否在new中调用(new绑定)?如果是的话this绑定的新创建的对象。函数是否通过callapply(显示绑定)调用?如果是的话,this绑定的是指定的对象。函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this绑定的是那个上下文对象。obj1.foo();如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到undefined,否则绑定到全局对象。foo();

2024-12-07 08:52:00 860

原创 JS中的类与对象

所以不要把Java/C++这类面向对象的概念往JS上套,这样很容易绕晕。要明白JS的核心一切皆对象。

2024-11-28 07:39:47 1027

原创 webrtc音频模块介绍(一) 音频引擎的架构

音频引擎全局只有一个,由所有的call对象所共享(一个pc对象对应一个call对象),各个call中的stream都会放在引擎的。

2024-11-24 08:10:03 615

原创 webrtc音频模块介绍(二) ADM

不同操作系统管理音频设备及提供的音频接口方式各不同,ADM用于屏蔽音频设备管理及接口的差异,抽象统一接口。它的全称是Adio Device Module。

2024-11-22 07:15:32 464

原创 webrtc中的Track,MediaChannel,MediaStream

Audio/Video track,MediaChannel,MediaStream是Webrtc的业务核心,对媒体的操作都是围绕着这三个对象进行,弄清出它们见的关系及作用,就等于弄清了Webrtc的骨架,对阅读Webrtc的代码大有益处。根据本地sdp或sdp的协商结果,来产生MediaChannel,MediaChannel代表一个Video或Audio通道,里面会有多个不同方向的MediaStream。sdp中的媒体信息需要转化为具体的编解码器,rtp流的信息。这些信息最终会分别变成为。

2024-04-14 21:30:06 2048

原创 C++ 模板基础知识(二)

可以是函数,函数指针,函数对象,lambad。),将会返回一个数据结构包含一个类型成员,指示得到的类型,推导出返回值的类型,推导是编译期完成。模板参数除了类型参数,可以使用非类型参数,如下,类模板。通过下面三种方法可以使编译器确定模板函数的返回值类型。下面是C++ 14及之后标准的写法,写法更简单些。它可以推导两种或多种不同类型的共同类型(如下定义了一个非类型参数的函数模板,结合。可以看到推导出来的类型为double。内的表达式不同了,这里要注意。上面是C++ 11的写法,用于获取表达式的类型,通过。

2024-03-24 19:24:28 1178

原创 C++模板基础知识

为了生成一个实例化版本,编译器需要掌握函数模板或类模板成员函数的定义。因此,与非模板代码不同,模板的头文件通常即包括声明也包括定义。函数模板和类模板成员函数的定义通常放在头文件中。像常规的头文件和源文件分离编译的情况,在模板情况下行不通。如下模板类Blob,在文件中public:public:T getA();U getB();U _b;如果将Blob类中的构造函数及getA()和getB()函数,定义在文件return _a;return _b;那么在。

2024-03-09 09:43:15 1005

原创 webrtc native api的几个要点

sdp中核心的信息就是描述媒体信息的内容,简称m行或媒体行。通过pc对象的AddTrack或AddTransceiver方法添加track,会直接反映到sdp中。一个PC对象表示一次P2P会话,它包括sdp handle,call。如下代码,添加了两个VideoTrack,最终反映到sdp中为两个sendrecv的m行。整个过程本质就是获取本地sdp信息和远端sdp信息,再进行协商,流程可以概括为如下图。,前者是告知sdp创建,协商的状态。,是webrtc native的pc对象封装示例代码。

2024-02-06 20:15:49 1826

原创 ZLMediaKit 切换用于源的RingBuffer

那么把它抽象为技术实现,就是web同时会与ZLMediaKit建立4个pc对象,这个4个pc对象建立后,就不会销毁(直到web播放器关闭),由ZLMediaKit根据web请求的rtsp摄像头标识,将不同摄像头的流转给web。有这样一个需求,基于webrtc实现的web实时流播放器,有4分屏,最大同时显示4个图像rtsp摄像头的图像。对象的生命周期只与任务对象一样长,这样显然不是原始要表达的意图,应该改成如下,在外部定义。中切换源,但是它并未提供这样的功能,根据上面的分析,可以加一个。上连了多少个连流端。

2024-01-08 21:46:30 1254

原创 通过ZLMediaKit来说说流媒体服务的实现

rtc中的流媒体服务主要目标是保证高效的转发,在基于udp/rtp协议的系统中,直接转发rtp包,不会转协议,不涉及到组帧,拆包,音视频同步。现在有很多开源事件库实现,比如libevet,libuv,asio等,不同的实现,主要是在性能,功能,和跨平台上做文章来突出差异化。现在服务器的实现大多采用了多线程模式,即多进程多线程或单进程多线程,ZLMediaKit是单进程多线程服务,虽然它有两个进程,但是其中一个是守护进程,并不处理业务。会出现多进程多线程,单进程多线程,单进程单线程,多进程单线程的各种模式。

2024-01-04 08:06:50 1256

原创 webrtc中的接口代理框架

模块提供接口,外部代码通过接口来使用模块功能。业务应用通过一层proxy来使用webrtc通过功能,也就是应用层与webrtc通过proxy隔离。在webrtc中通过一种接口代理的方式,来封装了对外的接口。(类图中我列出了类所在的文件名,方便查看代码,它的接口太多,这里就不列出了)(类图中我列出了类所在的文件名,方便查看代码,列出了几个核心的接口)文件中,这里就不展开叙述了,可以直接看看代码,是怎么使用的。在webrtc中需要导出的接口,采用的是如上的类体系。方法,它将产生接口类的实例类,供应用使用。

2024-01-01 12:03:06 1517

原创 我的2023年,平淡中寻找乐趣

我很满意的是我坚持了下来,虽然在很长的一段时间里,每天只背十个单词,这一年英语水平并没有大的提高。学习言语重要的是听与说,我也改变了背单词的策略,重点是听,是熟悉它的读音,而不是光记怎么写。要听到音后,知道是什么意思,怎么拼写,也就是记住了。经过一个月的练习,换气也顺畅了,划水也掌握了要领。剩下就是练习熟练度了,反复练。以这样的标准,反复练习,如果在水中感觉到了滑翔的感觉,就表示练成了。换气比较顺畅了,划水没掌握要领,前进基本靠腿打水,搞的小腿经常抽筋。开始无法顺畅换气,憋上一口气,游个20米,就不行了。

2023-12-28 22:41:26 459

原创 ZLMediaKit的转流流程(二)

中的suorce作为源时,此时就涉及到了组帧,拆包的过程了。中,通过信令协商产生了对应的音视频的Track,视频对应的Track为。,它是一个各种协议的muxer类,将视频帧按不同的协议进行拆包。**如果有rtmp的拉流端则会直接使用这个源,以。类型,数据将由它们转发。下面Frame的牛转图。类型的成员变量,存放的就是Frame的消费者。,视频帧又被拆分为各协议对应的包。类型,作为一个Rtmp的源。视频帧的转发的被抽象为一个。在以Rtsp为源的情况下,方法传入的是rtp包,经过。

2023-12-27 08:04:42 1769

原创 优秀的流媒体服务器ZLMediaKit

它适用于视频监控系统的转流服务或作为RTC系统的边缘媒体网关。而不太适合于高实时要求的RTC SFU转流服务。ZLMediaKit 是国人写的优秀的流媒体服务器,它支持的协议多,稳定,性能优秀。它的可以作为音视频开发的百宝箱,特别是对协议的实现,可以直接复用。

2023-12-24 20:38:28 794

原创 ZLMediaKit中的RingBuffer

前面的文章讲到ZLMediaKit转流,提到过RingBuffer,它是比较核心的数据结构。这篇文章就来讲讲RingBuffer的用法。

2023-12-24 20:09:02 1485

原创 40岁的堂哥从华为“退休“了

堂哥刚40出头,他说持续了十几年的高强度工作,现在有点力不从心了,心里总是想着工作,都不知道怎么生活了,思想无法放松,睡觉都在想工作的事。跟身边的同学,朋友聊起来,大家都有这样的顾虑,普遍都比较焦虑,但是人到中年,选择面越来越少,现在市场活力降低,就业学历歧视,年龄歧视的状态下,也很难有所改变。反观我呢,在二线城市普通的中年程序员,在私企上班。他学历背景不好,04年计算机应用专科毕业,毕业那年去深圳参加了软件测试的培训班,第二年进入了华为外包公司慧通,干了没多久,慧通被华为兼并,他也转成了华为的正式员工。

2023-12-21 10:21:07 2226

原创 ZLMediaKit的转流流程(一)

zlmediakit的优势就是支持多种媒体容器和媒体协议。我从推流和拉流的两个角度,梳理出了转流的核心骨架。

2023-12-20 07:43:38 2899

原创 ZLMediaKit中的线程

EventLoop在众多的开源网络库都有实现。ZLMediaKit的实现非常适合用于多线程模型。这种方式非常适用于对线程职责的划分,将特定的业务通过消息队列分到固定的线程。就是EventLoop,为一个事件循环。它还包括了计算CPU负载的功能(在。以上为ZLMediaKit中线程池类图,通过。方法来取一个线程(EventPoller)。方法获取一个CPU负责最小的线程。时,线程都已创建并绑定到了核上,通过。优先取一个CPU负载小的线程。设置线程数,当产生线程池对象。对象就代表了一个线程。

2023-12-14 07:43:06 566

原创 webrtc 支持H265(三) 总结

有音频流最大的难点是要做音视频同步,也意味着web端不再只是单纯的解码,渲染,回放。在这样的场景中,视频流是单向的,码流从摄像头到ZLMediaKit到浏览器并且没有音频。关于延迟,对于webrtc datachannel通道的延迟我并没有专门进行测试,但是在后续的播放器整体测试时,webrtc datachannel通道并没有引入不可接受的延迟。浏览器通过ffmpeg软解码,对于分辨率大,码流大的情况或多路视频时,还是会出现性能不足的情况。浏览器已经可以支持对H265的硬解码,但是有浏览器的版本限制。

2023-07-26 07:24:07 3309 3

原创 webrtc 支持H265(二) ZLMediaKit通过datachannel通道转发视频流

ZLMediaKit中的datachannel的实现也是基于usrsctp库,所以首先需要编译安装usrsctp,步骤比较简单这里就不列举。usrsctp的IO模式被设置成非阻塞IO,默认的发送缓存的大小为262144。中缓存的GOP大小可能远远大于262144,在一开始转流时就填满了发送缓冲区,造成图像卡顿。rtp包的长度不会大于mute,一般是在1500个字节一下,远远小于这个大小。,在offer的sdp中有一个表示可以发送最大发送消息长度的属性行。在只有datachannel通道时,才从src的。

2023-06-28 07:53:57 4308 10

原创 webrtc支持H265(一)webrtc datachannel的特性

但是这种缓存机制又无法优化,http-flv基于tcp协议,播放器的实现必然需要引入缓存来兼容tcp 协议流的特性,因为应用层无法预测什么时候有数据,数据有多少,所以必须有个缓存处理tcp协议上抛数据的抖动性,来保证播放的流畅。但是有这样一个问题:web 播放器通过http-flv拉h264或h265的流进行播放,有明显的延迟,即使在内网延迟也有2s,通过调试发现,主要是web播放器的缓存的机制导致。datachannel基于sctp协议,sctp协议是与udp,tcp同级的协议,属于传输层协议。

2023-06-21 20:41:25 5521 6

原创 连接器处理重复符号(二)具体不同地址的全局对象

方法,它将输出单例对象的地址。最终输出的结果是每个对象的地址都不相同。这显然不符合我们的预期。就好比原本有一个封装了日志功能的静态,被多个动态库链接使用,本意是都使用同一个日志全局对象输出日志,结果缺产生了多个日志对象,这显然是不符合业务需求的。,它会包含静态库中的所有符号,默认情况下这些静态库都会标示为导出符号,通过连接器脚本。在动态库,可执行程序中都调用了单例对象。,输出如下,全局对象的地址各不同。将这些静态库符号隐藏,只导出符号。在下面这个例子中,可执行程序。,把它编译为一个静态库。

2023-05-02 11:26:10 762

原创 连接器重复符号处理(一)动态库重复符号处理规则

在日常开发工作中,经常会遇到符号重复定义的问题,这篇文章主要描述的是链接器在处理重复符号时的规则。在解析引用的过程中,最常发生的问题就是会出现重复符号,该问题发生在链接的最后阶段,具体为在所有可用符号列表中包含两个甚至更多同名符号,连接器就会报错,一般如下错误:./libsecond.a(secondfile.o):在函数‘duplicateFunction(int)’中:/root/test/cf/secondfile.cpp:6: duplicateFunction(int) 的多重定义。

2023-04-24 16:12:31 2124

原创 C/C++程序编译与链接(五) 定位库文件

只有动态库在程序运行时加载,静态库是构建时就已经链接到程序中。

2023-03-21 19:07:56 371

原创 webrtc中的线程(二)ProcesThread

所以它也是一个异步任务队列。它也是一个接口,具体实现类为。在Pacing,audio 模块都有用到,主要用法就是注册。不同,它并没有直接封住操作系统的线程类API,而是使用了。主要功能方法,就是往Module list中插入或删除。实现还是比较简单,就是依次执行几个任务队列中的任务。在webrtc中另外一个用的比较多的线程对象是。就是驱动队列的事件:当队列为空时,线程阻塞在。因为它是一个异步任务队列,它内部的队列就是。,它主要用于执行定时任务。是定时任务队列,执行定时任务队列是。

2023-03-13 08:02:21 402

原创 C/C++程序编译与链接(四) 创建动态库

其实站在开发者的角度,认为API与ABI是应该等价的,代码里的接口匹配,难道编译后,二进制文件中的接口对应的符号还不匹配吗?是的,对C++来说是要需要关注这些问题。

2023-03-11 10:01:58 1802

原创 C/C++程序编译与链接(三) 动态库的概念

对一些核心动态库(比如libc.so,libstd++.so等),这些都不是问题,因为这些库的位置,都已经被预先内置到系统中。但是对我们自己依赖动态库的程序,要想运行必须有两点:1. 操作系统中有程序需要的动态库。构建动态库生成的二进制文件本质上与可执行文件是相同的,唯一的区别在与动态库缺少了让其独立执行的启动程例程。运行时需要将可执行程序的符号正确解析到正确的地址上,这个地址是动态库所映射到进程内存映射中的地址。与路径一样,对操作系统自身的功能动态库,版本都是适配于操作系统的最合适的版本。

2023-03-06 08:22:45 498

原创 webrtc中的线程(一) rtc::Thread

是webrtc中最重要的线程类型。它与WebRtc库的实现深度结合。线程类型,主要是用作执行一些定时任务。这篇文章将介绍rtc::Thread及它在WebRtc中的使用。的线程模型如下:不仅仅是只产生一个线程,它还包含一个队列**(message list)**,将它称为异步任务队列更适合。它的基本功能就是在线程中执行任务队列中的任务。它靠事件驱动,也就是说当中没有任务()时,它会阻塞在事件等待上,当有事件唤醒时后会继续在队列中去任务执行。在图中可以看到它可以处理IO事件,这里的IO事件就是网络数据的收发

2023-03-04 08:26:32 1453

原创 C/C++程序编译与链接(二) 静态库的概念及使用

静态库和动态库是我们都非常熟悉的概念,它们的产生根本目的就是为了代码重用。我们平常在工作中也会使用各种库,有静态库,动态库。虽然它们的目的都一致的,但是两种形式的库还是有本质上的区别,静态库是一种比较原始,简单的代码复用方式,而动态库相对就复杂些。所以如果静态库中某个方法或变量变动,意味着整个客户程序都需要重新链接,不管客户程序是否有改动(即使只是实现方式的变动,而不是方法名字,签名参数的变动)。我们有时需要在传递给链接器的静态库多次添加同一个静态库。参数是指定库的路径,静态库是在当前目录下,所以是。

2023-02-28 08:28:46 695

原创 C/C++程序编译与链接(一) 编译与链接的概念

编译器本质上是将源代码中的高级语言翻译成低级语言,比如翻译成intel x86平台的汇编代码。上面简单的描述编译器的主要工作后,可以体会到编译器的复杂性,通常一个大型的C/C++项目有成千上万上个源文件,源文件间的调用关系错中复杂,编译器生成正确的汇编代码,要理解这些调用关系产生正确符号地址等,再生成正确的执行文件,还要讲究速度。这样简单的想想都很复杂。平常我们认为C/C++复杂,认为它们是比较低级的语言,但是在它们背后,编译器还是做了大量的工作。那么对python,java这样简洁,高效的语言。

2023-02-27 09:52:28 2400

原创 手把手教你实现buffer(四)——webrtc中的CopyOnWriteBuffer

的实现基于Buffer,在功能上强于Buffer。我们也可以根据业务的需求,基于Buffer封装自己的Buffer类。

2022-11-02 10:07:50 614

原创 手把手教你实现buffer(三)——接口及自动扩容

但是buffer还是有特定的使用场景,也需要一些基本的,通用的,易用的接口。的中内容,就需要提供这样的接口,所以使用时一点要注意不要破坏内存,比如写了大于容量的数据量等。定义在buffer.h文件中,在前一篇文章已经贴出,下面是buffer.cpp的代码。内容管理机制的接口,可以直接往内存中读写数据,权限太大。写入数据时,如果当前的容量不够,则会再次分配内存,扩大容量。重载了两种不同形式的下标操作符,前面一个是返回。位置的引用,可以直接更改数据。内部内存的地址,并且可以直接读写数据。指针,只可读,不可写。.

2022-08-08 09:33:24 1062

原创 手把手教你实现buffer(二)——内存管理及移动语义

禁止拷贝,通过是构造函数,复制构造函数,赋值操作符号来实现。类,它是一个非常典型的基础buffer封装,我们来通过分析它的实现,来学习要如何实现一个buffer。多引用几次,引用关系就会混乱了,很容易造成问题,比如内存无法释放;在C++中最直观的语义就是引用语义,因为它代表一块内存空间。但是这种引用语义,很难区分所有权,即是谁需要对这块内存负责(负责分配,负责释放),这种语义的。移动赋值运算符的逻辑跟移动构造函数的相同,将资源转移,将原对象置为无效。给到了所构造的对象,而原对象的。时,内存会自动释放。...

2022-08-01 18:57:19 1187

HK 28181 PS流解包代码

HK 28181 PS流解包代码,可以提取出PS流中视频数据,音频数据

2018-12-21

从rtp包中提取opus及h265码流的小工具

可以在pcap抓包文件中提取指定ssrc rtp的h265或opus码流

2018-07-27

Directshow视频采集,支持图像预览,支持根据策略设置分辨率及帧率

1. 采集模式为回调模式,默认视频格式为RGB24。 2. 支持设置采集的视频数据的分辨率及帧率,支持以预定义的策略设置采集的分辨率。 3. 支持视频预览。 4. 支持检索系统中可用的摄像头。 5. 支持打开指定的摄像头。

2018-03-20

HK_28181摄像头PS流mpg文件

HK 28181摄像头PS流mpg文件,视频格式为h264。HK 28181摄像头PS流mpg文件,视频格式为h264

2017-10-20

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除