简介:本资源为基于 Qt5.15.2 与 VLC3.0.14 的 VLC-Qt 集成编译安装包,采用 mingw8.1.0_64 工具链在 Windows 64 位环境下构建,面向需要在 Qt 项目中嵌入 VLC 播放能力的开发者与爱好者,可省去自行编译 VLC-Qt 的繁琐过程,直接用于媒体播放器界面开发或流媒体功能验证。压缩包共 399 个文件,约 43.28MB,以 338 个 dll 动态库为主,另含 38 个 h 头文件、14 个 cmake 配置、4 个 a 静态库及 pc、qmltypes、qmldir 等辅助文件,覆盖运行库、开发头文件与 CMake 集成配置,便于在工程中直接链接调用。目前已有 435 人学习下载。借助其中的库文件与 CMake 目标配置,读者可快速完成 Qt 与 VLC 的对接,理解 VLCQtCore、VLCQtWidgets、VLCQtQml 等模块的依赖关系与集成方式,为二次开发与排错提供参考。
1. 从 vlc-qt_build_mingw64_install.zip 说起:这套构建包到底解决谁的痛点
如果你在 Windows 上写过 Qt 界面,又想内嵌 VLC 做视频播放,大概率经历过这样的场景:libvlc的头文件能引到,.lib也链接上了,程序一跑起来却黑屏、崩溃,或者干脆在vlc_qt的某个VlcMediaPlayer构造里直接挂掉。问题往往不在你的业务代码,而在 VLC 与 Qt 的版本、编译器 ABI、运行时库三者没对齐。vlc-qt_build_mingw64_install.zip这个包名本身就交代了它的定位:面向 MinGW-w64 工具链、已经编译好的 vlc-qt 安装产物,解压即用,省掉从源码拉 VLC 依赖、配 CMake、跟 MSVC 与 MinGW 混编打架的那一整套流程。它适合两类人:一是想快速验证「Qt + libvlc 能不能跑通」的桌面端开发者,二是被 MSVC 版 vlc-qt 折腾过、想换 MinGW-w64 重新来一遍的工程师。这一章先把这套东西是什么、边界在哪讲清楚,后面再落到具体怎么装、怎么编、怎么排错。
2. 拆开这个 zip:MinGW-w64 下 vlc-qt 的组成与选型逻辑
2.1 为什么是 MinGW-w64 而不是 MSVC
VLC 官方在 Windows 上发布的二进制包,长期以 MinGW 工具链构建为主,libvlc.dll、libvlccore.dll以及 plugins 目录里的插件,都是 MinGW 运行时那一套。你用 MSVC 去链接 MinGW 编出来的.dll,理论上可行,但一旦涉及 C++ 接口、异常传播、STL 对象跨边界传递,就容易出玄学问题。vlc-qt 作为一层 C++ 封装,把libvlc的 C 接口包成 Qt 风格的类,它自己也得跟 VLC 用同一套工具链编译,才能保证VlcInstance、VlcMediaPlayer这些对象在内存布局和调用约定上不出岔子。
所以选 MinGW-w64 不是偏好问题,是 ABI 一致性问题。vlc-qt_build_mingw64_install.zip里的install目录,通常包含include、lib、bin三块:头文件给你#include <VlcQtCore/...>,lib下是libVlcQtCore.a、libVlcQtWidgets.a这类静态导入库,bin下是配套的VlcQtCore.dll、VlcQtWidgets.dll。你拿到手之后,真正要做的不是「安装」,而是把这套产物接到自己的 Qt 工程里,再确保运行时能找到 VLC 本体。
2.2 解压后先看目录,别急着往工程里塞
拿到 zip 之后,我一般先解压到一个不带空格、不带中文的路径,比如D:\dev\vlcqt。然后做三件事:确认include下有没有VlcQtCore和VlcQtWidgets两个子目录;确认lib下.a文件的命名跟你的 MinGW 位数匹配(libVlcQtCore.a对应 64 位,32 位通常会有libVlcQtCore32.a之类区分,具体看包内实际命名);确认bin下的 dll 数量。下面这段命令用来快速盘点目录结构,Windows 上可以用 Git Bash 或 MSYS2 终端跑:
# 进入解压目录,列出关键子目录和文件 cd /d/dev/vlcqt find . -maxdepth 2 -type d | sort echo "---- lib ----" ls -lh lib/ echo "---- bin ----" ls -lh bin/逻辑说明:find -maxdepth 2只展开两层,避免 plugins 那种深层目录刷屏;ls -lh看文件大小,能快速判断.a是不是空壳、dll 是不是完整。参数上,如果你用的是 MSYS2 的 MinGW64 shell,路径写成/d/dev/vlcqt;如果是 CMD,就换成dir命令。这一步的意义在于:先确认包是完整的,再谈集成。很多人翻车的起点,就是解压不完整或者路径带中文,导致 CMake 找不到库。
2.3 版本对齐:Qt、MinGW、VLC 三者不能各玩各的
vlc-qt 的编译产物对 Qt 版本和 MinGW 版本是有要求的。常见做法是:Qt 5.15.x 配 MinGW 8.1.0 64 位,或者 Qt 6.x 配更新的 MinGW。VLC 本体则建议用 3.0.x 的 win64 版本,因为 vlc-qt 对 VLC 4.x 的接口适配并不完整。你不需要记住所有组合,但必须做一件事:确认你 Qt Creator 里当前 Kit 用的 MinGW 版本,跟这个 zip 编译时用的 MinGW 主版本一致。如果 zip 是 MinGW 8.1 编的,你拿 MinGW 11 去链接,多数情况能过,但遇到std::filesystem或异常相关符号时可能报未定义引用。
提示:不要试图用 MSVC 的 Qt Kit 去链接这套 MinGW 产物,链接器会直接告诉你格式不识别,这不是配置能绕过去的。
3. 把 vlc-qt 接进 Qt 工程:CMake 与 qmake 两条路
3.1 用 CMake 接入的最小可用配置
现在 Qt 工程用 CMake 的越来越多,vlc-qt 本身也是 CMake 构建的,所以用 CMake 接入最顺。假设你把 zip 解压到了D:/dev/vlcqt,工程里可以这样写:
# CMakeLists.txt 片段:引入 vlc-qt 预编译产物 set(VLCQT_ROOT "D:/dev/vlcqt" CACHE PATH "vlc-qt install root") # 头文件路径 include_directories( ${VLCQT_ROOT}/include ${VLCQT_ROOT}/include/VlcQtCore ${VLCQT_ROOT}/include/VlcQtWidgets ) # 链接库:注意顺序,Widgets 依赖 Core,Core 在前 target_link_libraries(YourApp PRIVATE ${VLCQT_ROOT}/lib/libVlcQtWidgets.a ${VLCQT_ROOT}/lib/libVlcQtCore.a ) # 运行时 dll 拷贝到输出目录,省得手动复制 add_custom_command(TARGET YourApp POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "${VLCQT_ROOT}/bin/VlcQtCore.dll" "${VLCQT_ROOT}/bin/VlcQtWidgets.dll" $<TARGET_FILE_DIR:YourApp> )逻辑说明:include_directories把三个路径都加进去,是因为 vlc-qt 的头文件内部有#include <VlcQtCore/...>这种写法,只加根 include 有时找不到。target_link_libraries里 Widgets 放前面、Core 放后面,是因为静态库链接有依赖顺序,被依赖的放后面。add_custom_command做的是构建后自动拷贝 dll,避免你每次编译完手动往build目录里拖。参数上,VLCQT_ROOT用CACHE PATH是为了在 CMake GUI 里能改,团队协作时不同人路径不一样也不用改源码。
3.2 qmake 工程的 .pro 写法
如果你的老工程还是 qmake,接入方式更直接:
# .pro 片段:qmake 引入 vlc-qt VLCQT_ROOT = D:/dev/vlcqt INCLUDEPATH += $$VLCQT_ROOT/include \ $$VLCQT_ROOT/include/VlcQtCore \ $$VLCQT_ROOT/include/VlcQtWidgets LIBS += -L$$VLCQT_ROOT/lib -lVlcQtWidgets -lVlcQtCore # 构建后拷贝 dll QMAKE_POST_LINK += $$quote(cmd /c copy /Y $$VLCQT_ROOT/bin/VlcQtCore.dll $$OUT_PWD) QMAKE_POST_LINK += $$quote(cmd /c copy /Y $$VLCQT_ROOT/bin/VlcQtWidgets.dll $$OUT_PWD)逻辑说明:LIBS里-lVlcQtWidgets会自动去找libVlcQtWidgets.a,这是 MinGW 的命名约定。QMAKE_POST_LINK用cmd /c copy是因为 qmake 在 Windows 上执行的是 shell 命令,直接写copy有时不认。注意$$OUT_PWD是构建输出目录,不是源码目录,别拷错地方。如果你用的是 shadow build,这个变量指向的就是你的 build 文件夹。
3.3 一个能跑起来的最小播放器代码
接好库之后,写个最小验证程序,确认不是链接过了就完事,而是真能播:
// main.cpp:最小 vlc-qt 播放器验证 #include <QApplication> #include <VlcQtCore/Common.h> #include <VlcQtCore/Instance.h> #include <VlcQtCore/MediaPlayer.h> #include <VlcQtWidgets/WidgetVideo.h> int main(int argc, char *argv[]) { QApplication app(argc, argv); // VlcCommon::args() 会带上 VLC 需要的默认参数 VlcInstance *instance = new VlcInstance(VlcCommon::args(), nullptr); VlcMediaPlayer *player = new VlcMediaPlayer(instance); VlcWidgetVideo *videoWidget = new VlcWidgetVideo(player); videoWidget->resize(800, 450); videoWidget->show(); // 换成你本地一个真实视频文件路径 player->open(QUrl::fromLocalFile("D:/test/sample.mp4")); return app.exec(); }逻辑说明:VlcCommon::args()返回一组 VLC 初始化参数,不加的话某些环境下插件加载会失败。VlcWidgetVideo是 vlc-qt 提供的视频渲染窗口,它内部会把 VLC 的窗口句柄绑到 Qt widget 上。player->open接受QUrl,本地文件用fromLocalFile。参数上,sample.mp4换成你机器上真实存在的文件,路径别带中文,否则 VLC 插件有时解析不了。
4. 运行时依赖:VLC 本体、plugins 与 PATH 的三角关系
4.1 vlc-qt 不等于 VLC,你还得装 VLC 本体
这是最容易误解的一点:vlc-qt_build_mingw64_install.zip里只有 vlc-qt 这层封装,没有 VLC 本体。你的程序运行时需要libvlc.dll、libvlccore.dll以及plugins目录。常见做法是去 VLC 官网下 win64 的 3.0.x 安装包,装完之后把安装目录下的这几个东西准备好。你可以选择把 VLC 装到默认路径,然后在代码里用绝对路径初始化,也可以把libvlc.dll、libvlccore.dll和plugins整个拷到你的 exe 同级目录。
# 假设 VLC 装在 C:\Program Files\VideoLAN\VLC # 把运行时需要的文件拷到你的构建输出目录 VLC_DIR="/c/Program Files/VideoLAN/VLC" OUT_DIR="/d/dev/yourproject/build" cp "$VLC_DIR/libvlc.dll" "$OUT_DIR/" cp "$VLC_DIR/libvlccore.dll" "$OUT_DIR/" cp -r "$VLC_DIR/plugins" "$OUT_DIR/"逻辑说明:plugins目录必须整个拷,不能只拷一部分,因为 VLC 是按需加载解码器的,你少一个 demux 插件,某种格式就播不了。libvlccore.dll容易被漏掉,它被libvlc.dll依赖。参数上,OUT_DIR换成你实际的 exe 所在目录,Qt Creator 默认在build-xxx-Debug或build-xxx-Release下。
4.2 PATH 与插件搜索路径的优先级
VLC 找插件有两种方式:一是通过VLC_PLUGIN_PATH环境变量,二是通过libvlc.dll所在目录的相对路径。如果你把libvlc.dll和plugins放在 exe 同级,通常能自动找到。但如果你把 VLC 装在系统目录,就得确保PATH里有 VLC 的安装路径。我一般推荐前者:把运行时文件跟 exe 放一起,部署时整个文件夹打包,不依赖用户机器上装没装 VLC。
注意:如果你同时装了多个 VLC 版本,
PATH里的顺序会决定加载哪个libvlc.dll,版本不匹配时会出现「能播但花屏」或者「一打开就退出」的现象。
4.3 用 Process Explorer 确认 dll 加载来源
排查运行时问题时,别猜,直接看进程加载了哪个 dll。用 Process Explorer 打开你的程序,看libvlc.dll的路径是不是你期望的那个。如果它从C:\Windows\System32或者别的 VLC 安装目录加载了,说明PATH或者 dll 搜索顺序有问题。这一步能省掉大量「为什么我拷了 dll 还是不行」的困惑。
5. 避坑与排查:MinGW-w64 构建 vlc-qt 的 5 个血泪现场
5.1 现象:编译通过,运行时报「找不到 VlcQtCore.dll」
原因:bin目录下的 dll 没有拷到 exe 同级目录,或者拷了但位数不对(32 位 dll 配 64 位 exe)。解决:用dumpbin或objdump确认 dll 位数,MinGW 下可以用objdump -f VlcQtCore.dll看 architecture。然后确保 CMake 的 POST_BUILD 或 qmake 的 POST_LINK 真的执行了,检查构建输出目录里有没有这两个 dll。
5.2 现象:player->open()之后黑屏,没有报错
原因:VLC 的 plugins 目录没找到,或者VLC_PLUGIN_PATH指向了错误位置。解决:在VlcInstance构造之前设置环境变量,或者把plugins目录放到libvlc.dll同级。可以用qputenv("VLC_PLUGIN_PATH", "D:/dev/yourproject/build/plugins")强制指定,确认能播之后再改成相对路径。
5.3 现象:链接时报undefined reference to '_imp__...'
原因:链接的是静态库.a,但实际需要的是导入库,或者库的顺序不对。MinGW 下.a既可能是静态库也可能是导入库,取决于编译方式。解决:先确认lib目录下的.a是不是导入库(用nm看有没有__imp_符号),然后调整target_link_libraries顺序,被依赖的库放后面。如果还是不行,试试在LIBS里加上-lVlcQtCore -lVlcQtWidgets的显式顺序。
5.4 现象:程序启动就崩溃,崩溃点在VlcInstance构造
原因:Qt 版本与 vlc-qt 编译时的 Qt 版本不一致,导致虚表布局或信号槽元对象系统对不上。解决:确认你的 Qt Kit 版本,尽量跟 zip 编译时用的 Qt 主版本一致。如果 zip 是 Qt 5.15 编的,你拿 Qt 6.5 去链,即使编译过了,运行时也可能崩。这种情况没有后悔药,只能换匹配的 Qt 版本或者自己重新编译 vlc-qt。
5.5 现象:视频能播但没声音,或者声音卡顿
原因:音频输出插件没加载,或者 VLC 的音频模块跟系统音频驱动不兼容。解决:检查plugins目录下有没有audio_output相关插件,确认libvlc.dll加载的是你拷过去的那份。可以在VlcCommon::args()里加--aout=directsound或--aout=mmdevice试试,看哪个输出模块在你机器上正常。
6. 进阶:把 vlc-qt 构建产物做成可复用的开发环境
6.1 用 CMake 的 find_package 封装成可查找模块
如果你团队里多个项目都要用这套 vlc-qt,每次都写绝对路径太原始。可以写一个FindVlcQt.cmake,放到工程的cmake目录下,让find_package(VlcQt REQUIRED)自动找到:
# FindVlcQt.cmake:封装 vlc-qt 查找逻辑 find_path(VLCQT_INCLUDE_DIR VlcQtCore/Instance.h HINTS ${VLCQT_ROOT}/include) find_library(VLCQT_CORE_LIB NAMES VlcQtCore HINTS ${VLCQT_ROOT}/lib) find_library(VLCQT_WIDGETS_LIB NAMES VlcQtWidgets HINTS ${VLCQT_ROOT}/lib) include(FindPackageHandleStandardArgs) find_package_handle_standard_args(VlcQt DEFAULT_MSG VLCQT_INCLUDE_DIR VLCQT_CORE_LIB VLCQT_WIDGETS_LIB) if(VlcQt_FOUND) set(VLCQT_INCLUDE_DIRS ${VLCQT_INCLUDE_DIR}) set(VLCQT_LIBRARIES ${VLCQT_WIDGETS_LIB} ${VLCQT_CORE_LIB}) endif()逻辑说明:find_path和find_library用HINTS而不是PATHS,是因为HINTS优先级更低,不会覆盖用户手动指定的路径。find_package_handle_standard_args负责统一处理REQUIRED和版本检查。这样封装之后,工程里只需要find_package(VlcQt REQUIRED)然后target_link_libraries(YourApp ${VLCQT_LIBRARIES}),换机器时改VLCQT_ROOT就行。
6.2 验证构建产物是否完整的三个检查点
在把环境交给别人之前,我习惯做三个检查。第一,用objdump -p VlcQtCore.dll | grep "DLL Name"看它依赖哪些 dll,确认没有指向你机器上特有的路径。第二,用一个干净的视频文件跑一遍最小播放器,确认解码、渲染、音频都正常。第三,把整个输出目录拷到另一台没装 VLC 的机器上,看能不能直接跑。这三个检查过了,这套 vlc-qt 构建产物才算真正可复用。
| 检查项 | 命令/操作 | 通过标准 |
|---|---|---|
| dll 依赖 | objdump -p VlcQtCore.dll | grep "DLL Name" | 只依赖系统 dll 和 VLC 运行时 |
| 播放验证 | 运行最小播放器,打开 mp4 | 画面、声音正常,无崩溃 |
| 干净机器 | 拷贝输出目录到无 VLC 机器运行 | 能启动并播放 |
6.3 一个我踩过的坑:别在 Debug 版里链 Release 库
最后说一个我自己的教训。有次赶进度,Qt Creator 里切到 Debug 构建,但 vlc-qt 的.a是 Release 编的,链接没报错,运行到VlcMediaPlayer析构时直接崩。查了半天才发现是 Debug 和 Release 的运行时库不匹配。MinGW 下 Debug 和 Release 的异常处理和 STL 容器布局有差异,混用就是给自己埋雷。后来我养成了一个习惯:在.pro或CMakeLists.txt里根据CMAKE_BUILD_TYPE或CONFIG(debug, debug|release)分别指定不同的库路径,Debug 就用 Debug 版 vlc-qt,Release 就用 Release 版。如果手里只有一套 Release 产物,那就统一用 Release 构建,别在 Debug 下硬链。这个习惯帮我省掉了至少两次通宵排查。希望帮到你。
本文还有配套的精品资源,点击获取