概述
项目实践中涉及到使用ffmpeg进行推流和拉流操作,本文主要对一些基本操作做一个学习总结,后续再学习其源码架构;总结方法遵循实现功能配合函数具体实现
基本使用
拉流
cpp
avformat_network_init();
//日志输出等级
set_ffmpeg_log_level();
AVFormatContext *fmt_ctx = NULL;
AVPacket *pkt = av_packet_alloc();
if (avformat_open_input(&fmt_ctx, "rtsp://127.0.0.1/live/test", NULL, NULL) < 0) {
fprintf(stderr, "无法打开输入文件\n");
return -1;
}
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
fprintf(stderr, "无法获取流信息\n");
return -1;
}
int video_stream_idx = -1;
for (int i = 0; i < fmt_ctx->nb_streams; i++) {
if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
video_stream_idx = i;
break;
}
}
if (video_stream_idx == -1) {
fprintf(stderr, "未找到视频流\n");
return -1;
}
while (av_read_frame(fmt_ctx, pkt) >= 0) {
if (pkt->stream_index == video_stream_idx) {
process_packet(pkt);
}
av_packet_unref(pkt);
}
av_packet_free(&pkt);
avformat_close_input(&fmt_ctx);
avformat_open_input
主要就是打开一个流,一般用到的是RTSP流地址
cpp
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt
, AVDictionary **options);
参数说明:
- ps :指向
AVFormatContext
指针的指针,AVFormatContext
是 FFmpeg 用来保存流媒体格式信息的结构体,包含了与流格式相关的详细信息,比如流的类型、码流、解码器、流的数量等。在函数调用后,这个指针会指向包含所有文件格式信息的上下文。 - url :输入流的 URL 或路径。对于 RTSP 流,它可能是一个 RTSP 地址,如
rtsp://example.com/stream
- fmt :输入格式,通常是
NULL
,FFmpeg 会自动选择合适的格式。如果指定了格式,FFmpeg 将强制使用这个格式 - options:一个可选的字典,用来设置额外的选项。可以设置输入流的一些参数,如缓冲区大小、最大延迟等
返回值:
- 0:成功打开输入流
- 负值:失败,返回错误代码
avformat_find_stream_info
解析流的内容,主要用于后续的解码播放操作。
cpp
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
参数说明:
- ic :指向
AVFormatContext
结构体的指针,包含了与媒体文件或流的格式相关的信息。这个结构体通常在调用avformat_open_input
时已经创建并初始化。 - options :一个可选的字典,包含额外的选项,例如超时、缓冲区大小等参数,通常为
NULL
。
返回值:
- 0:成功提取流信息。
- 负值:失败,返回错误代码
av_read_frame
从RTSP流中读取数据包,一般该数据包中都是压缩了数据,其中包含音视频等数据
- 输入参数:
AVFormatContext *fmt_ctx
,媒体流的上下文。 - 输出: 返回值是一个整数,成功时返回 0,失败时返回负值。数据包会存储在
AVPacket *pkt
中,pkt
包含读取到的音视频数据
AVFormatContext
该结构体中主要用于存储流媒体格式信息
cpp
typedef struct AVFormatContext {
const AVClass *av_class;
unsigned int flags;
AVInputFormat *iformat;
AVOutputFormat *oformat;
int nb_streams;
AVStream **streams;
AVCodecContext *codec;
// 其他字段...
} AVFormatContext;
- av_class :FFmpeg 的类系统用于描述
AVFormatContext
的类信息。 - flags :流的标志位,通常是
0
或其他标志。 - iformat:指向输入流格式的指针。
- oformat:指向输出流格式的指针。
- nb_streams:流的数量,通常是音频和视频流的总数。
- streams :指向
AVStream
结构体数组的指针,每个AVStream
对应一个音频或视频流。 - codec:指向解码器上下文的指针,包含解码器的设置和状态。