【Qt C++自绘制界面音乐播放器-10】添加VLC来播放音乐-1

111 阅读3分钟

最新大型开源项目-云游戏,云桌面系统,欢迎关注

GammaRay源码地址

本项目代码地址

源码

1.使用VLC播放音频

1.1 下载VLC的sdk

去VLC的官网,下载一个版本的VLC,注意要下载压缩包格式的,里面有sdk和头文件

地址

选择win64

选择压缩包格式的文件

下载完成后,解压放到一个地方备用

1.2 下载VLC的C++封装,来简化代码

不使用C++的封装也可以,只是代码写起来稍微有些麻烦了。有2个选择使用代码

1.将其添加为git子模块

2.直接拷贝到子目录下

因是教程原因,我们直接拷贝到目录下

地址

选择Download Zip,然后解压到自己的目录下即可。因为这个封装都是头文件,所以方便直接使用。

放入源码目录下

2.修改CMakeLists.txt

2.1 添加VLC的路径
// 引入VLC的C++封装头文件
include_directories(${CMAKE_SOURCE_DIR}/libvlcpp)

// 引入VLC本身的文件
set(VLC_ROOT D:/software/vlc-3.0.20-win64/vlc-3.0.20)
include_directories(${VLC_ROOT}/sdk/include)

在add_executable之后,添加要链接的目录,意思是VLC的库在这个目录里

add_executable(qt_cpp_advanced_u i...)
target_link_directories(qt_cpp_advanced_ui PRIVATE ${VLC_ROOT}/sdk/lib)
// 链接VLC的2个库,libvlc和libvlccore
target_link_libraries(qt_cpp_advanced_ui PRIVATE Qt5::Widgets libvlc libvlccore)
2.2 编译完成后,拷贝VLC的dll到可执行文件所在的目录

自定义一个命令,这个命令的执行时机为POST_BUILD,是在编译完成后执行的。

1.拷贝libvlc.dll到可执行文件的目录下

2.拷贝libvlccore.dll到可执行文件的目录下

3.拷贝plugins文件夹到可执行文件的目录下,相同名的plugins下

add_custom_command(TARGET qt_cpp_advanced_ui POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy "${VLC_ROOT}/libvlc.dll" "${CMAKE_BINARY_DIR}"
    COMMAND ${CMAKE_COMMAND} -E copy "${VLC_ROOT}/libvlccore.dll" "${CMAKE_BINARY_DIR}"
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${VLC_ROOT}/plugins" "${CMAKE_BINARY_DIR}/plugins"
    )

3.添加播放代码,开始播放音乐

3.1 首先添加一个mp3到resources目录下,并且也copy到可执行文件所在的目录,CMakeLists.txt再添加一个命令

add_custom_command(TARGET qt_cpp_advanced_ui POST_BUILD
    // 拷贝mp3文件
    COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/resources/music/A_Little_Story.mp3" "${CMAKE_BINARY_DIR}"
    COMMAND ${CMAKE_COMMAND} -E copy "${VLC_ROOT}/libvlc.dll" "${CMAKE_BINARY_DIR}"
    COMMAND ${CMAKE_COMMAND} -E copy "${VLC_ROOT}/libvlccore.dll" "${CMAKE_BINARY_DIR}"
    COMMAND ${CMAKE_COMMAND} -E copy_directory "${VLC_ROOT}/plugins" "${CMAKE_BINARY_DIR}/plugins"
    )
3.2 创建MediaPlayer

使用比较简单,直接看注释即可

#include "libvlcpp/vlcpp/vlc.hpp"

class MediaPlayer
{
public:
    MediaPlayer(const QString& name);
    ~MediaPlayer();
    
    // 播放
    void Play();
    // 暂停
    void Pause();
    // 恢复
    void Resume();
    // 停止
    void Stop();
    // 设置音量0~100
    void SetVolume(int volume);
    // 调整播放位置
    void SeekPosition(float percent);
    // 设置播放进度回调,0~1.0
    void SetOnPositionChangedCallback(std::function<void(float)>&& cbk);

private:
    // 按照VLC的使用,创建几个对象
    // VLC的实例
    std::shared_ptr<VLC::Instance> instance_ = nullptr;
    // 描述一个媒体,比如一个mp3
    std::shared_ptr<VLC::Media> media_ = nullptr;
    // 播放控制操作
    std::shared_ptr<VLC::MediaPlayer> player_ = nullptr;

    std::function<void(float)> on_position_changed_cbk_ = nullptr;
};
MediaPlayer::MediaPlayer(const QString& name) {
    // 将三个实例创建好
    instance_ = std::make_shared<VLC::Instance>(0, nullptr);
    // 这里需要将我们的文件路径填写进去,因为已经拷贝到了可执行文件的目录,所以直接写名字即可
    media_ = std::make_shared<VLC::Media>(*instance_.get(), name.toStdString().c_str(), VLC::Media::FromPath);
    player_ = std::make_shared<VLC::MediaPlayer>(*media_.get());

    //这里是设置几个回调函数,包括打开,关闭,播放进度回调等
    player_->eventManager().onOpening([=]() {
        qDebug() << "onOpening";
    });

    player_->eventManager().onPlaying([=]() {
        qDebug() << "onPlaying";
    });

    player_->eventManager().onPositionChanged([this](float pos) {
        //qDebug() << "onPositionChanged: " << pos;
        if (on_position_changed_cbk_) {
            on_position_changed_cbk_(pos);
        }
    });

    player_->eventManager().onTimeChanged([=](float t) {
        //qDebug() << "onTimeChanged: " << t;
    });

    player_->eventManager().onPaused([=]() {
        qDebug() << "onPaused ";
    });

    player_->eventManager().onStopped([=]() {
        qDebug() << "onStopped";
    });

    player_->eventManager().onEndReached([=]() {
        qDebug() << "onEndReached";
    });
}

void MediaPlayer::Play() {
    player_->play();
}

void MediaPlayer::Pause() {
    player_->pause();
}

void MediaPlayer::Resume() {
    player_->setPause(false);
}

void MediaPlayer::Stop() {
    player_->stop();
}

void MediaPlayer::SetVolume(int volume) {
    player_->setVolume(volume);
}

void MediaPlayer::SeekPosition(float percent) {
    player_->setPosition(percent);
}

void MediaPlayer::SetOnPositionChangedCallback(std::function<void (float)> &&cbk) {
    on_position_changed_cbk_ = std::move(cbk);
}

现在,去MainWindow的构造函数的最后,添加几行测试代码,执行后应该可以听见音乐了。


media_player_ = std::make_shared<MediaPlayer>("A_Little_Story.mp3");
media_player_->SetVolume(50);
media_player_->Play();

注意看log输出,因为VLC第一次加载,会比较慢。如果是使用SDK启动VLC会这样,后面有缓存就会好一些。

这个问题在论坛上也有讨论:

有一个办法是减少不必要VLC的插件,VLC本身功能非常强大,像音视频播放,各种协议的流媒体播放等,本应用只是来播放音乐,可以删除些用不到的插件,比如:

下一节我们将实现播放进度与控制。