自己做靜態(tài)網(wǎng)站的步驟百度搜索技巧
前言
參考了雷神的自制播放器項(xiàng)目,100行代碼實(shí)現(xiàn)最簡(jiǎn)單的基于FFMPEG+SDL的視頻播放器(SDL1.x)
不過(guò)老版本的代碼參考意義不大了,我現(xiàn)在準(zhǔn)備使用Qt + VS2022 + FFmpeg59重寫(xiě)這部分代碼,具體的代碼倉(cāng)庫(kù)如下:
LeventureQys/MediaPlay-FFmpeg
開(kāi)發(fā)環(huán)境:
Visual Studio 2022 + Qt 5.14.2 + FFmpeg 59
本文任務(wù)
- 調(diào)通編譯環(huán)境
- 打印協(xié)議支持信息、AVFormat信息、AVCodec 支持信息、AVFilter信息、配置信息等
- 提供一個(gè)通用的調(diào)試框架
流程
1. 開(kāi)發(fā)環(huán)境準(zhǔn)備
首先我們Visual Studio 2022 + qt是準(zhǔn)備好的,這里不做過(guò)多介紹了。
這里簡(jiǎn)單說(shuō)說(shuō)我在做這一塊的時(shí)候,為什么沒(méi)有選擇用雷神已經(jīng)寫(xiě)好的代碼和庫(kù)來(lái)進(jìn)行開(kāi)發(fā),因?yàn)槔习鎓fmpeg對(duì)新的項(xiàng)目支持比較差,而且是32位的,不兼容64位的qt,而且老版本的c++兼容對(duì)新版的編譯器有很多問(wèn)題,所以我在多次嘗試沒(méi)法正常使用VS 2022 + qt完成雷神的代碼編譯之后就放棄了,準(zhǔn)備用新版的ffmpeg來(lái)進(jìn)行一些編寫(xiě),而且實(shí)際上新版的接口更合理,不過(guò)有一些改動(dòng),需要稍微查一下??偟膩?lái)說(shuō)流程是一回事。
下載FFmpeg的build : FFmpeg-Builds - Public
壓縮包里的內(nèi)容如下:
其中include是頭文件,lib是鏈接文件,bin是dll文件
具體鏈接和include這里就不談了,很簡(jiǎn)單,隨便配配就行了
2. 具體代碼
在導(dǎo)入頭文件的時(shí)候,需要注意是以這種形式導(dǎo)入:
下面的#pragma comment (lib, “”) 是選配的,你可以在代碼中寫(xiě),也可以在工程中預(yù)備配置好
需要注意的是,新版本的迭代器和老版本的不太一樣,現(xiàn)在這個(gè)是自制了一個(gè)void*類型來(lái)作為迭代器使用的,所以需要注意!
//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")
};
我這里做了一個(gè)BaseInfos類,內(nèi)容就是返回這幾個(gè)特定信息的QString內(nèi)容,如下:
BaseInfo.h
#pragma once#include <QObject>
/// <summary>
/// 這個(gè)類用于獲得所有的ffmpeg信息
/// </summary>
///
#include "PublicHeader.h"
//FIX
struct URLProtocol;class BaseInfos : public QObject
{Q_OBJECTpublic:BaseInfos(QObject* parent = nullptr);/// <summary>/// 協(xié)議支持信息/// </summary>/// <returns>輸入內(nèi)容和輸出內(nèi)容</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()
{//初始化一個(gè)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()
{// 初始化一個(gè)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()
{}