ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

VLC-Qt预编译包集成指南:Qt5.15.2+MinGW+libVLC的CMake部署与避坑

2026/9/26 4:32:45 拓冰建站 浏览量
VLC-Qt预编译包集成指南:Qt5.15.2+MinGW+libVLC的CMake部署与避坑 简介这是一份基于Qt5.15.2与VLC3.0.14、使用MinGW64工具链在Windows环境下交叉编译生成的集成开发包面向需要在Qt界面中嵌入VLC播放能力的C开发者与音视频应用爱好者。压缩包内已预先完成libVLCQt系列动态库的编译并提供对应的头文件与CMake配置文件开发者可直接将VLCQtCore、VLCQtWidgets、VLCQtQml等模块引用至自己的Qt工程免去手动搭建MinGW编译环境和排查依赖链的繁琐过程适合具备一定Qt基础、希望加快播放器功能落地的中级开发者参考使用。包内共399个文件其中338个dll为运行时所需的动态链接库38个h头文件和14个cmake配置文件用于工程引用与构建另有少量静态库及pkg-config描述文件辅助链接压缩包整体43.28MB结构较为紧凑。目前已有435人浏览学习说明该集成方案具备一定的参考价值。需要注意的是此构建并非VLC官方发行版本下载后仅限24小时内本地验证使用建议读者将其作为学习Qt与VLC集成原理的样例在此基础上结合自身项目需求重新编译定制。1. 拿到 vlc-qt 的 mingw64 构建包先确认它就是你要的那套 Qt VLC 组合vlc-qt 在 mingw64 下从源码 build 到 install流程长且容易翻车而这个 vlc-qt_build_mingw64_install.zip 直接把人编译好的产物打包成了 zip版本固定 Qt5.15.2 VLC3.0.14工具链 mingw8.1.0_64导入库和 CMake 配置齐全。这个库本质是 libVLC 的 C 封装把 C 接口包成 VlcInstance、VlcMedia、VlcMediaPlayer 三个类还带能嵌进 QWidget 的播放控件。当 QMediaPlayer 被系统解码器卡住时这套组合是 Qt 客户端内嵌播放的最快路线。适合用 Qt 5.15.2 MinGW 版、想把解码交给 VLC 的开发者。提醒一句非官方构建作者声明仅供交流、下载后 24 小时内删除商用请自行确认授权。2. VLC-Qt 的构成与工具链配套Qt5.15.2、VLC3.0.14、mingw8.1.0 为什么必须绑死2.1 VLC-Qt 到底封装了什么libVLC 本身是纯 C 接口最常见的三个对象是 libvlc_instance_t、libvlc_media_t、libvlc_media_player_t所有操作都要手动管理内存和引用计数。VLC-Qt 做的就是把这套 C 接口包成 C 类VlcInstance 负责 libvlc_new 和 libvlc_releaseVlcMedia 负责媒体源解析VlcMediaPlayer 负责 Play、Pause、Stop 以及视频输出窗口绑定。Widgets 模块在核心之上又做了一层 QWidget 封装相当于给你一个拖进 UI 就能用的播放器控件。对照压缩包里的文件名模块划分很清楚libVLCQt.dll.a 是公共核心壳所有模块共用libVLCQtCore.dll.a 是核心类库libVLCQtWidgets.dll.a 是 QWidget 控件模块libVLCQtQml.dll.a 是给 QML 场景用的模块。文件名里的 .dll.a 是 MinGW 导入库链接期使用运行时真正干活的是 libVLC 自己的 libvlc.dll、libvlccore.dll 和 plugins 插件目录。这一点很多人搞混拿了一堆 .a 文件就以为万事大吉结果一运行就提示找不到 libvlc.dll。我一般拿到这类预编译包第一反应不是看导入库体积而是先看 .cmake 配置文件里的版本号确认它和我要用的 Qt 是不是同一个 ABI。MinGW 和 MSVC 的 C 类布局不同符号修饰规则也不同用 MSVC 的 Qt 去链 MinGW 的导入库基本就是玄学范畴。运气好能过编译运行起来大概率在某个字符串构造处直接崩溃这种问题查起来非常难受因为你面对的是两个编译器的黑匣子。2.2 三个版本为什么必须绑在一起看这套包的核心版本组合是 Qt5.15.2、VLC3.0.14、mingw8.1.0_64。Qt5.15.2 是 Qt 5 系列最后一条 LTS 分支上的版本官方在这个版本保留了 MinGW 8.1.0 64-bit 的预编译安装包很多人选 5.15.2 就是为了这套干净的 MinGW 环境。VLC 3.0.14 是 libVLC 3.0 分支的稳定点插件体系成熟。mingw8.1.0_64 对应 GCC 8.1.0是 Qt 官方工具链匹配版本太新的 GCC 可能踩 Qt 内部对旧编译器的兼容假设太旧又缺 C14 标准库支持。三者的关系可以理解成Qt 决定你的 C ABImingw 决定代码怎么编译libVLC 决定你链哪个版本的导入库和头文件。任何一个换掉包内 Targets.cmake 记录的路径和版本就可能对不上编译期或运行期总有一个地方要出事。实际生产里我用 8.1.0 和 8.3.0 都编译通过但没跨到 10、11 代以上这不是保守是不想给自己找无谓的排查成本。组件 | 当前包里的版本 | 选型理由 Qt | 5.15.2MinGW 64-bit | Qt 5 LTS官方保留 MinGW 配套安装包适合 Windows 桌面客户端 libVLC | 3.0.14 SDK | 3.0 分支 API 稳定解码器与插件体系成熟 工具链 | mingw-w64 GCC 8.1.0 64 位 | 与 Qt 官方安装包工具链一致规避 ABI 兼容问题2.3 拿到包以后先验证三件事第一步确认本机 Qt 是 MinGW 版。终端跑qmake -v看输出里的编译器信息如果是 MSVC 版后面全白搭先去装 Qt 5.15.2 MinGW 64-bit 版本再回来。第二步确认 GCC 版本运行g --version只要在 8.x 附近即可跨到 10 代以上就得留个心眼。第三步检查 libVLC 运行时确认 libvlc.dll、libvlccore.dll 和 plugins 插件目录在你的程序能找到的位置。3.0.14 的导入库配 3.0 系列新一点的 dll 一般能跑反过来用新 SDK 头文件链旧 dll 很容易出兼容问题。注意三步验证顺序不能反。先确认 Qt 编译器类型这是全局性问题改不了只能换 Qt再确认工具链版本正常不会有乱子最后看 libVLC 运行时属于细节问题环境变量就能修正。把最容易修的放最后排查效率才高。3. 安装与路径规划把 .dll.a 和 .cmake 放进 CMake 找得到的地方3.1 先分清压缩包里两类文件解压出来的 10 个文件分两堆。第一堆是四个导入库libVLCQt.dll.a、libVLCQtCore.dll.a、libVLCQtWidgets.dll.a、libVLCQtQml.dll.a对应 VLC-Qt 的四个模块链接期使用。第二堆是六个 CMake 文件VLCQtCoreConfigVersion.cmake、VLCQtWidgetsConfigVersion.cmake、VLCQtQmlConfigVersion.cmake 负责版本校验VLCQtCoreTargets.cmake、VLCQtWidgetsTargets.cmake、VLCQtQmlTargets.cmake 负责把导入库和头文件路径打包成具体 target。有个细节容易被忽略这个包里我没有看到 VLCQtCoreConfig.cmake 这种 Config 入口文件只有 ConfigVersion 和 Targets。如果直接把包路径写进 CMAKE_PREFIX_PATH 然后 find_package(VLCQtCore)CMake 找的是 VLCQtCoreConfig.cmake入口缺失就会直接报找不到包。标题里的 install 指的是 CMake install 导出的产物不是双击运行的安装程序所以这种情况在预编译包里很常见。解决办法是自己补一个最小入口放到prefix/lib/cmake/VLCQtCore/下# 最小可用的 VLCQtCoreConfig.cmake用于补全 find_package 入口 include(${CMAKE_CURRENT_LIST_DIR}/VLCQtCoreTargets.cmake) set(VLCQtCore_FOUND TRUE)这个文件的核心作用是把 Targets.cmake 拉进来。Targets.cmake 里面记录了 include 路径、导入库路径以及 VLCQt::Core 这类 target 定义手动 include 和走 find_package 最终效果一样差别只是你有没有提供一个 CMake 能识别的文件名入口。Widgets、Qml 两个模块按同方式各补一份。3.2 目录结构与 ZIP 解压步骤解压这个 zip 时我建议把释放出来的东西当“虚拟安装前缀”处理不要散到桌面。完整规划一个 VLC_QT_DIR内部结构按下面来# 先解压再手动组织目录结构 mkdir -p /d/dev/vlc-qt cd /d/dev/vlc-qt # 解压 zip 到临时目录Windows 下没 unzip 命令就用资源管理器解压或 tar -xf 处理 unzip ../vlc-qt_build_mingw64_install.zip -d extracted cd extracted # 把 include 与 lib 归位config 文件放 lib/cmake 下的模块目录 mkdir -p ../include ../lib/cmake/VLCQtCore ../lib/cmake/VLCQtWidgets ../lib/cmake/VLCQtQml # 按解压后的真实目录调整复制动作原则是 .h 放 ../include.a 与 .cmake 按模块归位不要急着写死路径先把 include 和 lib 两个顶层目录落位。CMake 的 find_package 在prefix/lib/cmake/Name/位置找 Config 文件所以 CMAKE_PREFIX_PATH 必须指向 vlc-qt 根目录而不是指向 lib。路径层级配错是预编译包最常见的翻车点很多人把 prefix 指到 lib/cmake 层然后纠结为什么 find_package 还是找不到。3.3 把路径交给 CMake 而不是写死在工程里我一般用环境变量 VLC_QT_DIR 传递安装前缀这样 CMakeLists.txt 里不需要出现任何本机绝对路径。Windows 下在系统环境变量里加VLC_QT_DIRD:/dev/vlc-qt或者用 CMakePresets.json 的 cacheVariables 注入。CMake 里这样读取# 从环境变量读取安装前缀并对缺失做保护 if(NOT DEFINED VLC_QT_DIR AND DEFINED ENV{VLC_QT_DIR}) set(VLC_QT_DIR $ENV{VLC_QT_DIR}) endif() list(APPEND CMAKE_PREFIX_PATH ${VLC_QT_DIR})这样处理的好处是工程文件可移植。同事 clone 之后只需要改一个环境变量不需要动 CMakeLists。加一层保护逻辑也很有必要环境变量没设置时CMake 错误信息会明确指向这个变量而不是报一个误导性的“找不到 VLCQtCore”。提示CMAKE_PREFIX_PATH 是按前缀拼接目录的只要你的目录结构是 include/、lib/cmake 这种标准 layout就不需要为每个模块手动 append 路径。4. 用 CMake 接进工程从 find_package 到第一个能拖动窗口的播放器4.1 最小 CMakeLists.txt实际项目里我不会把 VLC 相关的东西散布到子目录的 CMakeLists而是集中在顶层。下面是能跑通的最小编译配置cmake_minimum_required(VERSION 3.16) project(vlcqt_demo LANGUAGES CXX) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_AUTOMOC ON) # 读取环境变量指向的安装前缀 if(NOT DEFINED VLC_QT_DIR AND DEFINED ENV{VLC_QT_DIR}) set(VLC_QT_DIR $ENV{VLC_QT_DIR}) endif() list(APPEND CMAKE_PREFIX_PATH ${VLC_QT_DIR}) # 找 VLC-Qt 两个模块Core 提供核心类Widgets 提供播放控件 find_package(VLCQtCore REQUIRED) find_package(VLCQtWidgets REQUIRED) add_executable(vlcqt_demo WIN32 main.cpp ) target_link_libraries(vlcqt_demo PRIVATE VLCQt::Widgets VLCQt::Core )这里有个链接顺序的讲究MinGW 的链接器是单遍扫描静态库和导入库从左到右解析符号后面的库不会回头补前面缺失的符号。VLCQtWidgets 依赖 VLCQtCoreVLCQtCore 依赖公共库 VLCQt所以顺序必须从上层控件到内核写反了就是一堆 undefined reference。没有显式写 VLCQt 是因为 Widgets 和 Core 的 Targets.cmake 通常会把公共库作为 PUBLIC 依赖串进去你不需要自己手动追加。4.2 main.cpp 最小实现#include QApplication #include QWidget #include QVBoxLayout #include VlcInstance.h #include VlcMedia.h #include VlcMediaPlayer.h int main(int argc, char *argv[]) { QApplication app(argc, argv); // 实例化和媒体对象挂在主窗口父对象上析构交给 Qt 管理 VlcInstance *instance new VlcInstance(VlcCommon::args(), app); VlcMediaPlayer *player new VlcMediaPlayer(instance); QWidget window; window.resize(800, 450); // VlcWidgetVideo 是 Widgets 模块自带的视频输出控件 VlcWidgetVideo *videoWidget new VlcWidgetVideo(window); QVBoxLayout *layout new QVBoxLayout(window); layout-addWidget(videoWidget); // 把视频输出绑定到控件注意要在 setMedia 之前调用 player-setVideoWidget(videoWidget); // 本地文件必须用 file:/// 前缀Windows 路径写 file:///C:/videos/test.mp4 VlcMedia *media new VlcMedia(file:///C:/videos/test.mp4, instance); player-setMedia(media); window.show(); player-play(); return app.exec(); }这段代码有几个容易写错的地方。setVideoWidget 必须在 setMedia 之前调用顺序反了画面出不来播放器也不报错表现出来就是黑屏。文件路径必须用 file:/// 协议前缀直接传 C:/videos/test.mp4 会被解析成相对路径然后告诉你 media 打开失败。VlcCommon::args() 返回初始化 libVLC 所需的默认参数列表不同版本可能略有差异但基本都能用生产项目里我一般会再追加--no-video-title-show这类参数关掉默认标题覆盖。4.3 运行时的文件布局编译通过只是第一步运行时还要保证 exe 旁边有正确的 DLL 和插件目录。这一步不加当最常见现象是双击程序弹窗提示找不到 Qt 平台插件或者播放器黑屏只有声音没有画面。我一般把部署目录组织成三层| 文件/目录 | 来源 | 是否必需 | | libvlc.dll | libVLC 官方运行时 | 必需 | | libvlccore.dll | libVLC 官方运行时 | 必需 | | plugins/ | VLC 插件目录 | 必需 | | libgcc_s_seh-1.dll、libstdc-6.dll 等 | MinGW 工具链运行时 | 必需 | | platforms/qwindows.dll | Qt 平台插件 | 必需 |其中 plugins 一定不能漏。libVLC 的解码器、demux、输出模块都从这里加载缺了它的表现就是黑屏或直接无响应日志里写 cannot open access。可以用环境变量 VLC_PLUGIN_PATH 指向部署目录里的 pluginsQt 平台插件则用 QCoreApplication::addLibraryPath 指定两者不是一回事别混在一起。注意不要迷信把整个 VideoLAN 安装目录拷过来体积太大。只需要 libvlc.dll、libvlccore.dll 和 plugins 目录VLC 安装目录里那些 exe 和 locale 文件都用不上。5. 避坑指南链接顺序、运行时 DLL 与授权条款的五个踩坑现场这个包实际用起来坑不少我按踩过的频率从高到低排一遍。每条都是现象、原因、解决三段不是抽象警告。1. find_package 报错找不到 VLCQtCore 包配置文件现象cmake 配置阶段报By not providing FindVLCQtCore.cmake或直接提示找不到包配置文件。原因压缩包里没有 VLCQtCoreConfig.cmake只有 VLCQtCoreConfigVersion.cmake 和 VLCQtCoreTargets.cmake。find_package 优先找 Config 入口文件版本文件是入口找到之后才读的入口缺失等于模块整体不可见。另一个常见原因是 CMAKE_PREFIX_PATH 指到了 lib 或 lib/cmake 层而不是根目录。解决按第 3 章的方式用 include 手动引入 Targets.cmake补一个 VLCQtCoreConfig.cmake 到prefix/lib/cmake/VLCQtCore/下。顺手检查路径拼接prefix 是根目录不是 module 目录。2. 链接阶段一大片 undefined reference现象链接时输出几十个 undefined reference集中在 VlcMediaPlayer 相关符号上编译阶段一切正常。原因MinGW 的链接器单遍扫描依赖库VLCQt::Widgets、VLCQt::Core、公共库 VLCQt 三者顺序不对符号没有被正确解析。尤其把 VLCQt::Core 写在 VLCQt::Widgets 前面时Widgets 里的符号就没人管了。解决target_link_libraries 顺序固定成 VLCQt::Widgets VLCQt::Core显式引用公共库时把 VLCQt 放最后。还有一个技巧是用 --start-group 把一组库包起来但静态库互相引用严重时才需要正常情况调顺序就够了不要上 group 这种大锤。3. 运行时黑屏有声音没画面或者直接闪退现象程序跑起来窗口正常显示但播放区全黑有些机器上直接闪退没有任何 Qt 报错。原因libVLC 插件没加载。VLC 的解码器、demuxer、video output 全部在 plugins 目录里exe 旁边没有这个目录时 libVLC 只加载基础模块常见 mp4 都打不开。另一个可能是 setVideoWidget 写在 setMedia 后面视频输出绑定错过了。解决把 plugins 目录放到 exe 同目录设置 VLC_PLUGIN_PATH 指向它或者在初始化 libVLC 时用代码设置插件路径。先处理这个再检查代码里 setVideoWidget 和 setMedia 的顺序。我每次打完包都会把这两件事列成部署清单逐项勾。4. 用 MSVC 的 Qt 工程链这个 MinGW 导入库现象有人在 Qt Creator 建了 MSVC 套件的工程硬塞这个包的 .a 和头文件编译过了一些警告但运行起来在字符串赋值处崩溃。原因MSVC 和 MinGW 的 C ABI 不兼容类内存布局、异常处理、动态链接运行时都不同。导入库是给 MinGW 链接器认的MSVC 的 link.exe 根本不该吃这个文件。解决整个工程切换成 Qt 5.15.2 MinGW 64-bit 套件确认构建的 g 是 8.1.0 一代。如果项目被 MSVC 第三方库锁死就老实用 VLC-Qt 官方源码在 MSVC 下重新编一套这个包救不了你别硬凑。5. 授权条款与 24 小时删除约定现象有人把这个预编译产物直接塞进商业产品发布或者在公司内部大规模分发。原因这是非官方个人构建包内声明仅供爱好者交流、下载后 24 小时内删除。把它当生产依赖等于把第三方个人构建的无保证产物引入了供应链出了问题没人给你兜底也没法重放构建过程。我不展开法律分析但至少要尊重作者写的约定。解决学习、验证、对比代码行为用它没问题上线商用建议自己用相同参数从源码编一套另存一份构建日志。这样出了问题能重放构建过程链路完整。6. 进阶技巧用十秒自检包验证构建再精简部署目录我拿到任何新的 VLC-Qt 构建包第一件事不是写业务代码而是编一个十秒自检程序。说白了这个包是不是真的能用取决于三个事实qmake 是 MinGW、libvlc.dll 能被加载、plugins 里有能用的解码器。把第 4 章那个 main.cpp 改一下播放一个 10 秒的本地测试视频运行后满足三点就算通过窗口能看到画面而不是黑屏、拖动播放进度条能暂停和恢复、任务管理器里 CPU 占用从启动瞬间的高位回落到几个百分点。整个过程不到十分钟能筛掉八成的问题包。自检通过之后部署目录不要全量拷贝。VLC 官方安装目录里有大量用不到的东西精简打包才是落地形态。我一般只留 plugins 里的几个子目录access、demux、packetizer、codec、audio_output、video_output其余 playList、services_discovery、spu 这类的先不用就不拷。# 在部署目录下执行按实际 plugins 内容保留最小组 cd deploy/vlc mkdir -p plugins/access plugins/demux plugins/packetizer \ plugins/codec plugins/audio_output plugins/video_output cp -r libvlc.dll libvlccore.dll .这个命令在部署目录就地操作先建好最小插件子目录再把 libVLC 运行时两个核心 dll 拷回来。之后删掉 plugins 里没用到的原始目录整个 deploy 目录就是一份干净可发布的播放组件。做完把它打成 zip 备份以后每次换 Qt 或 VLC 版本解压这个 zip、替换 dll 和 plugins、重跑一遍十秒自检就能验证新包。从那以后我每次拿到 vlc-qt 的构建包都会强制走一遍这套流程先验证工具链再补 Config 入口链接顺序固定部署清单逐项勾选最后十分钟自检收尾。这套流程帮我避开了两次很坑的集成事故希望帮到你。本文还有配套的精品资源点击获取