Windows下Qt mingw64集成vlc-qt:从编译包到播放器实战
简介本资源为基于 Qt5.15.2 与 VLC3.0.14 的 VLC-Qt 集成编译安装包使用 mingw8.1.0_64 工具链在 Windows 64 位环境下构建面向需要在 Qt 项目中嵌入 VLC 播放能力的开发者与爱好者。包内共 399 个文件以 338 个 dll 动态库为主另含 38 个 h 头文件、14 个 cmake 配置脚本、4 个 a 静态库及 pc、qmltypes、qmldir 等辅助文件压缩包约 43.28MB涵盖运行库、开发头文件与 CMake 集成配置便于直接链接调用。内容预览显示包含 VLCQtCore、VLCQtWidgets、VLCQtQml 等模块的库文件与目标配置可支撑核心播放、控件封装与 QML 界面三类集成方式。目前已有 435 人学习下载适合希望快速搭建 Qt-VLC 播放环境、研究跨库集成与 CMake 配置的开发者参考但资源为非官方编译版本请遵守相关许可条款。1. 拿到 vlc-qt_build_mingw64_install.zip 之后它到底解决什么问题如果你在 Windows 上做 Qt 桌面播放器大概率绕不开 libvlc。Qt 自带的 QMediaPlayer 在 Windows 上底层走的是 DirectShow 或 WMF格式支持面窄遇到 RTSP、H.265、TS 流这类场景经常直接黑屏或者报 “Media Player error”。这时候换 libvlc 是常规选择而 vlc-qt 就是 libvlc 的 C 封装把 media player、media list、instance 这些对象包成 Qt 风格的类信号槽能直接用。问题出在编译环节。vlc-qt 官方给的构建方式依赖 CMake 加一堆环境变量Windows 上还要处理 libvlc 的 SDK 头文件和 .lib 导入库。mingw64 工具链下ABI 和 MSVC 不兼容直接拿 MSVC 编出来的 libvlc 库去链接会报一堆 undefined reference。所以 vlc-qt_build_mingw64_install.zip 这类包的核心价值是把「用 mingw64 编译好的 vlc-qt 库 对应头文件 CMake 配置文件」打包好让你跳过从源码编译这一步直接在自己的 Qt 工程里 find_package 就能用。适合谁用 Qt Creator mingw64 套件、需要嵌入视频播放能力、不想花两天时间折腾编译环境的 Windows 开发者。如果你用的是 MSVC 套件这个包不一定对得上后面会讲怎么判断。2. 先搞清楚 vlc-qt 和 mingw64 的匹配关系为什么不能随便混用2.1 vlc-qt 的库文件构成和链接方式一个编译好的 vlc-qt 安装包目录结构通常长这样vlc-qt-install/ ├── include/ │ └── vlc-qt/ │ ├── VlcInstance.h │ ├── VlcMediaPlayer.h │ ├── VlcMedia.h │ └── ... ├── lib/ │ ├── libvlc-qt.dll │ ├── libvlc-qt.lib (MSVC 导入库) │ ├── libvlc-qt.a (mingw 导入库) │ └── cmake/ │ └── vlc-qt/ │ ├── vlc-qt-config.cmake │ └── vlc-qt-config-version.cmake └── bin/ └── libvlc-qt.dll关键点在于 lib 目录下同时可能有 .lib 和 .a。MSVC 链接器认 .libmingw 的 ld 认 .a 或者直接链接 .dll。如果你在 mingw64 工程里误用了 .lib链接阶段会报 “file format not recognized” 或者 “undefined reference to_imp__...”。这不是代码问题是工具链 ABI 不匹配。vlc-qt 本身还依赖 libvlc 的运行时。libvlc.dll 和 plugins 目录必须放在可执行文件能找到的位置否则程序启动时 VlcInstance 构造会失败返回空指针或者直接崩溃。常见做法是把 libvlc.dll、libvlc-qt.dll 和 plugins 文件夹一起拷到 exe 同级目录。2.2 mingw64 版本和 Qt 套件的对应检查mingw64 不是单一版本Qt 官方安装器里带的 mingw 版本随 Qt 版本变化。比如 Qt 5.15 常用 mingw81_64Qt 6.x 可能带 mingw1120_64 或更新。vlc-qt 编译时用的 mingw 版本如果和你的 Qt 套件不一致可能出现 C 标准库符号不兼容典型报错是 “undefined reference tostd::__cxx11::basic_string...” 这类。检查方法很简单在 Qt Creator 的 Kits 里看你当前套件的编译器路径比如C:\Qt\Tools\mingw1120_64\bin\g.exe然后看 vlc-qt 包里 lib 目录下 .a 文件的编译信息。如果包里有 CMake 配置文件可以打开 vlc-qt-config.cmake 看它记录的编译器版本。没有的话用 mingw 的 nm 工具看符号# 在 mingw64 的 bin 目录下执行 nm -C libvlc-qt.a | grep std::__cxx11如果大量符号带 __cxx11 后缀说明编译时用了 C11 ABI你的 Qt 套件也得是同一 ABI。Qt 5.15 之后的 mingw 套件基本都带 __cxx11问题不大。Qt 5.9 以前的老套件可能不带那就对不上了。提示不要试图用 MSVC 编译的 vlc-qt 去配 mingw 工程反过来也不行。ABI 不兼容不是靠改 CMake 参数能绕过去的只能换包或者自己重新编译。3. 把 vlc-qt 接进 Qt 工程CMake 配置和最小可运行代码3.1 CMakeLists.txt 里怎么找到这个包假设你把 vlc-qt_build_mingw64_install.zip 解压到了D:/libs/vlc-qt-installQt 工程用 CMake 构建。CMakeLists.txt 核心部分cmake_minimum_required(VERSION 3.16) project(VlcQtDemo LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) # 指定 vlc-qt 的安装路径让 find_package 能找到 config 文件 list(APPEND CMAKE_PREFIX_PATH D:/libs/vlc-qt-install) find_package(Qt5 COMPONENTS Widgets REQUIRED) find_package(VlcQt COMPONENTS Core Widgets REQUIRED) add_executable(VlcQtDemo main.cpp MainWindow.cpp MainWindow.h ) target_link_libraries(VlcQtDemo PRIVATE Qt5::Widgets VlcQt::Core VlcQt::Widgets ) # 把 dll 和 plugins 拷到输出目录省得手动复制 add_custom_command(TARGET VlcQtDemo POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory D:/libs/vlc-qt-install/bin $TARGET_FILE_DIR:VlcQtDemo )逻辑说明CMAKE_PREFIX_PATH告诉 CMake 去哪个前缀目录找vlc-qt-config.cmake。find_package 的 COMPONENTS 里 Core 是基础库Widgets 是带视频窗口部件的模块。如果只需要后台解码不需要显示可以只链接 Core。参数说明VlcQt::Core和VlcQt::Widgets是 config 文件里定义的 imported target 名字不同版本的 vlc-qt 可能叫VlcQtCore或VlcQt::Core以实际 config 文件为准。打开 vlc-qt-config.cmake 搜add_library就能看到。3.2 最小播放器代码从 VlcInstance 到 VlcWidgetVideo下面是一个能跑起来的最小例子窗口里放一个视频部件打开本地文件播放// main.cpp #include QApplication #include VlcInstance.h #include VlcMediaPlayer.h #include VlcWidgetVideo.h #include VlcMedia.h int main(int argc, char *argv[]) { QApplication app(argc, argv); // VlcInstance 是 libvlc 的入口整个进程一个就够 // 参数里可以传 libvlc 的命令行选项比如 --no-video-title-show VlcInstance *instance new VlcInstance( QStringList() --no-video-title-show, app ); if (!instance) { qCritical(VlcInstance 创建失败检查 libvlc.dll 和 plugins 是否在 PATH 或 exe 同级目录); return -1; } VlcMediaPlayer *player new VlcMediaPlayer(instance); VlcWidgetVideo *videoWidget new VlcWidgetVideo(player); videoWidget-resize(800, 600); videoWidget-show(); // 播放本地文件路径用绝对路径或 file:// URL VlcMedia *media new VlcMedia(file:///D:/test/sample.mp4, true, instance); player-open(media); player-play(); return app.exec(); }逻辑说明VlcInstance 构造时会加载 libvlc 的插件系统如果 plugins 目录找不到instance 虽然能创建但播放时会报 “cannot load module”。VlcWidgetVideo 构造时传入 player内部会把视频输出绑定到 Qt 的 widget 上。VlcMedia 的第二个参数true表示本地文件如果是网络流传false。参数说明--no-video-title-show是 libvlc 的选项去掉视频上方的文件名叠加显示。其他常用选项还有--network-caching300控制网络流缓冲毫秒数--rtsp-tcp强制 RTSP 走 TCP。这些选项在 VlcInstance 构造时以 QStringList 传入等价于命令行参数。注意VlcMedia 对象在 player-open() 之后不要立即 deletevlc-qt 内部会接管生命周期。如果手动 delete 会导致播放中途崩溃这个坑我踩过。4. 避坑与排查mingw64 下 vlc-qt 最常见的 5 个翻车现场4.1 程序启动就崩报 “libvlc.dll not found”现象双击 exe 或者 Qt Creator 里运行直接弹窗说找不到 libvlc.dll或者进程闪退。原因libvlc.dll 不在系统 PATH 里也不在 exe 同级目录。mingw64 编译的程序默认按 exe 所在目录、当前工作目录、系统 PATH 顺序找 dll。解决把 vlc-qt 包里的 bin 目录下所有 dll以及 libvlc 的 dll 和 plugins 文件夹一起拷到 exe 输出目录。Qt Creator 里可以在 Projects → Run → Working directory 里确认工作目录是不是 exe 所在目录。更稳妥的做法是在 CMake 里加 POST_BUILD 拷贝命令前面 3.1 节已经写了。4.2 链接报 “undefined reference to_imp__libvlc_...”现象编译通过链接阶段大量 undefined reference符号名带_imp__前缀。原因链接器找到的是 MSVC 格式的 .lib 导入库或者根本没链接到 libvlc 的导入库。mingw 需要 .a 格式的导入库或者直接用-lvlc链接 dll。解决检查 CMake 里 VlcQt::Core 指向的实际库文件路径。打开 vlc-qt-config.cmake 看IMPORTED_LOCATION或IMPORTED_IMPLIB属性。如果是 .lib手动改成 .a或者用target_link_libraries直接写 dll 路径。另一种情况是 libvlc 的导入库没被自动带上需要手动加D:/libs/vlc-qt-install/lib/libvlc.a。4.3 播放时黑屏但音频正常现象视频窗口一片黑声音能听到进度条也在走。原因视频输出模块没加载成功。libvlc 在 Windows 上默认用 Direct3D 输出如果 plugins 目录不完整或者显卡驱动有问题视频输出会回退到 dummy。解决确认 plugins 目录下有libdirect3d_plugin.dll和libdirect3d11_plugin.dll。可以在 VlcInstance 构造时加--voutdirect3d11强制指定输出模块看报错信息。另外 VlcWidgetVideo 需要设置setMinimumSize尺寸为 0 时某些输出模块不渲染。4.4 Qt Creator 里运行正常单独双击 exe 就报错现象IDE 里跑得好好的把 exe 拷到别的机器或者直接双击就出问题。原因Qt Creator 运行时会把 Qt 的 bin 目录和 mingw 的 bin 目录加到 PATH 里单独运行没有这些路径。缺的是 Qt5Core.dll、Qt5Gui.dll、Qt5Widgets.dll 以及 mingw 的 libstdc-6.dll、libgcc_s_seh-1.dll、libwinpthread-1.dll。解决用 windeployqt 工具自动拷贝 Qt 依赖# 在 Qt 的 bin 目录下执行参数是 exe 路径 windeployqt.exe D:/build/VlcQtDemo/release/VlcQtDemo.exe --mingwmingw 的运行时 dll 需要手动从C:\Qt\Tools\mingw1120_64\bin拷贝windeployqt 不管这部分。或者用--compiler-runtime参数让 windeployqt 一起拷。4.5 换了一台机器报 “cannot load moduleaccess_...”现象在自己机器上好好的拷到同事电脑上播放就报模块加载失败。原因plugins 目录路径是编译时硬编码的libvlc 默认去编译时的路径找插件。换机器后路径不存在插件加载失败。解决在 VlcInstance 构造时显式指定插件路径QStringList args; args --no-video-title-show; // 用相对路径基于 exe 所在目录 args --plugin-path QCoreApplication::applicationDirPath() /plugins; VlcInstance *instance new VlcInstance(args, app);这样 plugins 文件夹跟着 exe 走换机器只要整个目录拷过去就行。5. 进阶用 CMake 的 find_package 做可移植配置以及一个验证清单5.1 把 vlc-qt 路径做成可配置变量硬编码D:/libs/vlc-qt-install在团队协作里是灾难每个人路径不一样。改成 CMake 缓存变量# 允许命令行覆盖cmake -DVLCQT_ROOTE:/libs/vlc-qt .. set(VLCQT_ROOT D:/libs/vlc-qt-install CACHE PATH vlc-qt 安装根目录) if(NOT EXISTS ${VLCQT_ROOT}/lib/cmake/vlc-qt/vlc-qt-config.cmake) message(FATAL_ERROR 在 ${VLCQT_ROOT} 下找不到 vlc-qt-config.cmake检查路径) endif() list(APPEND CMAKE_PREFIX_PATH ${VLCQT_ROOT}) find_package(VlcQt COMPONENTS Core Widgets REQUIRED)这样别人拿到工程后只需要cmake -DVLCQT_ROOT自己的路径 ..就能构建。加一个 EXISTS 检查路径不对时直接报明确错误比 find_package 失败后一堆输出好排查。5.2 运行时依赖的验证清单部署到干净机器之前按这个清单过一遍检查项验证方法期望结果libvlc.dll 存在exe 同级目录 ls文件存在libvlc-qt.dll 存在exe 同级目录 ls文件存在plugins 目录完整检查 access、codec、vout 子目录有对应 dllQt5Core.dll 等windeployqt 输出无 missingmingw 运行时检查 libstdc-6.dll文件存在plugin-path 参数代码里是否设置指向 exe 同级 plugins这个清单看着简单但实际部署时漏掉任何一项都是启动崩溃或者播放黑屏。我一般会在 main 函数开头加一段日志把 applicationDirPath、plugins 路径、libvlc 版本号打出来出问题时看日志比猜快得多。// 启动时打印关键路径方便排查 qDebug() exe dir: QCoreApplication::applicationDirPath(); qDebug() plugins dir exists: QDir(QCoreApplication::applicationDirPath() /plugins).exists(); qDebug() libvlc version: VlcInstance::libVersion();VlcInstance::libVersion() 返回 libvlc 的版本字符串如果返回空或者异常值说明 libvlc 根本没加载成功后面不用往下查了。5.3 一个我自己的习惯每次拿到一个新的 vlc-qt 编译包我不会直接往正式工程里塞。先建一个空的 Qt Widgets 工程只放一个 VlcWidgetVideo用 CMake 链接这个包跑一个本地 mp4。这一步能过再往业务代码里集成。听起来多花十分钟但比在几千行代码里排查链接错误省事得多。mingw64 下的库兼容性问题越早暴露越好拖到后面就是玄学调试。希望帮到你。本文还有配套的精品资源点击获取