Qt-VLC: 一个集成VLC的开源跨平台媒体播放库

目录

1.简介

2.安装编译

2.1.安装必要工具

2.2.下载核心依赖

2.3.windows下编译

2.4.Linux下编译

2.5.macOS编译

[3.在 Qt 项目中使用 VLC-Qt](#3.在 Qt 项目中使用 VLC-Qt)

4.Qt中使用VLC-Qt播放网络流

[5.直接使用 libvlc(不依赖 VLC-Qt)](#5.直接使用 libvlc(不依赖 VLC-Qt))

6.总结


1.简介

Qt-VLC是一个将 VLC 媒体框架与 Qt 集成的开源库,VLC 是强大的跨平台媒体播放框架,支持几乎所有音视频格式和流媒体协议,而 VLC-Qt 则简化了 Qt 与 VLC 的集成,让开发者能快速在 Qt 界面中实现媒体播放功能。VLC-Qt 是对 VLC 核心库(libvlc)的 Qt 封装,提供了 Qt 风格的 API(如 QObject 派生类、信号槽机制),支持:

  • 本地 / 网络音视频文件播放(MP4、MKV、MP3 等);
  • 流媒体播放(RTSP、HTTP 流等);
  • 播放控制(暂停、停止、进度调节、音量控制);
  • 视频渲染(支持 Qt Widgets 和 Qt Quick)。

官网:https://github.com/vlc-qt/vlc-qt

2.安装编译

2.1.安装必要工具

  • CMake :3.10 及以上版本(官网下载,选 Windows x64 安装包,勾选 "Add CMake to system PATH")。
  • Visual Studio 2022:安装时勾选 "使用 C++ 的桌面开发"(确保包含 MSVC 编译器和 Windows SDK)。
  • Git (可选):用于克隆 VLC-Qt 源码(官网下载)。

2.2.下载核心依赖

  • Qt :需与 VS2022 兼容的版本(如 Qt 5.15.2 或 Qt 6.5.0),选择 msvc2022_64 架构(64 位)。下载地址:Qt 官方镜像,安装时勾选 "MSVC 2022 64-bit"。
  • VLC SDK :64 位版本,需与编译目标架构一致(你的场景是 64 位)。下载地址:VLC 官网 SDK,解压到路径(如 D:/OpenProject/vlc-3.0.21-win64/sdk)。或者从以下网址下载:http://download.videolan.org/pub/videolan/vlc/last/
  • VLC-Qt 源码 :1) 方法 1(推荐):用 Git 克隆(包含 .git 目录,避免版本检查错误)
cpp 复制代码
git clone https://github.com/vlc-qt/vlc-qt.git
cd vlc-qt
  1. 方法 2:直接下载源码包(GitHub Releases),解压到 D:/OpenProject/vlc-qt-master

2.3.windows下编译

1.创建独立编译目录(分离编译)

在 VLC-Qt 源码目录外创建 build 目录(避免污染源码):

cpp 复制代码
mkdir D:/OpenProject/vlc-qt-master/build
cd D:/OpenProject/vlc-qt-master/build

2.运行 CMake 生成 VS 项目

通过 CMake 命令配置编译参数,需指定 Qt 路径、VLC SDK 路径、平台特性等。

完整 CMake 命令(根据你的实际路径修改):

cpp 复制代码
//[1]
cmake ..  -DCMAKE_PREFIX_PATH="C:\Qt\Qt5.12.12\5.12.12\msvc2017_64"   -DLIBVLC_LIBRARY="D:/OpenProject/vlc-3.0.21-win64/sdk/lib/libvlc.lib"  -DLIBVLCCORE_LIBRARY="D:/OpenProject/vlc-3.0.21-win64/sdk/lib/libvlccore.lib"  -DLIBVLC_INCLUDE_DIR="D:/OpenProject/vlc-3.0.21-win64/sdk/include"  -DCMAKE_CXX_FLAGS="/D_WIN32_WINNT=0x0600 /D_WINSOCKAPI_ /FIwinsock2.h"  -DCMAKE_EXE_LINKER_FLAGS="/DEFAULTLIB:ws2_32.lib" -DLIBVLC_VERSION=0x030015 -DDEBUG_SUFFIX=ON

//[2]
cmake --build . --config Debug

参数说明(核心):

  • -DCMAKE_PREFIX_PATH:Qt 安装路径,确保 CMake 能找到 Qt 的 Qt5Config.cmake 等配置文件。
  • -DVLC_INCLUDE_DIR-DVLC_LIBRARY_DIR:指定 VLC SDK 的头文件和库文件位置,避免 "找不到 vlc.h" 等错误。
  • LIBVLC_VERSION:匹配 VLC 版本(3.0.21 对应 0x030015),防止启用不支持的特性。
  • CMAKE_CXX_FLAGS 中的宏:
    • _WIN32_WINNT=0x0600:启用 Windows Vista 及以上特性(支持 WSAPoll)。
    • _WINSOCKAPI_:阻止 winsock.h 被包含(解决头文件冲突)。
    • /FIwinsock2.h:强制所有源码包含 winsock2.h(提供 WSAPoll 声明)。
  • CMAKE_EXE_LINKER_FLAGS:链接 ws2_32.libWSAPoll 的实现库)。

