QT+FFMPEG实现视频播放
阅读原文时间:2023年07月11日阅读:1

开发环境:MinGW+QT5.9+FFMPEG20190212

一、开发环境搭建

FFMPEG的开发环境部署比如容易,在官网下载库文件,然后在QT里面指定路径,把相关dll文件放到exe目录下就可以了,不需要根据开发工具重新编译。

(1)下载工具

https://ffmpeg.zeranoe.com/builds/下载对应版本。链接方式有三种,

Static:这个版本只包含了ffmpeg.exe、ffplay.exe、ffprobe.exe三个可执行程序,没有头文件和库文件。

Shared:这个版本包含了ffmpeg.exe、ffplay.exe、ffprobe.exe三个可执行程序和相关动态库文件。

Dev:开发版,这个包含了头文件和库文件。

我们需要下载Shared和Dev两个版本,Dev有我们程序开发需要的头文件和库文件,这里面包含的库是动态调用的,所依赖的动态库在Shared这个版本里面,所以两个版本都要下载。

(2)添加库

将下载的文件解压缩,然后新建一个QT工程,在pro添加lib目录和include目录的路径。

INCLUDEPATH +="E:\\Lib\\ffmpeg\\include"

LIBS += -LE:\Lib\ffmpeg\lib -lavutil -lavformat -lavcodec -lavdevice -lavfilter -lpostproc -lswresample -lswscale

然后将shared下的动态库添加到exe目录下。

二、代码实现播放功能

在界面上放置一个QLabel和QPushButton控件,当点击按钮时实现以下功能:

#include
extern "C"{
#include
#include
#include
#include
}
void Delay(int msec)
{
QTime dieTime = QTime::currentTime().addMSecs(msec);
while( QTime::currentTime() < dieTime )
QCoreApplication::processEvents(QEventLoop::AllEvents, );
}

void MainWindow::on_btnPlay_clicked()
{
AVFormatContext *pFormatCtx;
int i, videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame, *pFrameRGB;
unsigned char *out_buffer;
AVPacket *packet;
int ret, got_picture;
struct SwsContext *img_convert_ctx;

char filepath\[\] = "E:\\\\media\\\\1.avi";  
//初始化编解码库  
av\_register\_all();//创建AVFormatContext对象,与码流相关的结构。  
pFormatCtx = avformat\_alloc\_context();  
//初始化pFormatCtx结构  
if (avformat\_open\_input(&pFormatCtx, filepath, NULL, NULL) != ){  
    printf("Couldn't open input stream.\\n");  
    return ;  
}  
//获取音视频流数据信息  
if (avformat\_find\_stream\_info(pFormatCtx, NULL) < ){  
    printf("Couldn't find stream information.\\n");  
    return ;  
}  
videoindex = -;  
//nb\_streams视音频流的个数,这里当查找到视频流时就中断了。  
for (i = ; i < pFormatCtx->nb\_streams; i++)  
    if (pFormatCtx->streams\[i\]->codec->codec\_type == AVMEDIA\_TYPE\_VIDEO){  
        videoindex = i;  
        break;  
}  
if (videoindex == -){  
    printf("Didn't find a video stream.\\n");  
    return ;  
}  
//获取视频流编码结构  
pCodecCtx = pFormatCtx->streams\[videoindex\]->codec;  
//查找解码器  
pCodec = avcodec\_find\_decoder(pCodecCtx->codec\_id);  
if (pCodec == NULL){  
    printf("Codec not found.\\n");  
    return ;  
}  
//用于初始化pCodecCtx结构  
if (avcodec\_open2(pCodecCtx, pCodec, NULL) < ){  
    printf("Could not open codec.\\n");  
    return ;  
}  
//创建帧结构,此函数仅分配基本结构空间,图像数据空间需通过av\_malloc分配  
pFrame = av\_frame\_alloc();  
pFrameRGB = av\_frame\_alloc();  
//创建动态内存,创建存储图像数据的空间  
//av\_image\_get\_buffer\_size获取一帧图像需要的大小  
out\_buffer = (unsigned char \*)av\_malloc(av\_image\_get\_buffer\_size(AV\_PIX\_FMT\_RGB32, pCodecCtx->width, pCodecCtx->height, ));  
av\_image\_fill\_arrays(pFrameRGB->data, pFrameRGB->linesize, out\_buffer,  
    AV\_PIX\_FMT\_RGB32, pCodecCtx->width, pCodecCtx->height, );

packet = (AVPacket \*)av\_malloc(sizeof(AVPacket));  
//Output Info-----------------------------  
printf("--------------- File Information ----------------\\n");  
//此函数打印输入或输出的详细信息  
av\_dump\_format(pFormatCtx, , filepath, );  
printf("-------------------------------------------------\\n");  
//初始化img\_convert\_ctx结构  
img\_convert\_ctx = sws\_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix\_fmt,  
    pCodecCtx->width, pCodecCtx->height, AV\_PIX\_FMT\_RGB32, SWS\_BICUBIC, NULL, NULL, NULL);  
//av\_read\_frame读取一帧未解码的数据  
while (av\_read\_frame(pFormatCtx, packet) >= ){  
    //如果是视频数据  
    if (packet->stream\_index == videoindex){  
        //解码一帧视频数据  
        ret = avcodec\_decode\_video2(pCodecCtx, pFrame, &got\_picture, packet);  
        if (ret < ){  
            printf("Decode Error.\\n");  
            return ;  
        }  
        if (got\_picture){  
            sws\_scale(img\_convert\_ctx, (const unsigned char\* const\*)pFrame->data, pFrame->linesize, , pCodecCtx->height,  
                pFrameRGB->data, pFrameRGB->linesize);  
            QImage img((uchar\*)pFrameRGB->data\[\],pCodecCtx->width,pCodecCtx->height,QImage::Format\_RGB32);  
            ui->label->setPixmap(QPixmap::fromImage(img));  
            Delay();  
        }  
    }  
    av\_free\_packet(packet);  
}  
sws\_freeContext(img\_convert\_ctx);  
av\_frame\_free(&pFrameRGB);  
av\_frame\_free(&pFrame);  
avcodec\_close(pCodecCtx);  
avformat\_close\_input(&pFormatCtx);  

}

以上就是QT显示视频图像的简单例子,对于对FFMPEG感兴趣想学习更多内容的,推荐看看下面博主的博文,对FFMPEG的介绍非常详细:

https://blog.csdn.net/leixiaohua1020/article/details/15811977

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章