QT+FFMPEG实现视频播放
开发环境: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 <QTime>
extern "C"{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
}
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
QT+FFMPEG实现视频播放的更多相关文章
- Qt+FFmpeg 简单实现视频播放
这里使用 Qt + FFmpeg 实现了一个简单播放视频的例子.先看下按下按钮播放视频时的效果图: 完整工程下载链接:Github-FFmpeg_demo 注意:一定要将 bin 目录下的 dll 文 ...
- 项目实战:Qt+Ffmpeg+OpenCV相机程序(打开摄像头、支持多种摄像头、分辨率调整、翻转、旋转、亮度调整、拍照、录像、回放图片、回放录像)
若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...
- 音视频处理之FFmpeg+SDL视频播放器20180409
一.FFmpeg视频解码器 1.视频解码知识 1).纯净的视频解码流程 压缩编码数据->像素数据. 例如解码H.264,就是“H.264码流->YUV”. 2).一般的视频解码流程 视频码 ...
- QT+FFMPEG+SDL2.0实现视频播放
开发环境:MinGW+QT5.9+FFMPEG20190212+SDL2.0.9 一.开发环境搭建 (1)下载工具 在https://ffmpeg.zeranoe.com/builds/下载对应版本. ...
- 海思3519 qt ffmpeg 软解码播放avi
在海思3519上基于qt采用ffmpeg对avi进行解码显示,其中ffmpeg的配置,qt的配置在前文中已经说明,在此不再赘述. 解码 解码在单独的线程中进行,具体的代码如下: void VideoP ...
- Qt ffmpeg环境搭建
ffmpeg下载地址:https://ffmpeg.zeranoe.com/builds/ 版本选择第一个,然后多少位看自己的pc(我的是64),右边对应三个都要下载,Static,Shared,De ...
- Qt FFMPEG+OpenCV开启摄像头
//ffmpegDecode.h #ifndef __FFMPEG_DECODE_H__ #define __FFMPEG_DECODE_H__ #include "global.h&quo ...
- Qt + FFmpeg 本地音频播放器
http://pan.baidu.com/s/1hqoYXrI
- 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0)
===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG ...
随机推荐
- express捕获全局异常的三种方法
场景 express的路由里抛出异常后,全局中间件没办法捕获,需要在所有的路由函数里写try catch,这坑爹的逻辑让人每次都要多写n行代码 官方错误捕获中件间代码如下 app.use(functi ...
- WPF xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<Button Grid.Row="1" Content="Load Data" BorderBrush="Black" Border ...
- asp.net 创建虚拟目录 iis创建虚拟目录
这几天本人接了个档案管理查询系统的小项目,踩过的坑. 其实功能都挺简单的,大致要求客户有很多pdf文档,为了方便管理,所有要开发一个相当于文件管理系统,本人正好有现成的文件管理系统,修改下就可以.其中 ...
- 三元運算子回傳lambda expression
紀錄一下 假如我想要透過三元運算子?: 傳回lambda expression 要明確轉型
- Python collectioins
collections是一个python的内建模块,提供了一些除了dict.list.tuble.等常见的数据类型之外的一些集合类 参考链接:https://www.liaoxuefeng.com/w ...
- Linux目录和文件——目录格式
Linux目录和文件——目录格式 摘要:本文主要了解了Linux系统的目录格式. 一切皆文件 Linux下“一切皆文件”是Unix/Linux的基本哲学之一. Linux中所有内容都是以文件的形式保存 ...
- excel转pdf,itextpdf转换excel
最近项目有需求,需要把excel转pdf.由于时间比较急,所以在github上找了一个转换的.最终没用上,但还是踩坑了一波. 踩坑一: 首先,这个是导出的流之间会互相影响,因为流读取过,导致导出的ex ...
- 使用qwt作曲线图——有网格线背景的画法
创建自己的QwtPlot (1) 增加一个类比如curvePlotWidget,继承自QwtPlot (2)代码示例 curvePlotWidget::curvePlotWidget(QWid ...
- Linux中用postfix搭建邮件服务器实战详解
Linux中用postfix搭建邮件服务器实战详解 postfix是Wietse Venema在IBM的GPL协议之下开发的MTA(邮件传输代理)软件.Postfix试图更快.更容易管理.更安全,同时 ...
- vue学习指南:第六篇(详细) - Vue的组件 component
1. 什么是组件?有两种解释 1. 第一种解释: 什么是组件? 1. 组件是 vue 中的一个可复用的实例,所以new Vue() 是vue中最大的那个组件(根组件),有名字,使用的时候以单标签或双标 ...