3.解决常见编译错误

1) CMake版本报错

cpp 复制代码
CMake Warning:
  Ignoring extra path from command line:

   "D:/OpenProject/vlc-qt-master/build/.5"


-- Building for: Visual Studio 17 2022
CMake Error at CMakeLists.txt:19 (CMAKE_MINIMUM_REQUIRED):
  Invalid CMAKE_POLICY_VERSION_MINIMUM value "3".  A numeric
  major.minor[.patch[.tweak]] must be given.


CMake Error at CMakeLists.txt:20 (CMAKE_POLICY):
  Invalid CMAKE_POLICY_VERSION_MINIMUM value "3".  A numeric
  major.minor[.patch[.tweak]] must be given.


-- Building VLC-Qt 1.2.0
fatal: not a git repository (or any of the parent directories): .git

修改如下:

2)poll函数报错

cpp 复制代码
D:\OpenProject\vlc-3.0.21-win64\sdk\include\vlc\plugins\vlc_threads.h(90,11): error C3861: "poll": 找不到标识符 [D:\OpenProje
ct\vlc-qt-master\build\src\core\Core.vcxproj]
  (编译源文件"../../../src/core/Audio.cpp")

原因:

错误 C3861: "poll": 找不到标识符 发生在 Windows 环境下使用 MSVC 编译器编译 VLC-Qt 时,核心原因是 Windows 系统默认不支持 POSIX 标准的 poll 函数poll 是 Linux/Unix 系统的系统调用,用于 I/O 多路复用),而 VLC 的头文件 vlc_threads.h 中直接使用了 poll,导致 MSVC 编译器无法识别。

解决思路:

在 Windows 下,需用 Windows 平台的等效函数 WSAPoll (属于 Winsock 库,功能类似 poll)替代 poll,并通过配置让编译器识别该替代函数。

具体解决方案:

代码修改:D:\OpenProject\vlc-3.0.21-win64\sdk\include\vlc\plugins\vlc_threads.h

CMake配置选项增加:

cpp 复制代码
-DCMAKE_CXX_FLAGS="/D_WIN32_WINNT=0x0600 /D_WINSOCKAPI_ /FIwinsock2.h"  -DCMAKE_EXE_LINKER_FLAGS="/DEFAULTLIB:ws2_32.lib"

4.生成文件

CMake查找vlc-qt库的文件:

vlc-qt核心库:

插件库:

qml开发用的库

qwidget开发用的库:

2.4.Linux下编译

从您的发行版仓库安装依赖项。支持的生成器包括make和ninja。make示例如下:

cpp 复制代码
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Debug
$ make -j8
$ make install

2.5.macOS编译

在构建之前,你需要准备好VLC库和插件。运行cmake后执行make prepare,然后重新运行cmake。以常规库或应用程序的形式进行构建。

支持的生成器为make和ninja。将使用路径中的Qt和位于/Applications中的VLC。

make示例如下:

cpp 复制代码
$ export PATH=$PATH:/path/to/Qt/5.6/clang_64/bin
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE=Debug
$ make prepare
$ cmake ..
$ make -j8
$ make install

3.在 Qt 项目中使用 VLC-Qt

1.项目配置(以 Qt Widgets + qmake 为例)

.pro 文件中添加 VLC-Qt 的头文件路径、库路径和链接库:

