ubuntu中 使用C++ FFmpeg拉取RTSP视频流

ops/2025/2/9 5:32:46/

在C++中使用FFmpeg拉取RTSP视频流涉及多个步骤,包括初始化FFmpeg库、打开RTSP流、读取帧数据等。以下是一个简单的示例代码,展示如何使用FFmpeg库拉取RTSP视频流并解码视频帧。

1. 安装FFmpeg库

首先,确保你已经安装了FFmpeg库。你可以通过以下命令在Ubuntu上安装FFmpeg开发库:

sudo apt-get install libavformat-dev libavcodec-dev libavutil-dev libswscale-dev

2. 示例代码

extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
}#include <iostream>int main() {
// 初始化FFmpeg库
av_register_all();
avformat_network_init();AVFormatContext* formatContext = avformat_alloc_context();
if (!formatContext) {
std::cerr << "Could not allocate format context" << std::endl;
return -1;
}// 打开RTSP流
const char* rtspUrl = "rtsp://your_rtsp_stream_url";
if (avformat_open_input(&formatContext, rtspUrl, nullptr, nullptr) != 0) {
std::cerr << "Could not open RTSP stream" << std::endl;
return -1;
}// 获取流信息
if (avformat_find_stream_info(formatContext, nullptr) < 0) {
std::cerr << "Could not find stream information" << std::endl;
return -1;
}// 查找视频流
int videoStreamIndex = -1;
for (unsigned int i = 0; i < formatContext->nb_streams; i++) {
if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStreamIndex = i;
break;
}
}if (videoStreamIndex == -1) {
std::cerr << "Could not find video stream" << std::endl;
return -1;
}// 获取视频流的编解码器参数
AVCodecParameters* codecParameters = formatContext->streams[videoStreamIndex]->codecpar;// 查找解码器
AVCodec* codec = avcodec_find_decoder(codecParameters->codec_id);
if (!codec) {
std::cerr << "Unsupported codec" << std::endl;
return -1;
}// 创建解码器上下文
AVCodecContext* codecContext = avcodec_alloc_context3(codec);
if (!codecContext) {
std::cerr << "Could not allocate codec context" << std::endl;
return -1;
}// 将编解码器参数复制到解码器上下文
if (avcodec_parameters_to_context(codecContext, codecParameters) < 0) {
std::cerr << "Could not copy codec parameters to context" << std::endl;
return -1;
}// 打开解码器
if (avcodec_open2(codecContext, codec, nullptr) < 0) {
std::cerr << "Could not open codec" << std::endl;
return -1;
}// 分配帧和包
AVFrame* frame = av_frame_alloc();
AVPacket* packet = av_packet_alloc();
if (!frame || !packet) {
std::cerr << "Could not allocate frame or packet" << std::endl;
return -1;
}// 读取帧
while (av_read_frame(formatContext, packet) >= 0) {
if (packet->stream_index == videoStreamIndex) {
// 解码视频帧
if (avcodec_send_packet(codecContext, packet) == 0) {
while (avcodec_receive_frame(codecContext, frame) == 0) {
// 在这里处理解码后的帧(frame)
std::cout << "Decoded frame: " << frame->pts << std::endl;
}
}
}
av_packet_unref(packet);
}// 释放资源
av_frame_free(&frame);
av_packet_free(&packet);
avcodec_free_context(&codecContext);
avformat_close_input(&formatContext);
avformat_free_context(formatContext);return 0;
}

3. 编译代码

使用以下命令编译代码:

g++ -o rtsp_stream rtsp_stream.cpp -lavformat -lavcodec -lavutil -lswscale

4. 运行程序

运行编译后的程序:

./rtsp_stream

5. 代码说明

  • avformat_open_input:打开RTSP流。
  • avformat_find_stream_info:获取流信息。
  • avcodec_find_decoder:查找解码器。
  • avcodec_open2:打开解码器。
  • av_read_frame:读取帧数据。
  • avcodec_send_packetavcodec_receive_frame:解码视频帧。

6. 注意事项

  • 确保RTSP URL正确。
  • 处理解码后的帧时,可以根据需要进行进一步处理,如显示、保存等。
  • 在实际应用中,可能需要处理更多的错误情况和资源管理。

通过以上步骤,你可以在C++中使用FFmpeg拉取RTSP视频流并解码视频帧。


http://www.ppmy.cn/ops/156901.html

相关文章

全面的生成式语言模型学习路线

设计了一套全面的生成式语言模型学习路线&#xff0c;包含基础储备、核心知识学习、实践应用和进阶提升四个阶段&#xff0c;你可以根据自身情况进行调整。 第一阶段&#xff1a;基础储备&#xff08;1 - 2个月&#xff09; 数学基础 线性代数 学习向量、矩阵的基本运算&…

腾讯社招流程记录

bg&#xff1a;24届985硕士&#xff0c;四个多月被裁&#xff0c;后端开发 12.20上午投递&#xff0c;腾讯csig云计算后台 12.20下午约面 12.24晚上一面 1h45min 12.26中午约二面 12.26晚上二面 1h10min 目前状态还在面试流程中 ---------------------- 三面还没约&#xff0…

缓存的今生今世

缓存是什么 了解缓存&#xff0c;首先要了解内存概念&#xff0c;毕竟缓存离不开内存。 内存又称内部存储器和主存储器(RAM)&#xff0c;内存条由内存芯片、电路板、金手指等部分组成。它与CPU之间的连通是通过总线完成&#xff0c;是CPU与外存的连通桥梁。计算机里所有的运算…

Qt之设置QToolBar上的按钮样式

通常给QAction设置icon后,菜单栏的菜单项和工具栏(QToolBar)上对应的按钮会同时显示该icon。工具栏还可以使用setToolButtonStyle函数设置按钮样式,其参数为枚举值: enum ToolButtonStyle {ToolButtonIconOnly,ToolButtonTextOnly,ToolButtonTextBesideIcon,ToolButtonTe…

【C语言】指针详细解读3

1. 数组名的理解 我们使用指针一般访问数组内容时&#xff0c;我们可能会这样写&#xff1a; int arr[10] {1,2,3,4,5,6,7,8,9,10}; int *p &arr[0]; 这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址&#xff0c;但是其实数组名本来就是地址&#xff0c;⽽…

Java JDK17 API 离线文档下载

Java JDK17 API 离线文档下载 JavaJDK17API离线文档下载 本仓库提供了一个方便的资源文件下载&#xff0c;即 **Java JDK17 API 离线文档**。该文档是Java开发者在离线环境下查阅JDK17 API的必备工具。无论你是Java初学者还是经验丰富的开发者&#xff0c;这份离线文档都能帮助…

基于springboot+vue的图书管理系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

javaEE初阶————多线程初阶(1)

多线程初阶———— 1&#xff0c;认识线程 1.1 概念 1&#xff09;线程是什么 线程就是一个“执行流”&#xff0c;可以理解为程序执行的最小单位&#xff1b; 可以看成轻量级的进程&#xff1b; 2&#xff09;为啥要有线程 “并发编程” 的需要&#xff0c;但是我们不…