快手 · 移动端音视频开发实战
展晓凯
快手回森技术负责人
12246 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 25 讲
快手 · 移动端音视频开发实战
15
15
1.0x
00:00/00:00
登录|注册

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
立即购买
登录 后留言

全部留言(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归属地:北京
收起评论
显示
设置
留言
2
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部