写一个使用ffmpeg 5.1.2版本播放rtsp流,vs2019可以编译通过的播放器
时间: 2024-04-04 11:32:35 浏览: 217
C#基于FFMpeg.AutoGen的RTSP拉流播放
好的,我可以为您提供一个简单的使用FFmpeg 5.1.2版本播放rtsp流的播放器示例,但是需要您自行编译FFmpeg库。
首先,您需要从FFmpeg官网(https://ffmpeg.org/download.html)下载FFmpeg 5.1.2版本的源代码,并按照官方指南进行编译。
接下来,您可以使用以下示例代码进行播放:
```c++
#include <iostream>
#include <string>
#include <chrono>
#include <thread>
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>
#include <SDL2/SDL.h>
}
int main(int argc, char* argv[])
{
// 初始化FFmpeg库
av_register_all();
avformat_network_init();
// 创建AVFormatContext
AVFormatContext* pFormatCtx = avformat_alloc_context();
if (!pFormatCtx) {
std::cerr << "Failed to allocate AVFormatContext." << std::endl;
return EXIT_FAILURE;
}
// 打开rtsp流
std::string rtspUrl = "rtsp://example.com/stream";
if (avformat_open_input(&pFormatCtx, rtspUrl.c_str(), nullptr, nullptr) != 0) {
std::cerr << "Failed to open rtsp stream." << std::endl;
return EXIT_FAILURE;
}
// 获取流信息
if (avformat_find_stream_info(pFormatCtx, nullptr) < 0) {
std::cerr << "Failed to get stream information." << std::endl;
return EXIT_FAILURE;
}
// 查找视频流
int videoStreamIndex = -1;
for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
videoStreamIndex = i;
break;
}
}
if (videoStreamIndex == -1) {
std::cerr << "Failed to find video stream." << std::endl;
return EXIT_FAILURE;
}
// 获取视频解码器
AVCodec* pCodec = avcodec_find_decoder(pFormatCtx->streams[videoStreamIndex]->codecpar->codec_id);
if (!pCodec) {
std::cerr << "Failed to find video decoder." << std::endl;
return EXIT_FAILURE;
}
// 创建AVCodecContext
AVCodecContext* pCodecCtx = avcodec_alloc_context3(pCodec);
if (!pCodecCtx) {
std::cerr << "Failed to allocate AVCodecContext." << std::endl;
return EXIT_FAILURE;
}
// 设置AVCodecContext参数
if (avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStreamIndex]->codecpar) < 0) {
std::cerr << "Failed to set AVCodecContext parameters." << std::endl;
return EXIT_FAILURE;
}
// 打开视频解码器
if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0) {
std::cerr << "Failed to open video decoder." << std::endl;
return EXIT_FAILURE;
}
// 创建AVFrame和AVPacket
AVFrame* pFrame = av_frame_alloc();
if (!pFrame) {
std::cerr << "Failed to allocate AVFrame." << std::endl;
return EXIT_FAILURE;
}
AVPacket* pPacket = av_packet_alloc();
if (!pPacket) {
std::cerr << "Failed to allocate AVPacket." << std::endl;
return EXIT_FAILURE;
}
// 创建SwsContext
SwsContext* pSwsCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, SWS_BILINEAR, nullptr, nullptr, nullptr);
if (!pSwsCtx) {
std::cerr << "Failed to create SwsContext." << std::endl;
return EXIT_FAILURE;
}
// 初始化SDL库
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
std::cerr << "Failed to initialize SDL library." << std::endl;
return EXIT_FAILURE;
}
// 创建SDL窗口
SDL_Window* pWindow = SDL_CreateWindow("RTSP Player", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
pCodecCtx->width, pCodecCtx->height, SDL_WINDOW_SHOWN);
if (!pWindow) {
std::cerr << "Failed to create SDL window." << std::endl;
return EXIT_FAILURE;
}
// 创建SDL渲染器
SDL_Renderer* pRenderer = SDL_CreateRenderer(pWindow, -1, SDL_RENDERER_ACCELERATED);
if (!pRenderer) {
std::cerr << "Failed to create SDL renderer." << std::endl;
return EXIT_FAILURE;
}
// 创建SDL纹理
SDL_Texture* pTexture = SDL_CreateTexture(pRenderer, SDL_PIXELFORMAT_RGB24,
SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height);
if (!pTexture) {
std::cerr << "Failed to create SDL texture." << std::endl;
return EXIT_FAILURE;
}
// 读取视频帧
while (av_read_frame(pFormatCtx, pPacket) >= 0) {
if (pPacket->stream_index == videoStreamIndex) {
// 解码视频帧
if (avcodec_send_packet(pCodecCtx, pPacket) == 0) {
while (avcodec_receive_frame(pCodecCtx, pFrame) == 0) {
// 转换帧格式
AVFrame* pFrameRGB = av_frame_alloc();
if (!pFrameRGB) {
std::cerr << "Failed to allocate AVFrame." << std::endl;
return EXIT_FAILURE;
}
av_image_alloc(pFrameRGB->data, pFrameRGB->linesize, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_RGB24, 1);
sws_scale(pSwsCtx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
// 显示帧
SDL_UpdateTexture(pTexture, nullptr, pFrameRGB->data[0], pFrameRGB->linesize[0]);
SDL_RenderClear(pRenderer);
SDL_RenderCopy(pRenderer, pTexture, nullptr, nullptr);
SDL_RenderPresent(pRenderer);
// 释放帧内存
av_frame_free(&pFrameRGB);
}
}
}
av_packet_unref(pPacket);
// 暂停一段时间以控制帧率
std::this_thread::sleep_for(std::chrono::milliseconds(33));
}
// 释放资源
av_packet_free(&pPacket);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
sws_freeContext(pSwsCtx);
SDL_DestroyTexture(pTexture);
SDL_DestroyRenderer(pRenderer);
SDL_DestroyWindow(pWindow);
SDL_Quit();
return EXIT_SUCCESS;
}
```
请注意,此示例仅适用于Windows平台,并使用SDL库进行视频显示。如果您在其他平台上运行此示例,您需要相应地更改代码以适应不同的平台和库。
阅读全文