C++调用ffmpeg库来实现将rtsp流服务器上的视频流拉取下来,并保存成MP4格式
1. 引入ffmpeg的Lib和头文件
2. 将程序运行环境放入ffmpeg动态库
2.代码实现
2.1 引入头文件
```bash
#include
#include
#include
extern "C" {
#include
#include
#include
#include
#include
#include
}
2.2 按步骤分解实现
av_log_set_level(AV_LOG_DEBUG); // 开启FFmpeg日志
av_log_set_level 是 FFmpeg 库中的一个重要函数,用于设置日志输出的级别。
level:这是一个整数类型的参数,用于指定日志的输出级别。FFmpeg 定义了多个日志级别常量,常见的级别及其含义如下:
AV_LOG_QUIET(值为 -8):不输出任何日志信息。
AV_LOG_PANIC(值为 0):输出非常严重的错误信息,程序可能无法继续运行。
AV_LOG_FATAL(值为 8):输出致命错误信息,程序可能会终止。
AV_LOG_ERROR(值为 16):输出普通错误信息。
AV_LOG_WARNING(值为 24):输出警告信息,提示可能存在的问题。
AV_LOG_INFO(值为 32):输出一般的信息,如编码器参数、文件信息等。
AV_LOG_VERBOSE(值为 40):输出详细的信息。
AV_LOG_DEBUG(值为 48):输出调试信息,包含大量的详细内容,通常用于开发和调试阶段。
AV_LOG_TRACE(值为 56):输出最详细的跟踪信息。
AVFormatContext* input_ctx = nullptr;
AVFormatContext* output_ctx = nullptr;
// 1. 初始化网络协议(必须!否则无法处理rtsp)
avformat_network_init();
avformat_network_init 是 FFmpeg 库中的一个重要函数,主要用于初始化网络相关的组件,以支持网络协议的使用,比如 RTSP、HTTP 等。
返回值:
- 成功:返回值为 0,表示网络初始化成功。
- 失败:返回一个负的错误码,指示初始化过程中出现了问题。
功能用途
在使用 FFmpeg 处理网络相关的音视频流时,例如从 RTSP 服务器拉取流、通过 HTTP 下载视频文件等,需要先调用 avformat_network_init 函数来初始化网络环境。它会初始化底层的网络库(如 socket 库等),确保后续的网络操作能够正常进行。
// 2. 打开输入流(RTSP)
AVDictionary* options = nullptr;
av_dict_set(&options, "rtsp_transport", "tcp", 0); // 强制使用TCP传输
av_dict_set(&options, "stimeout", "5000000", 0); // 设置超时5秒(单位微秒)
const char* input_url = "rtsp://127.0.0.1:554/your_stream_key";
int ret = avformat_open_input(&input_ctx, input_url, nullptr, &options);
if (ret < 0) {
//std::cerr << "无法打开输入流: " << av_err2str(ret) << std::endl;
return -1;
}
avformat_open_input 是 FFmpeg 库中一个非常关键的函数,主要用于打开输入的音视频文件或者网络流,为后续的音视频数据读取和处理做准备。
参数解释
AVFormatContext **ps
:
这是一个指向 AVFormatContext 指针的指针。AVFormatContext 是 FFmpeg 中一个非常重要的结构体,它包含了输入文件或流的全局信息,如文件格式、流信息等。函数会分配并初始化一个 AVFormatContext 结构体,并将其指针存储在 *ps 中。const char *url
:
输入文件或流的路径或 URL。如果是本地文件,就是文件的路径;如果是网络流,就是对应的网络地址,如 RTSP、HTTP 等协议的 URL。ff_const59 AVInputFormat *fmt
:
指定输入文件的格式。一般设置为 NULL,这样 FFmpeg 会自动探测输入文件的格式。如果你明确知道输入文件的格式,也可以传入对应的 AVInputFormat 指针。AVDictionary **options
:
一个指向 AVDictionary 指针的指针,用于传递一些额外的选项参数。例如,在打开 RTSP 流时,可以设置一些网络相关的参数。如果不需要额外的选项,可以设置为 NULL。
返回值
- 成功:返回值为 0,表示输入文件或流成功打开。
- 失败:返回一个负的错误码,指示打开过程中出现了问题。可以使用 av_err2str 函数将错误码转换为可读的错误信息。
// 3. 获取流信息
if (avformat_find_stream_info(input_ctx, nullptr) < 0) {
std::cerr << "无法获取流信息" << std::endl;
avformat_close_input(&input_ctx);
return -1;
}
avformat_find_stream_info 是 FFmpeg 库中一个用于获取输入文件或流详细信息的重要函数
参数解释
AVFormatContext *ic
:
指向 AVFormatContext 结构体的指针。AVFormatContext 包含了输入文件或流的全局信息,通常是在调用 avformat_open_input 函数成功打开输入文件或流后得到的。此函数会基于该上下文去分析流的详细信息。AVDictionary **options
:
一个指向 AVDictionary 指针的指针,用于传递额外的选项参数。这些选项可以影响信息查找的行为。若不需要额外选项,可将其设置为 NULL。
返回值
- 成功:返回值大于等于 0,表示成功获取到输入流的信息。
- 失败:返回一个负的错误码,代表在查找流信息过程中出现了问题。可以使用 av_err2str 函数将错误码转换为可读的错误信息。
功能
avformat_find_stream_info 函数的主要功能是读取输入文件或流的数据包,分析其中的信息,从而填充 AVFormatContext 结构体中关于流的详细信息。这些信息包括但不限于:
每个流的编解码器信息(如视频的 H.264、音频的 AAC 等)。
视频流的分辨率、帧率。
音频流的采样率、声道数等。
avformat_close_input 是 FFmpeg 库中用于关闭已打开的输入文件或流,并释放相关资源的重要函数。
// 4. 创建输出文件(MP4)
const char* output_filename = "output.mp4";
avformat_alloc_output_context2(&output_ctx, nullptr, nullptr, output_filename);
if (!output_ctx) {
std::cerr << "无法创建输出上下文" << std::endl;
avformat_close_input(&input_ctx);
return -1;
}