ffmpeg 获取 rtsp 视频流 c++ 代码实现
时间: 2023-08-12 20:18:40 浏览: 159
C++封装FFMPEG拉取RTSP的音视频流接口类
5星 · 资源好评率100%
以下是一个简单的 C++ 代码示例,用于使用 FFmpeg 获取 RTSP 视频流:
```c++
extern "C"
{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libavutil/avutil.h"
}
int main(int argc, char* argv[])
{
avformat_network_init(); // 初始化网络
AVFormatContext* pFormatContext = NULL;
// 打开 RTSP 流
if (avformat_open_input(&pFormatContext, "rtsp://xxx.xxx.xxx.xxx:xxxx", NULL, NULL) != 0)
{
printf("打开 RTSP 流失败!\n");
return -1;
}
printf("打开 RTSP 流成功!\n");
// 查找 RTSP 流信息
if (avformat_find_stream_info(pFormatContext, NULL) < 0)
{
printf("查找 RTSP 流信息失败!\n");
return -1;
}
printf("查找 RTSP 流信息成功!\n");
// 找到视频流
int videoStream = -1;
for (int i = 0; i < pFormatContext->nb_streams; i++)
{
if (pFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStream = i;
break;
}
}
if (videoStream == -1)
{
printf("找不到视频流!\n");
return -1;
}
printf("找到视频流!\n");
// 获取解码器
AVCodecParameters* pCodecParameters = pFormatContext->streams[videoStream]->codecpar;
AVCodec* pCodec = avcodec_find_decoder(pCodecParameters->codec_id);
if (pCodec == NULL)
{
printf("找不到解码器!\n");
return -1;
}
printf("找到解码器!\n");
// 创建解码器上下文
AVCodecContext* pCodecContext = avcodec_alloc_context3(pCodec);
if (avcodec_parameters_to_context(pCodecContext, pCodecParameters) != 0)
{
printf("创建解码器上下文失败!\n");
return -1;
}
// 打开解码器
if (avcodec_open2(pCodecContext, pCodec, NULL) < 0)
{
printf("打开解码器失败!\n");
return -1;
}
printf("打开解码器成功!\n");
// 创建 AVFrame
AVFrame* pFrame = av_frame_alloc();
// 创建 AVPacket
AVPacket* pPacket = av_packet_alloc();
// 读取视频帧
int ret = 0;
while (av_read_frame(pFormatContext, pPacket) >= 0)
{
// 如果不是视频流,跳过
if (pPacket->stream_index != videoStream)
{
av_packet_unref(pPacket);
continue;
}
// 解码视频帧
ret = avcodec_send_packet(pCodecContext, pPacket);
if (ret < 0)
{
printf("解码视频帧失败!\n");
break;
}
while (ret >= 0)
{
ret = avcodec_receive_frame(pCodecContext, pFrame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
{
break;
}
else if (ret < 0)
{
printf("解码视频帧失败!\n");
break;
}
// 处理视频帧
printf("处理视频帧:%lld\n", pFrame->pts);
}
av_packet_unref(pPacket);
}
// 释放资源
av_frame_free(&pFrame);
av_packet_free(&pPacket);
avcodec_close(pCodecContext);
avcodec_free_context(&pCodecContext);
avformat_close_input(&pFormatContext);
avformat_free_context(pFormatContext);
avformat_network_deinit();
return 0;
}
```
在代码中,我们首先使用 `avformat_open_input()` 函数打开 RTSP 流,并使用 `avformat_find_stream_info()` 函数查找流信息。接着,我们找到视频流并获取解码器。然后,我们创建解码器上下文并打开解码器。最后,我们使用 `av_read_frame()` 函数读取视频帧,并使用解码器解码每一帧。在处理完视频帧后,我们释放资源,关闭解码器和输入流。
阅读全文