You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Qt应用中读取并控制Windows当前播放的媒体信息?

实现Windows端Qt媒体控制小部件的方案

核心依赖:Windows Media Session API

Windows 10及以上系统提供的Media Session API(WinRT组件)是实现系统级媒体控制的关键,它能让Qt应用和系统媒体传输控件(SMTC)交互,获取媒体信息、控制播放状态、读取专辑封面等,和锁屏显示的媒体控制逻辑同源。

具体实现步骤

1. 配置Qt项目支持WinRT

在Qt项目的.pro文件中添加以下配置,确保能调用WinRT相关API:

QT += core gui widgets
CONFIG += c++17
win32 {
    CONFIG += windows
    LIBS += -lole32 -loleaut32 -lshlwapi
    # 引入WinRT头文件路径
    INCLUDEPATH += $$(WindowsSdkDir)Include/$$(WindowsSDKVersion)/winrt
}

2. 封装WinRT媒体控制逻辑

C++调用WinRT需先初始化运行环境,再通过MediaSessionManager获取当前活跃媒体会话,核心操作代码示例如下:

#include <winrt/Windows.Media.Control.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Storage.Streams.h>

using namespace winrt;
using namespace Windows::Media::Control;
using namespace Windows::Foundation;
using namespace Windows::Storage::Streams;

// 初始化WinRT环境
void initWinRT() {
    winrt::init_apartment();
}

// 获取当前活跃的媒体会话
GlobalSystemMediaTransportControlsSession getActiveSession() {
    auto manager = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get();
    return manager.GetCurrentSession();
}

// 读取媒体元数据(歌曲名、艺术家、专辑、封面)
void getMediaMetadata(GlobalSystemMediaTransportControlsSession session) {
    auto props = session.TryGetMediaPropertiesAsync().get();
    if (!props) return;
    
    hstring title = props.Title();
    hstring artist = props.Artist();
    hstring album = props.AlbumTitle();
    
    // 处理专辑封面:将WinRT流转换为Qt图像
    auto thumbnail = props.Thumbnail();
    if (thumbnail) {
        DataReader reader(thumbnail.GetInputStreamAt(0));
        reader.LoadAsync(thumbnail.Size()).get();
        Buffer buffer(thumbnail.Size());
        reader.ReadBuffer(buffer);
        QByteArray imgData(buffer.data(), buffer.Length());
        QImage cover = QImage::fromData(imgData);
        // 后续可将cover设置到QLabel显示
    }
}

// 播放/暂停控制
void togglePlayback(GlobalSystemMediaTransportControlsSession session) {
    auto controls = session.GetControls();
    if (controls.IsPlayEnabled()) {
        session.TryPlayAsync().get();
    } else if (controls.IsPauseEnabled()) {
        session.TryPauseAsync().get();
    }
}

// 切换曲目
void skipToPrevious(GlobalSystemMediaTransportControlsSession session) {
    session.TrySkipPreviousAsync().get();
}

void skipToNext(GlobalSystemMediaTransportControlsSession session) {
    session.TrySkipNextAsync().get();
}

// 获取播放进度
void getPlaybackProgress(GlobalSystemMediaTransportControlsSession session, qint64& posMs, qint64& durationMs) {
    auto timelineProps = session.GetTimelineProperties();
    posMs = timelineProps.Position().count() / 10000; // WinRT时间单位为100纳秒,转毫秒
    durationMs = timelineProps.EndTime().count() / 10000;
}

// 设置播放进度
void setPlaybackProgress(GlobalSystemMediaTransportControlsSession session, qint64 posMs) {
    TimeSpan targetPos;
    targetPos.count(posMs * 10000); // 转回100纳秒单位
    session.TryChangePlaybackPositionAsync(targetPos).get();
}

3. Qt界面集成

  • 用QLabel展示歌曲名、艺术家信息和专辑封面
  • 用QPushButton绑定播放/暂停、上一曲/下一曲的控制逻辑
  • 用QSlider实现进度拖动,绑定sliderReleased信号调用setPlaybackProgress
  • 定时(如1秒)调用getPlaybackProgress更新滑块位置,同时刷新媒体元数据

4. 监听媒体会话切换

通过CurrentSessionChanged事件捕获活跃媒体会话的切换,及时更新界面内容:

void setupSessionListener() {
    auto manager = GlobalSystemMediaTransportControlsSessionManager::RequestAsync().get();
    manager.CurrentSessionChanged([this](auto&&, auto&&) {
        auto newSession = manager.GetCurrentSession();
        getMediaMetadata(newSession);
        // 同步播放状态和进度
    });
}

注意事项

  • 仅支持Windows 10 1507及以上版本(WinRT API最低兼容版本)
  • WinRT异步操作需用.get()等待完成,或结合Qt的QFuture封装异步逻辑
  • 部分媒体应用可能限制外部控制权限,需确保目标应用支持SMTC交互

内容的提问来源于stack exchange,提问作者Tianming

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:10:27