21|如何实现视频录制器的底层模块?(下)
展晓凯
你好,我是展晓凯。今天我们一起来学习视频录制器底层核心模块的实现。
上节课我们一起实现了视频录制器中的音频模块,把人声和伴奏的 PCM 数据放到了 PCM 队列中。这节课我们会先构造出音频编码器,把 PCM 数据编码成 AAC 的包放到音频队列里,然后进入视频模块的学习,视频模块的目标是把采集到视频帧编码成 H264 的包放到视频队列里。
音频编码模块的实现
我们先来看音频编码模块,输入是从 PCM 音频队列里获取的 PCM 数据,输出会放到另外一个 AAC 格式的音频队列中。这节课的重点是把这个编码器集成到整个系统中,这里我们会以软件编码为例来讲解。如果你有兴趣,还可以自己把硬件编码的实现集成到这个视频录制器项目中。
音频的编码应该也放到一个单独的线程里,所以我们建立一个类 AudioEncoderAdapter,利用 PThread 维护一个编码线程,不断从音频队列里取出 PCM 数据,然后调用编码器把这些数据编码成 AAC 数据,最后把 AAC 数据封装成 AudioPacket 数据结构,并放入 AAC 的队列里。其中编码器是我们自己封装的一个 AudioEncoder 类,它是在第 12 节课编码器类的基础上进行改造的,下面我们来逐一看一下各个类的具体实现。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入介绍了视频录制器的底层模块实现,包括音频编码模块和视频模块的详细实现原理。在音频编码模块中,作者讲解了编码器的改造和编码器适配器的实现,包括初始化方法、编码线程的工作流程以及销毁方法。在视频模块中,重点介绍了视频队列的实现和将编码后的H264数据放入队列的过程。文章以软件编码为例,详细讲解了音频编码和视频编码的实现原理,对于想要深入了解视频录制器底层核心模块的读者来说,是一篇非常有价值的技术文章。同时,还介绍了Android平台和iOS平台的画面编码后入队的实现方法。整篇文章内容丰富,对于从事相关领域的技术人员具有很高的参考价值。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《快手 · 移动端音视频开发实战》,新⼈⾸单¥59
《快手 · 移动端音视频开发实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(2)
- 最新
- 精选
- peter请教老师几个问题啊: Q1:编码器的输入是什么? 代码“audioEncoder->encode(&audioPacket);”,其中的audioPacket是存放编码后的数据,那编码器需要的PCM数据从哪里来的? Q2:03课的AudioTrack例子,提到“decoder 是一个decoder实例,构建这个decoder实例比较简单,在这里我就不详细介绍了”。我不知道该用哪个解decoder,就创建了一个MediaCodec: MediaCodec.createDecoderByType(“audio/mpeg”); 线程中:decoder.readSamples(samples);。 但是,MediaCodec并没有readSamples这个函数? 请问:decoder.readSamples只是一个伪代码吗?还是说某一个类有这个函数?(安卓平台除了MediaCodec还有其他的系统decoder吗?) Q3:华为安卓10上不能用FFmpeg播放音频。 华为手机,安卓10,用FFmpeg,能够将两个音频合并,然后可以用原生的MediaPlayer将合并后的音频播放出来。但我想尝试用FFmpeg播放,本来以为很简单,但怎么都播放不出来。 为什么啊? 方法1:用RxFFmpegPlayer,听不到声音 RxFFmpegPlayer fFmpegPlayer = new RxFFmpegPlayerImpl(); fFmpegPlayer.play(musicFilePath,false); 方法2:用RxFFmpegPlayerView,还是听不到声音 RxFFmpegPlayerView rxFFmpegPlayerView = new RxFFmpegPlayerView(MainActivity2.this); rxFFmpegPlayerView.switchPlayerCore(RxFFmpegPlayerView.PlayerCoreType.PCT_RXFFMPEG_PLAYER); Log.d(TAG,"before play, get volume = " + rxFFmpegPlayerView.getVolume()); //缺省就是100 rxFFmpegPlayerView.setVolume(100);//此处没有必要 RxFFmpegPlayerController controller = new RxFFmpegPlayerControllerImpl(MainActivity2.this); rxFFmpegPlayerView.setController(controller, MeasureHelper.FitModel.FM_DEFAULT); rxFFmpegPlayerView.play(musicFilePath,false); 注意注意:上面用到的”decoder”是指”JieMaQi”,如果用中文,会被当做敏感词而不能提交。
作者回复: A1: 输入就是PCM,是从PCM队列中取出来封装到AudioPacket这个结构体中,建议中秋之后结合源码来看。 A2: 这个decoder是一个自己封装的Native层的【jiema】控制器,readSamples也是自己封装的方法,内部会从队列中读取数据,而队列中的数据是这个【jiema】控制器开了一个线程调用ffmpeg底层【jiema】器将数据【jiema】为PCM数据。也建议中秋之后结合源码进行学习; A3: 这里你使用的并不是原始的ffmpeg哈,应该是一个基于ffmpeg的封装的库,如果此段代码在别的地方都可以运行但是仅仅在华为安卓10上不能播放的话,建议看看权限之类的。
2022-09-09归属地:北京 - 我的無力雙臂有示例demo吗 求分享
作者回复: 有的,中秋节以后更新到github。
2022-09-09归属地:北京
收起评论