[音视频学习笔记]六、自制音视频播放器Part1 -新版本ffmpeg,Qt +VS2022,都什么年代了还在写传统播放器?
前言
参考了雷神的自制播放器项目,100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)
不过老版本的代码参考意义不大了,我现在准备使用Qt + VS2022 + FFmpeg59重写这部分代码,具体的代码仓库如下:
LeventureQys/MediaPlay-FFmpeg
开发环境:
Visual Studio 2022 + Qt 5.14.2 + FFmpeg 59
本文任务
- 调通编译环境
- 打印协议支持信息、AVFormat信息、AVCodec 支持信息、AVFilter信息、配置信息等
- 提供一个通用的调试框架
流程
1. 开发环境准备
首先我们Visual Studio 2022 + qt是准备好的,这里不做过多介绍了。
这里简单说说我在做这一块的时候,为什么没有选择用雷神已经写好的代码和库来进行开发,因为老版ffmpeg对新的项目支持比较差,而且是32位的,不兼容64位的qt,而且老版本的c++兼容对新版的编译器有很多问题,所以我在多次尝试没法正常使用VS 2022 + qt完成雷神的代码编译之后就放弃了,准备用新版的ffmpeg来进行一些编写,而且实际上新版的接口更合理,不过有一些改动,需要稍微查一下。总的来说流程是一回事。
下载FFmpeg的build : FFmpeg-Builds - Public
压缩包里的内容如下:

