使用opencv + ffmpeg 开发视频播放器Demo

时间:2024-04-10 07:19:36
#include <opencv2/opencv.hpp> #include <opencv2/highgui.hpp> #include <opencv2/videoio.hpp> extern "C" { #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #include <libswscale/swscale.h> } int main() { // 初始化 FFmpeg av_register_all(); // 打开视频文件 AVFormatContext* formatContext = avformat_alloc_context(); if (avformat_open_input(&formatContext, "video.mp4", NULL, NULL) != 0) { std::cout << "无法打开视频文件" << std::endl; return -1; } // 获取视频流信息 if (avformat_find_stream_info(formatContext, NULL) < 0) { std::cout << "无法获取视频流信息" << std::endl; return -1; } // 寻找视频流索引 int videoStreamIndex = -1; for (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::cout << "无法找到视频流" << std::endl; return -1; } // 获取视频解码器 AVCodecParameters* codecParameters = formatContext->streams[videoStreamIndex]->codecpar; AVCodec* codec = avcodec_find_decoder(codecParameters->codec_id); AVCodecContext* codecContext = avcodec_alloc_context3(codec); avcodec_parameters_to_context(codecContext, codecParameters); avcodec_open2(codecContext, codec, NULL); // 创建窗口 cv::namedWindow("Video Player", cv::WINDOW_NORMAL); // 读取视频帧 AVPacket packet; AVFrame* frame = av_frame_alloc(); while (av_read_frame(formatContext, &packet) >= 0) { if (packet.stream_index == videoStreamIndex) { avcodec_send_packet(codecContext, &packet); avcodec_receive_frame(codecContext, frame); // 转换 AVFrame 到 OpenCV Mat cv::Mat image(cv::Size(frame->width, frame->height), CV_8UC3, frame->data[0], frame->linesize[0]); // 显示图像 cv::imshow("Video Player", image); cv::waitKey(25); } av_packet_unref(&packet); } // 清理 av_frame_free(&frame); avcodec_close(codecContext); avformat_close_input(&formatContext); return 0; }