cpp 复制代码
# 路径根据实际安装/编译位置修改
VLCQT_INCLUDE = D:/vlc-qt/include  # VLC-Qt 头文件目录(含 VLCQtCore、VLCQtWidgets)
VLCQT_LIB = D:/vlc-qt/lib          # VLC-Qt 库文件目录(.lib 或 .a)
VLC_INCLUDE = D:/vlc-3.0.21-win64/sdk/include  # VLC SDK 头文件
VLC_LIB = D:/vlc-3.0.21-win64/sdk/lib          # VLC SDK 库文件

# 包含头文件
INCLUDEPATH += $$VLCQT_INCLUDE $$VLC_INCLUDE

# 链接库路径
LIBS += -L$$VLCQT_LIB -L$$VLC_LIB

# 链接具体库(根据需求选择)
# Core:核心功能;Widgets:Qt Widgets 渲染;Qml:Qt Quick 渲染
LIBS += -lVLCQtCore -lVLCQtWidgets
LIBS += -llibvlc -llibvlccore  # VLC 核心库

2.基本使用示例(播放本地视频)

(1)初始化 VLC 实例

VLC-Qt 需先初始化 VlcInstance(封装 libvlc_instance_t),全局只需一个实例:

cpp 复制代码
#include <VLCQtCore/Instance.h>
#include <VLCQtWidgets/WidgetVideo.h>
#include <VLCQtCore/Media.h>
#include <VLCQtCore/MediaPlayer.h>

// 初始化 VLC 实例(全局一次)
VlcInstance *instance = new VlcInstance(VlcCommon::args(), this);
if (!instance->status()) {
    qDebug() << "VLC 初始化失败!";
    return;
}

(2)创建视频播放组件

使用 VlcMediaPlayer(播放控制)和 VlcWidgetVideo(视频渲染窗口):

cpp 复制代码
// 视频渲染窗口(添加到 Qt 界面)
VlcWidgetVideo *videoWidget = new VlcWidgetVideo(this);
ui->verticalLayout->addWidget(videoWidget);  // 假设界面有一个垂直布局

// 媒体播放器(关联实例和渲染窗口)
VlcMediaPlayer *player = new VlcMediaPlayer(instance);
player->setVideoWidget(videoWidget);
videoWidget->setMediaPlayer(player);  // 绑定播放器和渲染窗口

(3)播放视频文件

cpp 复制代码
// 打开本地文件(或网络流 URL,如 "rtsp://xxx")
QString filePath = "D:/test.mp4";
VlcMedia *media = new VlcMedia(filePath, instance);

// 播放
player->open(media);
player->play();  // 开始播放

(4)播放控制(信号槽)

VLC-Qt 提供信号槽接口,方便控制和监听状态:

cpp 复制代码
// 暂停/继续
connect(ui->btnPause, &QPushButton::clicked, player, &VlcMediaPlayer::pause);

// 停止
connect(ui->btnStop, &QPushButton::clicked, player, &VlcMediaPlayer::stop);

// 进度调节(0.0 ~ 1.0)
connect(ui->sliderProgress, &QSlider::valueChanged, this, [=](int value) {
    player->setPosition(value / 100.0);  // 假设滑块范围 0~100
});

// 监听播放结束
connect(player, &VlcMediaPlayer::end, this, []() {
    qDebug() << "播放结束";
});

关键类说明