其中include是头文件,lib是链接文件,bin是dll文件
具体链接和include这里就不谈了,很简单,随便配配就行了
2. 具体代码
在导入头文件的时候,需要注意是以这种形式导入:
下面的#pragma comment (lib, “”) 是选配的,你可以在代码中写,也可以在工程中预备配置好
需要注意的是,新版本的迭代器和老版本的不太一样,现在这个是自制了一个void*类型来作为迭代器使用的,所以需要注意!
//Windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
};extern "C"
{
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "avcodec.lib")
#pragma comment (lib, "avdevice.lib")
#pragma comment (lib, "avfilter.lib")
#pragma comment (lib, "avformat.lib")
#pragma comment (lib, "avutil.lib")
#pragma comment (lib, "swresample.lib")
#pragma comment (lib, "swscale.lib")
};
我这里做了一个BaseInfos类,内容就是返回这几个特定信息的QString内容,如下:
BaseInfo.h
#pragma once#include <QObject>
/// <summary>
/// 这个类用于获得所有的ffmpeg信息
/// </summary>
///
#include "PublicHeader.h"
//FIX
struct URLProtocol;class BaseInfos : public QObject
{Q_OBJECTpublic:BaseInfos(QObject* parent = nullptr);/// <summary>/// 协议支持信息/// </summary>/// <returns>输入内容和输出内容</returns>QString getProtocolInfo();/// <summary>/// 获得AVFormat信息/// </summary>/// <returns></returns>QString getAVFormatInfo();/// <summary>/// 获得AVCodec 支持信息/// </summary>/// <returns></returns>QString getAVCodedInfo();/// <summary>/// 获得AVFilter信息/// </summary>/// <returns></returns>QString getAVFilterInfo();/// <summary>/// 获得配置信息/// </summary>/// <returns></returns>QString getConfigurationInfo(); ~BaseInfos();
};
BaseInfos.cpp
#include "BaseInfos.h"BaseInfos::BaseInfos(QObject* parent): QObject(parent)
{}QString BaseInfos::getProtocolInfo()
{//初始化一个info字符串char info[10000] = { 0 };avformat_network_init();struct URLProtocol* pup = nullptr;//inputstruct URLProtocol** p_temp = &pup;avio_enum_protocols((void**)p_temp, 0);while ((*p_temp) != nullptr) {sprintf(info, "%s[ProtocolInfo - In ][%10s]\n", info, avio_enum_protocols((void**)p_temp, 0));}pup = nullptr;//outputavio_enum_protocols((void**)p_temp, 1);while ((*p_temp) != nullptr) {sprintf(info, "%s[ProtocolInfo - Out][%10s]\n", info, avio_enum_protocols((void**)p_temp, 1));}QString ret = QString::fromUtf8(info, 10000);return ret;
}QString BaseInfos::getAVFormatInfo()
{// 初始化一个info字符串char info[10000] = { 0 };avformat_network_init();const AVInputFormat* input_format = nullptr;const AVOutputFormat* output_format = nullptr;// 输入while ((input_format = av_demuxer_iterate((void**)&input_format)) != nullptr) {sprintf(info, "%s[getAVFormatInfo - In ] %10s\n", info, input_format->name);}// 输出while ((output_format = av_muxer_iterate((void**)&output_format)) != nullptr) {sprintf(info, "%s[getAVFormatInfo- Out] %10s\n", info, output_format->name);}QString ret = QString::fromUtf8(info, 10000);return ret;}QString BaseInfos::getAVCodedInfo()
{char info[50000] = { 0 };avformat_network_init();const AVCodec* codec_temp = nullptr;void* opaque = nullptr;codec_temp = av_codec_iterate(&opaque);while ((codec_temp = av_codec_iterate(&opaque)) != nullptr) {const AVCodec* decoder = avcodec_find_decoder(codec_temp->id);if (decoder != nullptr) {sprintf(info, "%s[getAVCodedInfo -Dec]", info);}else {sprintf(info, "%s[getAVCodedInfo - Enc]", info);}switch (codec_temp->type) {case AVMEDIA_TYPE_VIDEO: {sprintf(info, "%s[getAVCodedInfo - Video]", info);break;}case AVMEDIA_TYPE_AUDIO: {sprintf(info, "%s[getAVCodedInfo - Audio]", info);break;}default: {sprintf(info, "%s[getAVCodedInfo - Other]", info);break;}}}return QString::fromUtf8(info,50000);}QString BaseInfos::getAVFilterInfo()
{char info[10000] = { 0 };avformat_network_init();const AVFilter* filter = nullptr;void* opaque = nullptr;filter = av_filter_iterate(&opaque);while ((filter = av_filter_iterate(&opaque)) != nullptr) {sprintf(info, "%s[%10s]\n", info, filter->name);}QString ret = QString::fromUtf8(info);return ret;
}QString BaseInfos::getConfigurationInfo()
{char info[10000] = { 0 };avformat_network_init();sprintf(info, "%s\n", avcodec_configuration());return QString::fromUtf8(info);
}BaseInfos::~BaseInfos()
{}
3.效果

相关文章:
[音视频学习笔记]六、自制音视频播放器Part1 -新版本ffmpeg,Qt +VS2022,都什么年代了还在写传统播放器?
前言 参考了雷神的自制播放器项目,100行代码实现最简单的基于FFMPEGSDL的视频播放器(SDL1.x) 不过老版本的代码参考意义不大了,我现在准备使用Qt VS2022 FFmpeg59重写这部分代码,具体的代码仓库如下: …...
GPT-5可能会在今年夏天作为对ChatGPT的“实质性改进”而到来
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...
官宣|阿里巴巴捐赠的 Flink CDC 项目正式加入 Apache 基金会
摘要:本文整理自阿里云开源大数据平台徐榜江 (雪尽),关于阿里巴巴捐赠的 Flink CDC 项目正式加入 Apache 基金会,内容主要分为以下四部分: 1、Flink CDC 新仓库,新流程 2、Flink CDC 新定位,新玩法 3、Flin…...
部署单节点k8s并允许master节点调度pod
安装k8s 需要注意的是k8s1.24 已经弃用dockershim,现在使用docker需要cri-docker插件作为垫片,对接k8s的CRI。 硬件环境: 2c2g 主机环境: CentOS Linux release 7.9.2009 (Core) IP地址: 192.168.44.161 一、 主机配…...
Django日志(三)
内置TimedRotatingFileHandler 按时间自动切分的log文件,文件后缀 %Y-%m-%d_%H-%M-%S , 初始化参数: 注意 发送邮件的邮箱,开启SMTP服务 filename when=h 时间间隔类型,不区分大小写 S:秒 M:分钟 H:小时 D:天 W0-W6:星期几(0 = 星期一) midnight:如果atTime未指定,…...
【吾爱破解】Android初级题(二)的解题思路 _
拿到apk,我们模拟器打开看一下 好好,抽卡模拟器是吧😀 jadx反编译看一下源码 找到生成flag的地方,大概逻辑就是 java signatureArr getPackageManager().getPackageInfo(getPackageName(), 64).signaturesfor (int i 0; i &l…...
富格林:谨记可信计策安全做单
富格林悉知,现货黄金由于活跃的行情给投资者带来不少的盈利的机会,吸引着众多的投资者进场做单。但在黄金投资市场中一定要掌握可信的投资方法,提前布局好策略,这样才能增加安全获利的机会。不建议直接进入市场做单,因…...
【工具使用】mingw64编译完成运行可执行文件时出现乱码
一,问题现象: notepad设置的时UTF-8编码: mingw64命令行设置的编码格式为: 二,问题原因: 在执行的时候,windows下的编码格式是GBK 三,解决方法: 编译时࿰…...
WebSocket 使用示例,后台为nodejs
效果图 页面代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>WebSocket Client</title&g…...
【算法】力扣【树形DP】687. 最长同值路径
【算法】力扣【树形DP】687. 最长同值路径 687. 最长同值路径 文章目录 【算法】力扣【树形DP】687. 最长同值路径题目描述输入输出示例 题解思路代码描述 复杂度分析总结 题目描述 本题要求在给定的二叉树中寻找最长的同值路径,这个路径中的每个节点的值都相同。…...
S32DS用PE调试报错
1、问题: 在S32DS上用PE进行调试报错: Error while launching command: --version 2、解决方法 按下图操作 填入内容: ${cross_prefix}gdb${cross_suffix}...
Day02-DDLDMLDQL(定义,操作,查询)(联合查询,子查询,字符集和校对集,MySQL5.7乱码问题)
文章目录 Day02-DDL&DML和DQL学习目标1. SQL语言的组成2. DDL2.1 数据库结构2.2 表结构2.3 约束2.3.1 主键约束(重要)(1)特点(2) 添加主键(3)删除主键(了解) 2.3.2 自增约束(1)特点(2) 添加自增约束(3)删除自增约束(了解) 2.3.3 非空约束(1)添加非空约束(2) 删除非空约束 2…...
3D高斯泼溅的崛起
沉浸式媒体领域正在以前所未有的速度发展,其中 3D 高斯溅射成为一项关键突破。 这项技术在广泛的应用中看起来非常有前景,并且可能会彻底改变我们未来创建数字环境以及与数字环境交互的方式。 在本文中,我们将通过与摄影测量和 NeRF 等前辈进…...
基于python+vue家政服务系统flask-django-php-nodejs
相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低家政公司的运营人员成本,实现了家政服务的标准化、制度化、程序化的管理,有效地防止了家政服务的随意管理,提高了信息的处理速度和精确度,能够及时、准确地…...
用户中心项目(登录 + 用户管理功能后端)
文章目录 1.登录功能-后端1.思路分析2.完成对用户名和密码的校验1.com/sun/usercenter/service/UserService.java 添加方法2.com/sun/usercenter/service/impl/UserServiceImpl.java 添加方法3.com/sun/usercenter/service/impl/UserServiceImpl.java 新增属性 3.记录用户的登录…...
嵌入式相机WEB,用C直接处理?
以前用HTTP连接相机的时候,以为是相机内部有一个类似tomcat之类的WEB服务器。收到相机命令后,通过链接库执行动作。 昨天想给相机增加一个时间显示,增加的项目一点就跳转到登录。 于是问了之前负责的,说是要后端改。再问嵌入式相…...
LeetCode_31_中等_下一个排列
文章目录 1. 题目2. 思路及代码实现详解(Python)2.1 两遍扫描 1. 题目 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如, a r r [ 1 , 2 , 3 ] arr [1,2,3] arr[1,2,3] ,以下这些都可以视作 a r r arr arr…...
huggingface的transformers训练gpt
目录 1.原理 2.安装 3.运行 编辑 4.数据集 编辑 4.代码 4.1 model init编辑 forward: 总结: 关于loss和因果语言模型: 编辑 交叉熵:编辑 记录一下transformers库训练gpt的过程。 transformers/examples/…...
第六十一回 放冷箭燕青救主 劫法场石秀跳楼-编译安装飞桨paddlepaddle@openKylin+RISCV
卢俊义在水里被张顺抓住,用轿子抬到了梁山。宋江等人下马跪在地上迎接,请他坐第一把交椅。卢俊义宁死不从,大家只好说留他在山寨几天,先让李固带着马车货物回去。吴用对李固说,你的主人已经答应坐第二把交椅了…...
白话讲人工智能、机器学习、深度学习
人工智能(Artificial Intelligence,AI) 定义: 想象一个聪明的机器人,它能思考、决策和学习,就像电影里的智能角色那样。人工智能就是努力打造这样的智能实体的学科,它试图模仿、扩展乃至超越人…...
Kali Linux抓包工具Burp Suite社区版安装教程(简易上手版)
前言由于本人前段时间不小心删掉了Kali Linux上的Burp Suite社区版,后面需要用的时候,在网上参考了很多文章,均要下载和后续配置。我尝试了不少方法,不仅没有安装好,还得到了两个结论,那就是耗时和耗力。后…...
Nebula Console深度解析:高效管理图数据库的核心技巧与实战指南
Nebula Console深度解析:高效管理图数据库的核心技巧与实战指南 【免费下载链接】nebula-console Command line interface for the Nebula Graph service 项目地址: https://gitcode.com/gh_mirrors/ne/nebula-console Nebula Console作为NebulaGraph图数据库…...
500W无桥PFC开关电源设计资料详解:硬件原理与C语言源码揭秘
500W 无桥PFC开关电源设计资料,C语言源码。 硬件原理 500W 无桥PFC开关电源设计资料,C语言源码。 硬件原理无桥PFC这玩意儿现在在电源圈子里火得不行,相比传统拓扑,它直接把整流桥给扬了,效率提升不是一点半点。今天…...
终极跨平台串口调试工具:5个秘诀让硬件调试效率翻倍
终极跨平台串口调试工具:5个秘诀让硬件调试效率翻倍 【免费下载链接】SerialPortAssistant This project is a cross-platform serial port assistant. It can run on WINDOWS, linux、android、macos system. 项目地址: https://gitcode.com/gh_mirrors/se/Seri…...
VS2022性能剖析器实战:精准测量算法的时间与内存消耗
1. 为什么需要性能剖析工具? 写算法代码时,我们经常会遇到这样的场景:代码逻辑明明正确,但运行时间就是超出限制,或者内存消耗过大导致程序崩溃。这时候就需要性能剖析工具来帮我们找出问题所在。 我最近在准备算法竞赛…...
FreakStudio俅
环境安装 pip install keystone-engine capstone unicorn 这3个工具用法极其简单,下面通过示例来演示其用法。 Keystone 示例 from keystone import * CODE b"INC ECX; ADD EDX, ECX" try:ks Ks(KS_ARCH_X86, KS_MODE_64)encoding, count ks.asm(CODE)…...
IsaacGym力传感器实战:从初始化到数据读取的保姆级避坑指南
IsaacGym力传感器实战:从初始化到数据读取的保姆级避坑指南 在机器人仿真开发中,力传感器的数据采集往往是实现物理交互的关键环节。作为NVIDIA推出的高性能机器人仿真平台,IsaacGym凭借其GPU加速能力为开发者提供了强大的工具链,…...
对前端总体结构的认识
前端:qian/ — Vue 3 SPA 前端是一个轻量级的单页应用,使用带有 <script setup> 语法的 Vue 3 组合式 API。它作为面向用户的界面,提供认证、题目浏览和代码提交功能。 文件结构 qian/ ├── index.html ← …...
探索文本转CAD技术:如何用一句话重构你的3D设计工作流?
探索文本转CAD技术:如何用一句话重构你的3D设计工作流? 【免费下载链接】text-to-cad-ui A lightweight UI for interfacing with the Zoo text-to-cad API, built with SvelteKit. 项目地址: https://gitcode.com/gh_mirrors/te/text-to-cad-ui …...
网络安全8大就业领域和待遇对比!
网络安全8大就业领域和待遇对比! 游戏、互联网企业集中在北上广深;医疗、运营商岗位在省会城市机会更多;汽车物流则需关注长三角、珠三角等制造业集群,教育类比较适合女生发展。 学习资源 如果你也是零基础想转行网络安全&#x…...
