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;}相关文章:
QT ubuntu下开发视频播放 FFmpeg
ubuntu 安装FFmpeg T113VideoDemo.pro #------------------------------------------------- # # Project created by QtCreator 2023-07-28T11:45:22 # #-------------------------------------------------QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widget…...
8.3一日总结
1.远程仓库的使用 a.克隆远程仓库 1>.在桌面克隆远程仓库 git clone 仓库名 2>.修改仓库内容 3>添加目录 git add. 4>提交: git commit -m 完成登录功能 5>推送提交远程仓库 : git push origin master -u 6>更改推送:git push(简写形式) 需要先添加,再提交,最…...
load、unload和pagehide、pageshow
一、load、unload和pagehide、pageshow的主要应用 1)load 和 unload 事件监听web页面的进入和离开,一般用于页面的首次加载、刷新和关闭等操作的监听; 2)pageshow 和 pagehide 事件多用于监听浏览器的前进和后退等。 二、pagesh…...
【面试问题12】
1.吞吐量和并发区别? 并发请求树/单位时间一般是s 吞吐量 并发/平均响应时间 常用的吞吐量指标有qps,tps 2.mysql数据是怎么存储的? 存储在data目录下,数据库作为文件夹,文件夹里面有.ibd文件,一个表一个ib…...
高性能网络框架笔记
目录 TCP粘包、分包惊群断开连接,TCP怎么检测的?大量的close wait,如何解 ?双方同时调用close水平触发和边沿触发的区别 TCP粘包、分包 解决:1.应用层协议头前面pktlen;2.为每一个包加上分隔符;(\r\n&…...
leetcode 738. 单调递增的数字
2023.8.4 这题用暴力法会超时,我就没试了,采用了个挺巧的方法,为了方便需要先将整数n转换为字符串的形式,然后从后向前遍历,当两个数字非递增时,将前一个数字--,后一个数字的位置记录在index中&…...
FPGA项目设计:数字时钟
项目要求: 设计一个数字时钟,数码管前两位显示小时,数码管中间两位显示分钟,数码管后面两位显示秒。 项目设计: 系统框架图: 计数模块时序图: 代码实现: 计数模块: /…...
科技云报道:向量数据库:AI时代的下一个热点
科技云报道原创。 最近,又一个概念火了——向量数据库。 随着大模型带来的应用需求提升,4月以来多家海外知名向量数据库创业企业传出融资喜讯。 4月28日,向量数据库平台Pinecone宣布获得1亿美元(约7亿元)B轮融资&am…...
【更新】119所院校考研重点勾画更新预告!
截至目前,我已经发布了47篇不同院校的择校分析。发布了87套名校信号考研真题以及119所不同院校的考研知识点重点勾画。 另外为了更好服务已经报名的同学,24梦马全程班也到了收尾的阶段。即将封班!需要报名的同学抓紧啦! 去年开始…...
【Leetcode】(自食用)LRU算法(哈希链表法)
step by step. 题目: 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 key 存在于缓存中,则返回关键…...
robots.txt 如何禁止蜘蛛(百度,360,搜狗,谷歌)搜索引擎获取页面内容
什么是蜘蛛抓取 搜索引擎使用spider程序自动访问互联网上的网页并获取网页信息。spider在访问一个网站时,会首先会检查该网站的根域下是否有一个叫做robots.txt的纯文本文件。您可以在您的网站中创建一个纯文本文件robots.txt,在文件中声明该网站中不想…...
JVM 学习—— 类加载机制
前言 在上一篇文章中,荔枝梳理了有关Java中JVM体系架构的相关知识,其中涉及到的有关Java类加载机制的相关知识并没有过多描述。那么在这篇文章中,荔枝会详细梳理一下有关JVM的类加载机制和双亲委派模型的知识,希望能够帮助到有需要…...
C#实现int类型和字节流的相互在转化
通过TCP协议进行数据传输时,需要将所有传输的内容转为字节流,这里就用到了将int型的数据转为字节流的。代码如下: public static byte[] BytesConvertToInt(int vel) {byte[] hex new byte[4];hex[3] (byte)(vel >> 24) & 0xff)…...
Centos设置固定IP地址,外网访问
查看网络信息 一般会看到enp0s3的网络配置 ip address切换至网络配置路径 cd /etc/sysconfig/network-scripts/编辑配置 vi ifcfg-enp0s3 编辑配置 主要修改 静态ip:BOOTPROTOdhcp --> OOTPROTOstaticDNS(訪問外網):DNS1114.114.114.114本机ip: 192.168.70.121子网掩码…...
非线性弹簧摆的仿真(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
css实现文字颜色渐变+阴影
效果 代码 <div class"top"><div class"top-text" text"总经理驾驶舱">总经理驾驶舱</div> </div><style lang"scss" scoped>.top{width: 100%;text-align: center;height: 80px;line-height: 80px;fo…...
C++学习笔记总结练习:关联容器
关联容器 0 关联容器概述 关联容器与顺序容器的区别 关联容器和顺序容器有着根本不同。关联容器中的元素是按关键字来把偶才能和访问的。书序容器中的元素是按他们在容器中的位置来顺序保存和访问的。 两个基础类型 map:键值对key-value。关键字是索引,值表示与…...
TypeScript技能总结(二)
typescript是js的超集,目前很多前端框架都开始使用它来作为项目的维护管理的工具,还在不断地更新,添加新功能中,我们学习它,才能更好的在的项目中运用它,发挥它的最大功效 //readonly 只能修饰属性&#x…...
整理一些Postgresql工作中常用面试中会问的问题---Postgresql面试题001
1.什么是Postgresql TOAST? TOAST (The Oversized-Attribute Storage Technique,超大尺寸字段存储技术)主要用于存储大字段的值。 PostgreSQL 页面(page)大小是固定的(通常为8KB),且不允许tuples跨多个页面存储。因此不能存储非常大的字段值。为了克服这个限制,大字段…...
Xposed回发android.os.NetworkOnMainThreadException修复
最近用xposed进行hook回发的时候,又出现了新的问题; android.os.NetworkOnMainThreadException; 在Android4.0以后,写在主线程(就是Activity)中的HTTP请求,运行时都会报错,这是因为…...
从零搭建到安全加固:CMAK for Apache Kafka 生产环境部署全记录(含LDAP配置避坑)
从零构建金融级Kafka监控体系:CMAK生产部署与LDAP深度集成实战 金融科技场景下的Kafka集群管理,从来都不只是技术参数的简单堆砌。当某跨国支付平台因监控盲区导致消息积压事故时,他们最终选择了CMAK作为监控解决方案——这个源自Yahoo开源的…...
JAVA手办商城手办盲盒商城系统源码的概率计算
在JAVA手办商城或手办盲盒商城系统中,概率计算是核心功能之一,它直接关系到盲盒的公平性、用户体验以及商业逻辑的合理性。以下从概率模型设计、算法实现、数据库设计、测试验证四个方面详细解析手办盲盒商城系统的概率计算实现:一、概率模型…...
基于Grafana+Prometheus+Micrometer的JVM性能监控实战指南
1. 为什么需要JVM性能监控系统? 第一次线上服务崩溃的经历让我记忆犹新。那天凌晨三点,报警电话把我从睡梦中惊醒,线上订单服务完全瘫痪。排查了半天才发现是JVM老年代内存泄漏导致Full GC频繁触发,最终拖垮了整个系统。如果当时有…...
免费实时空气质量API接口:一站式获取AQI+PM2.5+NO2+CO+O3+SO2+PM10数据
1. 空气质量API接口的价值与应用场景 空气质量数据对现代生活的重要性不言而喻。无论是个人健康管理、企业决策还是政府监管,实时准确的空气质量信息都发挥着关键作用。作为一个开发者,我曾经在多个项目中需要集成空气质量数据,但市面上的商业…...
3步解锁B站专业直播:告别直播姬限制的终极方案
3步解锁B站专业直播:告别直播姬限制的终极方案 【免费下载链接】bilibili_live_stream_code 用于在准备直播时获取第三方推流码,以便可以绕开哔哩哔哩直播姬,直接在如OBS等软件中进行直播,软件同时提供定义直播分区和标题功能 项…...
字节怎么就成了AI界黄埔军校?
现在国内AI圈但凡有点名气的大模型团队,不管是大厂还是六小龙,核心岗位里几乎都能找到从字节出来的人,而且很多都是骨干、负责人、甚至联创。 这很奇怪呀?字节的AI明明是国内第一梯队! 待遇也给得拉满,百…...
Kylin V10系统下KVM虚拟化环境搭建与虚拟机快速部署指南
1. Kylin V10系统与KVM虚拟化基础 作为国产操作系统的代表,Kylin V10凭借其出色的稳定性和安全性,在政务、金融等领域得到广泛应用。我在多个企业级项目中实测发现,其x86架构下的KVM虚拟化性能表现优异,完全能满足生产环境需求。要…...
STM32U575利用cubeMX配置DMA实现ADC电压采集与UART实时输出
1. STM32U575电压采集系统概述 在嵌入式开发中,实时采集电压数据并通过串口输出是最基础也最实用的功能之一。STM32U575作为STMicroelectronics推出的高性能微控制器,内置了12位ADC模数转换器和DMA控制器,配合STM32CubeMX可视化配置工具&…...
Oracle VM VirtualBox快速上手指南——从下载到安装的完整流程
1. 为什么选择Oracle VM VirtualBox 如果你正准备学习Oracle数据库,或者需要在本地搭建一个隔离的测试环境,虚拟机无疑是最佳选择。而众多虚拟机软件中,Oracle VM VirtualBox凭借其完全免费和轻量易用的特性,成为入门级用户的首选…...
如何用Obsidian Projects实现知识管理的可视化革命?[特殊字符]
如何用Obsidian Projects实现知识管理的可视化革命?🚀 【免费下载链接】obsidian-projects Plain text project planning in Obsidian 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-projects 你是否曾为散落在各处的笔记而烦恼…...
