【Qt C++自绘制界面音乐播放器-11】添加VLC来播放音乐-2-完结

0 阅读2分钟

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

GammaRay源码地址

本项目代码地址

源码

1.音乐Item添加双击事件

class AudioItem;

using OnItemDoubleClickedCallback = std::function<void(const std::shared_ptr<AudioItem>&)>;

class ContentPage : public QWidget
{
...
    // 鼠标双击时,触发这个事件
    void mouseDoubleClickEvent(QMouseEvent *event) override;
    void SetOnItemDoubleClickCallback(OnItemDoubleClickedCallback&& cbk);
...
    OnItemDoubleClickedCallback double_click_cbk_;
}

触发后,将当前的Item做参数回调

void ContentPage::mouseDoubleClickEvent(QMouseEvent *event) {
    if (double_click_cbk_) {
        double_click_cbk_(current_item_);
    }
}

void ContentPage::SetOnItemDoubleClickCallback(OnItemDoubleClickedCallback&& cbk) {
    double_click_cbk_ = std::move(cbk);
}

2.MainWindow中,设置回调处理

        content_page_->SetOnItemDoubleClickCallback([=](const std::shared_ptr<AudioItem>& item) {
        // 设置音量(更新到UI),标题,切换选中的图片
        int init_volume = 50;
        play_controller_->SetVolume(init_volume);
        play_controller_->SetTitle(item->name_);
        play_controller_->ChangeIcon(item->pixmap_);

        // 如果正在播放其他的音乐,则停止
        if (media_player_) {
            media_player_->Stop();
            media_player_.reset();
        }

        // 新建一个Player,因为没有准备很多音乐,默认使用一个测试。
        media_player_ = std::make_shared<MediaPlayer>("A_Little_Story.mp3");
        // 设置音量,设置到Player里面,影响声音的大小
        media_player_->SetVolume(init_volume);
        // 设置播放进度的回调函数,将当前播放的进度,更新到UI
        media_player_->SetOnPositionChangedCallback([=](float percent) {
            // 更新UI必须在主线程里做,所以这里使用invokeMethod将执行放到主线程中。
            QMetaObject::invokeMethod(this, [=]() {
                play_controller_->UpdatePlayingPosition(percent);
            });
        });
        // 开始播放
        media_player_->Play();
        
        // 将media_player实例存入player_controller一份,方便调整UI时,把设置更新到Player中去。
        play_controller_->SetMediaPlayer(media_player_);
        // 将当前的播放按钮,设置为正在播放的状态。
        play_controller_->ChangePlayButtonState(true);
    });

整体来说比较简单了,唯一要注意的问题,就是跟新UI,必须放到主线程 。否则可能出现app崩溃的情况。

另外就是播放开始后,我们就把播放按钮的状态设置成true,此时显示的是暂停的icon,因为已经开始播放了,下一次点击,就是暂停。

最后就是使用weak_ptr来存储的MediaPlayer,这样能感知到外面的MediaPlayer实例,是否已经被析构了。

void PlayController::ChangePlayButtonState(bool playing) {
    is_playing_ = playing;
    if (playing) {
        play_btn_->ChangeIcon(":/images/resources/pause.svg", ":/images/resources/pause_active.svg");
        // 使用weak ptr
        auto mp = this->media_player_.lock();
        if (mp) {
            mp->Resume();
        }
    }
    else {
        play_btn_->ChangeIcon(":/images/resources/play_arrow.svg", ":/images/resources/play_arrow_active.svg");
        auto mp = this->media_player_.lock();
        if (mp) {
            mp->Pause();
        }
    }
}

至此,一个简单的app写完了。

坚持到此,你一定有所收获!