类名 作用
VlcInstance VLC 实例(全局唯一,初始化 libvlc
VlcMedia 媒体资源(本地文件、URL 等)
VlcMediaPlayer 媒体播放器(控制播放、暂停、进度等)
VlcWidgetVideo Qt Widgets 视频渲染窗口
VlcQmlVideo Qt Quick 视频渲染组件

4.Qt中使用VLC-Qt播放网络流

在 Qt 中使用 VLC-Qt 播放网络流(如 RTSP、HTTP 流、HLS 等)的完整示例代码,包含初始化、播放控制、状态监听等功能,适用于 Qt Widgets 项目。

首先确保 .pro 文件正确配置 VLC-Qt 和 VLC 依赖:

cpp 复制代码
QT       += core gui widgets

TARGET = VlcStreamPlayer
TEMPLATE = app

# VLC-Qt 头文件和库路径(根据实际安装路径修改)
VLCQT_PATH = D:/vlc-qt  # VLC-Qt 安装目录
VLC_SDK_PATH = D:/vlc-3.0.21-win64/sdk  # VLC SDK 目录

INCLUDEPATH += $$VLCQT_PATH/include \
               $$VLC_SDK_PATH/include

LIBS += -L$$VLCQT_PATH/lib \
        -L$$VLC_SDK_PATH/lib \
        -lVLCQtCore \
        -lVLCQtWidgets \
        -llibvlc \
        -llibvlccore

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

主窗口代码(播放网络流核心逻辑)

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <VLCQtCore/Instance.h>
#include <VLCQtCore/Media.h>
#include <VLCQtCore/MediaPlayer.h>
#include <VLCQtWidgets/WidgetVideo.h>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    // 播放控制按钮槽函数
    void on_btnPlay_clicked();
    void on_btnPause_clicked();
    void on_btnStop_clicked();
    void on_btnOpenUrl_clicked();

    // VLC 状态监听槽函数
    void onPlayerStateChanged(Vlc::State state);  // 播放状态变化
    void onMediaParsed(bool parsed);  // 媒体解析完成
    void onErrorOccurred();  // 错误发生

private:
    Ui::MainWindow *ui;

    // VLC-Qt 核心对象
    VlcInstance *_vlcInstance;      // VLC 实例(全局唯一)
    VlcMediaPlayer *_mediaPlayer;   // 媒体播放器
    VlcWidgetVideo *_videoWidget;   // 视频渲染窗口
    VlcMedia *_currentMedia;        // 当前播放的媒体(网络流)
};
#endif // MAINWINDOW_H

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QInputDialog>
#include <QMessageBox>
#include <QUrl>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , _vlcInstance(nullptr)
    , _mediaPlayer(nullptr)
    , _videoWidget(nullptr)
    , _currentMedia(nullptr)
{
    ui->setupUi(this);
    setWindowTitle("VLC-Qt 网络流播放器");

    // 1. 初始化 VLC 实例(全局唯一,需传入命令行参数,这里传空)
    _vlcInstance = new VlcInstance(VlcCommon::args(), this);
    if (!_vlcInstance->status()) {
        QMessageBox::critical(this, "初始化失败", "VLC 实例创建失败,无法播放媒体!");
        return;
    }

    // 2. 创建视频渲染窗口并添加到界面
    _videoWidget = new VlcWidgetVideo(this);
    ui->videoLayout->addWidget(_videoWidget);  // 假设 UI 中有一个名为 videoLayout 的 QVBoxLayout

    // 3. 创建媒体播放器并关联实例和视频窗口
    _mediaPlayer = new VlcMediaPlayer(_vlcInstance);
    _mediaPlayer->setVideoWidget(_videoWidget);
    _videoWidget->setMediaPlayer(_mediaPlayer);  // 绑定播放器和渲染窗口

    // 4. 连接信号槽(监听播放状态、错误等)
    connect(_mediaPlayer, &VlcMediaPlayer::stateChanged, 
            this, &MainWindow::onPlayerStateChanged);
    connect(_mediaPlayer, &VlcMediaPlayer::mediaParsedChanged, 
            this, &MainWindow::onMediaParsed);
    connect(_mediaPlayer, &VlcMediaPlayer::error, 
            this, &MainWindow::onErrorOccurred);

    // 初始化界面状态(默认禁用播放/暂停/停止按钮)
    ui->btnPlay->setEnabled(false);
    ui->btnPause->setEnabled(false);
    ui->btnStop->setEnabled(false);
}

MainWindow::~MainWindow()
{
    // 释放资源
    if (_currentMedia) {
        _currentMedia->stop();
        delete _currentMedia;
    }
    delete _mediaPlayer;
    delete _videoWidget;
    delete _vlcInstance;
    delete ui;
}

// 打开网络流 URL(如 rtsp://、http://、https:// 等)
void MainWindow::on_btnOpenUrl_clicked()
{
    // 弹出输入框获取网络流 URL(示例:RTSP流、HTTP流)
    QString defaultUrl = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
    QString url = QInputDialog::getText(this, "输入网络流 URL", 
                                        "请输入 RTSP/HTTP 等网络流地址:", 
                                        QLineEdit::Normal, defaultUrl);
    if (url.isEmpty()) return;

    // 停止当前播放的媒体(如果有)
    if (_currentMedia) {
        _mediaPlayer->stop();
        delete _currentMedia;
        _currentMedia = nullptr;
    }

    // 创建新的媒体(网络流)
    _currentMedia = new VlcMedia(url, _vlcInstance);
    _mediaPlayer->open(_currentMedia);  // 加载媒体(异步解析)

    // 启用控制按钮
    ui->btnPlay->setEnabled(true);
    ui->btnPause->setEnabled(true);
    ui->btnStop->setEnabled(true);
}

