QT ubuntu下开发视频播放 FFmpeg

ubuntu 安装FFmpeg

T113VideoDemo.pro

#-------------------------------------------------
#
# Project created by QtCreator 2023-07-28T11:45:22
#
#-------------------------------------------------QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = T113VideoDemo
TEMPLATE = app# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \main.cpp \mainwindow.cppHEADERS += \mainwindow.hFORMS += \mainwindow.uiINCLUDEPATH += /usr/local/ffmpeg/include \LIBS += /usr/local/ffmpeg/lib/libavcodec.so \/usr/local/ffmpeg/lib/libavdevice.so \/usr/local/ffmpeg/lib/libavfilter.so \/usr/local/ffmpeg/lib/libavformat.so \/usr/local/ffmpeg/lib/libavutil.so \/usr/local/ffmpeg/lib/libpostproc.so \/usr/local/ffmpeg/lib/libswresample.so \/usr/local/ffmpeg/lib/libswscale.so \

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = 0);~MainWindow();
private slots:void slotOpenFile();void on_pushButton_clicked();void on_close_clicked();void on_screen_clicked();private:Ui::MainWindow *ui;QString currentFileName;};#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTime>
#include <QFileDialog>
#include <QScreen>
// 调用FFmpeg的头文件
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, 100);
}MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowTitle("hello");//设置窗口的标题QObject::connect(ui->open,SIGNAL(clicked()),this,SLOT(slotOpenFile()));}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::slotOpenFile()//打开文件键
{currentFileName = QFileDialog::getOpenFileName(this, tr("open-file"), tr(""),tr("Video files(*.rmvb *.rm *.avi *.wmv *.mkv *.asf *.3gp *.mov *.mp4 *.ogv* )"));if( !currentFileName.isEmpty() ){on_pushButton_clicked();}
}void MainWindow::on_pushButton_clicked(){AVFormatContext *pFormatCtx; // 存储音视频封装格式中包含的信息int videoIndex = -1; // 视频帧索引,初始化为-1AVCodecContext *pCodecCtx; // 视频流编码结构AVCodec *pCodec; // 视频解码器AVFrame *pFrame, *pFrameRGB;unsigned char *out_buffer;AVPacket *packet;int ret, got_picture;struct SwsContext *img_convert_ctx; // 主要用于视频图像的转换char file_path[1280] = {0};strcpy(file_path,currentFileName.toUtf8().data());// 注册FFMpeg的库av_register_all();/*** (一)打开音视频流并获取音视频流信息 ***/// 初始化AVFormatContextpFormatCtx = avformat_alloc_context();// 打开音视频流/*avformat_open_input函数*///打开一个文件并解析。可解析的内容包括:视频流、音频流、视频流参数、音频流参数、视频帧索引。//参数一:AVFormatContext **ps, 格式化的上下文(由avformat_alloc_context分配)的指针。//参数二:要打开的流的url,地址最终会存入到AVFormatContext结构体当中。//参数三:指定输入的封装格式。一般传NULL,由FFmpeg自行探测。//参数四:包含AVFormatContext和demuxer私有选项的字典。返回时,此参数将被销毁并替换为包含找不到的选项if (avformat_open_input(&pFormatCtx, file_path, NULL, NULL) != 0){printf("Couldn't open input stream.\n");return;}// 获取音视频流数据信息if (avformat_find_stream_info(pFormatCtx, NULL) < 0){printf("Couldn't find stream information.\n");return;}/*** (二)查找视频流位置以及查找并打开视频解码器 ***/// 查找视频流的起始索引位置(nb_streams表示视音频流的个数)for (int i = 0; i < (int)pFormatCtx->nb_streams; i++){// 查找到视频流时退出循环if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) // 判断是否为视频流{videoIndex = i;break;}}if (videoIndex == -1){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 ;}// 打开解码器if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){printf("Could not open codec.\n");return ;}// 打印视频信息printf("--------------- File Information ----------------\n");av_dump_format(pFormatCtx, 0, file_path, 0); // 此函数打印输入或输出的详细信息printf("-------------------------------------------------\n");/*** (三)视频解码的同时处理图片像素数据 ***/// 创建帧结构,此函数仅分配基本结构空间,图像数据空 间需通过av_malloc分配pFrame = av_frame_alloc();pFrameRGB = av_frame_alloc();// 创建动态内存,创建存储图像数据的空间(av_image_get_buffer_size获取一帧图像需要的大小)out_buffer = (unsigned char *)av_malloc((size_t)av_image_get_buffer_size(AV_PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height, 1));// 存储一帧像素数据缓冲区av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, out_buffer,AV_PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height, 1);packet = (AVPacket *)av_malloc(sizeof(AVPacket));// 初始化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) >= 0){// 如果是视频数据if (packet->stream_index == videoIndex){// 解码一帧视频数据ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);if (ret < 0){printf("Decode Error.\n");return ;}if (got_picture){sws_scale(img_convert_ctx, (const unsigned char* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height,pFrameRGB->data, pFrameRGB->linesize);QImage img((uchar*)pFrameRGB->data[0],pCodecCtx->width,pCodecCtx->height,QImage::Format_RGB32);ui->label->setPixmap(QPixmap::fromImage(img)); // 在label上播放视频图片delay(40);}}av_free_packet(packet);}/*** (四)最后要释放申请的内存空间 ***/sws_freeContext(img_convert_ctx); // 释放一个SwsContextav_frame_free(&pFrameRGB);av_frame_free(&pFrame);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);
}void MainWindow::on_close_clicked(){close();}void MainWindow::on_screen_clicked(){
//    static bool max = false;
//    static QRect location = this->geometry();
//    if (max) {
//        this->setGeometry(location);
//    } else {
//        location = this->geometry();
//        this->setGeometry(qApp->desktop()->availableGeometry());
//    }//    this->setProperty("canMove", max);
//    max = !max;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/20282.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker更换数据存储路径

1. 先停掉docker服务 sudo systemctl stop docker 可能会出现的问题&#xff1a; 这样会导致docker关闭失败,解决办法&#xff1a;systemctl stop docker.socket 确保docker关闭: 2.备份现在的 Docker 数据存储目录 /var/lib/docker(默认路径) mv /var/lib/docker /var/lib/…

Meta开源Llama 2免费大语言模型,媲美ChatGPT,可在线试玩

Llama 2是Llama 1模型的升级版本,引入了一系列预训练和微调 LLM,参数量范围从7B到70B (7B、13B、70B)。其预训练模型比 Llama 1模型有了显著改进,包括训练数据的总词元数增加了 40%、上下文长度更长 (4k 词元),以及利用了分组查询注意力机制来加速 70B模型的推理! 但最激动…

快速远程桌面控制公司电脑远程办公

文章目录 第一步第二步第三步 远程办公的概念很早就被提出来&#xff0c;但似乎并没有多少项目普及落实到实际应用层面&#xff0c;至少在前几年&#xff0c;远程办公距离我们仍然很遥远。但2019年末突如其来的疫情&#xff0c;着实打了大家一个措手不及。尽管国内最初的大面积…

vue的生命周期

什么是生命周期 Vue 实例从创建到销毁的过程就是生命周期。从开始创建&#xff0c;初始化数据&#xff0c;编译模板&#xff0c;挂载 Dom 到渲染&#xff0c;更新到渲染&#xff0c;销毁等一系列过程&#xff0c;称之为生命周期 Vue生命周期共有8个阶段&#xff0c;分别为&am…

【Leetcode】(自食用)找到消失的数字

step by step. 题目&#xff1a; 给你一个含 n 个整数的数组 nums &#xff0c;其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字&#xff0c;并以数组的形式返回结果。 示例 1&#xff1a; 输入&#xff1a;nums [4,3,2,7,8,2,3,1] 输…

PyTorch Lightning教程五:Debug调试

如果遇到了这样一个问题&#xff0c;当一次训练模型花了好几天&#xff0c;结果突然在验证或测试的时候崩掉了&#xff0c;这个时候其实是很奔溃的&#xff0c;主要还是由于没有提前知道哪些时候会出现什么问题&#xff0c;本节会引入Lightning的Debug方案 1.fast_dev_run参数 …

一套ai绘图软件教程帮你打开创作新篇章

在一个寂静的艺术工作室里&#xff0c;住着一个渴望成为画家的年轻人&#xff0c;名叫艾米。她梦想能够运用自己的创造力和手艺&#xff0c;创作出令人叹为观止的艺术作品。然而&#xff0c;面对空白的画布&#xff0c;她感到无从下手&#xff0c;不知道该从何处开始。每次她试…

Stable Diffusion 硬核生存指南:WebUI 中的 CodeFormer

本篇文章聊聊 Stable Diffusion WebUI 中的核心组件&#xff0c;强壮的人脸图像面部画面修复模型 CodeFormer 相关的事情。 写在前面 在 Stable Diffusion WebUI 项目中&#xff0c;源码 modules 目录中&#xff0c;有一个有趣的目录叫做 CodeFormer&#xff0c;它就是本文的…

Fibonaccharsis

题意&#xff1a;第数n是斐波那契的第k个数&#xff0c;让你求有多少满足这个的序列&#xff08;成员非负&#xff0c;不下降&#xff09; 思路&#xff1a; 1 2 3 4 5 6 7 0 1 1 2 …

归并排序——“数据结构与算法”

各位CSDN的uu们好呀&#xff0c;今天&#xff0c;小雅兰的内容仍然是数据结构与算法专栏的排序呀&#xff0c;下面&#xff0c;让我们进入归并排序的世界吧&#xff01;&#xff01;&#xff01; 归并排序 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种…

初识C++:类与对象

前言&#xff08;类的引入&#xff09; C语言结构体中只能定义变量&#xff0c;在C中&#xff0c;结构体内不仅可以定义变量&#xff0c;也可以定义函数。比如&#xff1a; 之前在C语言中&#xff0c;用C语言方式实现的栈&#xff0c;结构体中只能定义变量&#xff1b;现在以C方…

Stable Diffusion - 真人照片的高清修复 (StableSR + GFPGAN) 最佳实践

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132032216 GFPGAN (Generative Facial Prior GAN) 算法&#xff0c;用于实现真实世界的盲脸恢复的算法&#xff0c;利用预训练的面部 GAN&#xf…

SDUT 2023 summer team contest(for 22) - 10

H - Exam 题意&#xff1a;就是给你一个数N&#xff0c;和一个方案数K&#xff0c;初始值为1&#xff0c;你有三种操作方式让值恰为N 1&#xff1a;自身加1&#xff1b; 2&#xff1a;加上X&#xff1b; 3&#xff1a;自身乘以7&#xff1b; 要你确定一X使得你…

2023华数杯数学建模竞赛选题建议

提示&#xff1a;DS C君认为的难度&#xff1a;C<B<A&#xff0c;开放度&#xff1a;B<A<C 。 A题&#xff1a;隔热材料的结构优化控制研究 A题是数模类赛事很常见的物理类赛题&#xff0c;需要学习不少相关知识。 其中第一问需要建立平纹织物整体热导率与单根纤…

偶数科技亮相第十届中国中小企业投融资交易会

第十届中国中小企业投融资交易会暨2023“小企业 大梦想”高峰论坛近日在北京举办。本届大会以“金融活水精准滴灌 专精特新体制增量”为主题&#xff0c;通过展览展示、论坛活动、项目路演、产融对接等形式&#xff0c;搭建了专精特新企业与金融机构之间、与地方政府之间的产融…

华为云hcip核心知识笔记(存储服务规划)

云上存储 &#xff1a; 云硬盘:基于分布式架构&#xff0c;可弹性扩展的虚拟块存储服务 注意事项 挂载云硬盘实例和云硬盘必须在同一区域&#xff0c;否则挂载失败文件存储服务&#xff1a;完全托管的共享文件存储 可以为多个实例实现共享访问&#xff0c;不同vpc中可以进行对…

[RocketMQ] Consumer 负载均衡服务 RebalanceService入口源码 (十五)

RocketMQ一个消费者组中可以有多个消费者, 在集群模式下他们共同消费topic下的所有消息, RocketMQ规定一个消息队列仅能被一个消费者消费, 但是一个消费者可以同时消费多个消息队列。需要负载均衡服务RebalanceService来进行消息队列分配的重平衡。使用负载均衡服务RebalanceSe…

stm32 mpu6050 cubemx DMP法读取角度

文章目录 前言一、相关文件二、cubemx配置三、代码变量初始化主循环 总结 前言 文件 记录使用dmp库来读取mpu6050的角度。 这是参考文件 参考1–主要参考 github参考 参考2 参考三 一、相关文件 相关文件在这里下载&#xff08;未填&#xff0c;不过可以在上面的git中下载&a…

LPython:最新的高性能Python实现、速度极快且支持多后端

LPython 是最新的开源 Python 实现&#xff0c;目标是打造高性能版本的 Python。 LPython 官网写道&#xff0c;它一直作为 Python 编译器在开发&#xff0c;能够生成优化的机器代码。LPython 的后端支持 LLVM、C/C 翻译&#xff0c;甚至还支持 WebAssembly (WASM)。 LPython 主…

从0到1开发go-tcp框架【3-读写协程分离、引入消息队列、进入连接管理器、引入连接属性】【基础篇完结】

从0到1开发go-tcp框架【3-读写协程分离、引入消息队列、进入连接管理器、引入连接属性】 1 读写协程分离[v0.7] 添加一个Reader和Writer之间通信的channel添加一个Writer goroutineReader由之前直接发送给客户端改为发送给通信channel启动Reader和Writer一起工作 zinx/znet/co…