每天一点点音视频相关_ffmpeg解包数据示例 part1

今天上午因为我个来,没有写,牵挂了一天,补上。

ffmpeg 可以说是音视频领域的明星, 使用 C 写的, 跨平台, 强大。

今天是演示 ffmpeg 的解包, 本来想在 Linux 上测试, 结果, 很痛苦。想用 gradle
构建, 但是 java 环境不对, java环境对了, 发现 gradle 对 c++ 的构建有点鸡肋, 没深入研究, 以后再说吧。

简单粗暴,直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

// 创建一个 avformat 的数据结构, 存储视频文件的信息
AVFormatContext *format_context = avformat_alloc_context();

// 打开文件, 读取头信息存入 format_context
if (avformat_open_input(format_context, url, NULL, NULL) != 0) {
LOGE("can not open url\n");
ret = 100;
goto fail;
}

// 以后就只用 format_context 了, 这里查找流信息
if (avformat_find_stream_info(format_context, NULL) < 0) {
LOGE("can not find stream\n");
ret = 101;
goto fail;
}

// 找到视频流
int video_index = av_find_best_stream(format_context, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (video_index != AVERROR_STREAM_NOT_FOUND) {
LOGI("video_index pd->av_track_flags:%d", i);
}

// 找到音频流
int audio_index = av_find_best_stream(pd->format_context, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
if (audio_index != AVERROR_STREAM_NOT_FOUND) {
LOGI("audio_index pd->av_track_flags:%d", i);
}

AVStream *v_stream = format_context->streams[video_index];

avformat_close_input(&format_context)

注释基本白费, 基本的流程就是创建一个数据结构, 然后执行几个方法, 来初始化数据结构,将视频文件的信息存入其中, 以后所有的操作,只用这个数据机构就行了。

还可以知道, 一个视频文件, 里面是分视频流和音频流的, 实际上,一个视频可能会有多个视频轨道,音频轨道。

就这个小模块, 还没说完, 明天说: 每天一点点音视频相关_ffmpeg解包数据示例_part2。

值得强调的是,我发现C语言的模式了:

  1. 定义一个数据结构
  2. 调用方法, 填入数据
  3. 以后, 都用这个数据结构了, 对数据做各种操作

当然, 这是标准的面向对象的方式吧, 或者叫 “基于数据结构的算法”