// 播放
void MainWindow::on_btnPlay_clicked()
{
    if (_mediaPlayer && _currentMedia) {
        _mediaPlayer->play();
    }
}

// 暂停
void MainWindow::on_btnPause_clicked()
{
    if (_mediaPlayer) {
        _mediaPlayer->pause();
    }
}

// 停止
void MainWindow::on_btnStop_clicked()
{
    if (_mediaPlayer) {
        _mediaPlayer->stop();
    }
}

// 监听播放状态变化
void MainWindow::onPlayerStateChanged(Vlc::State state)
{
    QString status;
    switch (state) {
        case Vlc::Playing: status = "正在播放"; break;
        case Vlc::Paused:  status = "已暂停"; break;
        case Vlc::Stopped: status = "已停止"; break;
        case Vlc::Ended:   status = "播放结束"; break;
        case Vlc::Error:   status = "播放错误"; break;
        default: status = "未知状态";
    }
    ui->statusbar->showMessage("状态:" + status);  // 在状态栏显示状态
}

// 媒体解析完成(网络流需要解析元数据)
void MainWindow::onMediaParsed(bool parsed)
{
    if (parsed) {
        ui->statusbar->showMessage("媒体解析成功,可播放");
    } else {
        QMessageBox::warning(this, "解析失败", "网络流解析失败,可能 URL 无效或网络不可达");
    }
}

// 错误发生时处理
void MainWindow::onErrorOccurred()
{
    QMessageBox::critical(this, "播放错误", 
                         "播放过程中发生错误:" + _mediaPlayer->errorString());
}

支持的网络流协议

VLC-Qt 支持 VLC 原生支持的所有网络流协议,常见示例:

  • RTSP 流rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov(测试用公开流)
  • HTTP 流http://clips.vorwaerts-gmbh.de/VfE_html5.mp4
  • HLS 流https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8
  • 带认证的 RTSP 流rtsp://username:password@ip:port/path(用户名密码需替换为实际值)

5.直接使用 libvlc(不依赖 VLC-Qt)

如果需要更灵活的控制,也可直接调用 libvlc 的 C 接口(VLC 原生 API),但需手动处理 Qt 事件循环和 UI 线程同步(例如用 QMetaObject::invokeMethod 在主线程更新界面)。示例初始化代码:

cpp 复制代码
#include <vlc/vlc.h>

// 初始化 libvlc
libvlc_instance_t *inst = libvlc_new(0, nullptr);
libvlc_media_player_t *mp = libvlc_media_player_new(inst);
libvlc_media_t *m = libvlc_media_new_path(inst, "D:/test.mp4");
libvlc_media_player_set_media(mp, m);

// 关联 Qt 窗口句柄(HWND 或 X11 Window)
libvlc_media_player_set_hwnd(mp, (void*)ui->videoWidget->winId());

// 播放
libvlc_media_player_play(mp);

6.总结

VLC-Qt 是 Qt 集成 VLC 媒体功能的最佳选择,通过封装好的 Qt 风格 API 可快速实现播放功能。核心步骤是:初始化 VLC 实例 → 创建播放器和渲染窗口 → 加载媒体并控制播放。注意运行时需部署 VLC 依赖库,避免缺失 DLL 错误。

相关推荐
不惑_2 小时前
Java 使用 FileOutputStream 写 Excel 文件不落盘?
开发语言·python
郝学胜-神的一滴2 小时前
128天写作之旅:记录与成长的点滴
开发语言·程序人生
superman超哥3 小时前
仓颉语言中流式I/O的设计模式深度剖析
开发语言·后端·设计模式·仓颉
豆浆whisky3 小时前
Go内存管理最佳实践:提升性能的Do‘s与Don‘ts|Go语言进阶(17)
开发语言·后端·golang
Kay_Liang3 小时前
Spring中@Controller与@RestController核心解析
java·开发语言·spring boot·后端·spring·mvc·注解
l1t3 小时前
luadbi和luasql两种lua duckdb驱动的性能对比
开发语言·单元测试·lua·c·csv·duckdb
国服第二切图仔3 小时前
Rust开发实战之使用 Reqwest 实现 HTTP 客户端请求
开发语言·http·rust
weixin_497845543 小时前
Windows系统Rust安装慢的问题
开发语言·后端·rust
骚戴4 小时前
PDF或Word转图片(多线程+aspose+函数式接口)
java·开发语言