[音视频学习笔记]六、自制音视频播放器Part1 -新版本ffmpeg,Qt +VS2022,都什么年代了还在写传统播放器?

本文主要是介绍[音视频学习笔记]六、自制音视频播放器Part1 -新版本ffmpeg,Qt +VS2022,都什么年代了还在写传统播放器?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

参考了雷神的自制播放器项目,100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x)

不过老版本的代码参考意义不大了,我现在准备使用Qt + VS2022 + FFmpeg59重写这部分代码,具体的代码仓库如下:

LeventureQys/MediaPlay-FFmpeg

开发环境:
Visual Studio 2022 + Qt 5.14.2 + FFmpeg 59

本文任务

  1. 调通编译环境
  2. 打印协议支持信息、AVFormat信息、AVCodec 支持信息、AVFilter信息、配置信息等
  3. 提供一个通用的调试框架

流程

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,都什么年代了还在写传统播放器?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/834647

相关文章

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

QT Creator配置Kit的实现示例

《QTCreator配置Kit的实现示例》本文主要介绍了使用Qt5.12.12与VS2022时,因MSVC编译器版本不匹配及WindowsSDK缺失导致配置错误的问题解决,感兴趣的可以了解一下... 目录0、背景:qt5.12.12+vs2022一、症状:二、原因:(可以跳过,直奔后面的解决方法)三、解决方

Ubuntu如何升级Python版本

《Ubuntu如何升级Python版本》Ubuntu22.04Docker中,安装Python3.11后,使用update-alternatives设置为默认版本,最后用python3-V验证... 目China编程录问题描述前提环境解决方法总结问题描述Ubuntu22.04系统自带python3.10,想升级

基于Java和FFmpeg实现视频压缩和剪辑功能

《基于Java和FFmpeg实现视频压缩和剪辑功能》在视频处理开发中,压缩和剪辑是常见的需求,本文将介绍如何使用Java结合FFmpeg实现视频压缩和剪辑功能,同时去除数据库操作,仅专注于视频处理,需... 目录引言1. 环境准备1.1 项目依赖1.2 安装 FFmpeg2. 视频压缩功能实现2.1 主要功

Unity新手入门学习殿堂级知识详细讲解(图文)

《Unity新手入门学习殿堂级知识详细讲解(图文)》Unity是一款跨平台游戏引擎,支持2D/3D及VR/AR开发,核心功能模块包括图形、音频、物理等,通过可视化编辑器与脚本扩展实现开发,项目结构含A... 目录入门概述什么是 UnityUnity引擎基础认知编辑器核心操作Unity 编辑器项目模式分类工程

Python学习笔记之getattr和hasattr用法示例详解

《Python学习笔记之getattr和hasattr用法示例详解》在Python中,hasattr()、getattr()和setattr()是一组内置函数,用于对对象的属性进行操作和查询,这篇文章... 目录1.getattr用法详解1.1 基本作用1.2 示例1.3 原理2.hasattr用法详解2.

更改linux系统的默认Python版本方式

《更改linux系统的默认Python版本方式》通过删除原Python软链接并创建指向python3.6的新链接,可切换系统默认Python版本,需注意版本冲突、环境混乱及维护问题,建议使用pyenv... 目录更改系统的默认python版本软链接软链接的特点创建软链接的命令使用场景注意事项总结更改系统的默

Linux升级或者切换python版本实现方式

《Linux升级或者切换python版本实现方式》本文介绍在Ubuntu/Debian系统升级Python至3.11或更高版本的方法,通过查看版本列表并选择新版本进行全局修改,需注意自动与手动模式的选... 目录升级系统python版本 (适用于全局修改)对于Ubuntu/Debian系统安装后,验证Pyt

Qt中实现多线程导出数据功能的四种方式小结

《Qt中实现多线程导出数据功能的四种方式小结》在以往的项目开发中,在很多地方用到了多线程,本文将记录下在Qt开发中用到的多线程技术实现方法,以导出指定范围的数字到txt文件为例,展示多线程不同的实现方... 目录前言导出文件的示例工具类QThreadQObject的moveToThread方法实现多线程QC

MySQL 升级到8.4版本的完整流程及操作方法

《MySQL升级到8.4版本的完整流程及操作方法》本文详细说明了MySQL升级至8.4的完整流程,涵盖升级前准备(备份、兼容性检查)、支持路径(原地、逻辑导出、复制)、关键变更(空间索引、保留关键字... 目录一、升级前准备 (3.1 Before You Begin)二、升级路径 (3.2 Upgrade