使用 Windows.Media.Control 控制音乐播放程序

using Windows.Media.Control;


static void PrintHelp()
{
    Console.WriteLine("用法: ConsoleApp1 <command>");
    Console.WriteLine("可用命令: play/l, pause/a, toggle/t, next/n, prev/p, info/i");
    Console.WriteLine("扩展命令: list/ls, r/refresh, use <序号> 或直接输入序号");
}

var manager = await GlobalSystemMediaTransportControlsSessionManager.RequestAsync();
var state = CreateSessionState(manager);
if (state.Sessions.Count == 0)
{
    Console.WriteLine("未找到可控制的媒体会话,请先在系统中播放音乐。");
    return;
}

if (args.Length > 0)
{
    var raw = string.Join(' ', args);
    await ExecuteInteractiveCommand(raw, manager, state);
    return;
}

PrintHelp();
PrintSessions(state.Sessions, state.CurrentIndex);
Console.WriteLine("进入交互模式,输入命令控制播放,输入 exit 退出。");

while (true)
{
    Console.Write("> ");
    var input = Console.ReadLine();
    if (input == null)
    {
        break;
    }

    var command = input.Trim();
    if (command.Length == 0)
    {
        continue;
    }

    if (string.Equals(command, "exit", StringComparison.OrdinalIgnoreCase))
    {
        break;
    }

    await ExecuteInteractiveCommand(command, manager, state);
}

static SessionState CreateSessionState(GlobalSystemMediaTransportControlsSessionManager manager)
{
    var sessions = manager.GetSessions();
    if (sessions.Count == 0)
    {
        return new SessionState(sessions, null, -1);
    }

    var current = manager.GetCurrentSession() ?? sessions[0];
    var index = FindSessionIndex(sessions, current);
    if (index < 0)
    {
        index = 0;
        current = sessions[index];
    }

    return new SessionState(sessions, current, index);
}

static int FindSessionIndex(IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions,
    GlobalSystemMediaTransportControlsSession session)
{
    for (var i = 0; i < sessions.Count; i++)
    {
        if (sessions[i] == session)
        {
            return i;
        }
    }

    return -1;
}

static async Task ExecuteInteractiveCommand(
    string rawCommand,
    GlobalSystemMediaTransportControlsSessionManager manager,
    SessionState state)
{

    var trimmed = rawCommand.Trim();
    if (trimmed.Length == 0)
    {
        return;
    }

    if (string.Equals(trimmed, "r", StringComparison.OrdinalIgnoreCase) ||
        string.Equals(trimmed, "refresh", StringComparison.OrdinalIgnoreCase))
    {
        var refreshed = CreateSessionState(manager);
        state.Sessions = refreshed.Sessions;
        state.CurrentSession = refreshed.CurrentSession;
        state.CurrentIndex = refreshed.CurrentIndex;

        if (state.Sessions.Count == 0)
        {
            Console.WriteLine("当前没有可控制的媒体会话。");
            return;
        }

        PrintSessions(state.Sessions, state.CurrentIndex);
        return;
    }

    if (string.Equals(trimmed, "list", StringComparison.OrdinalIgnoreCase) ||
        string.Equals(trimmed, "ls", StringComparison.OrdinalIgnoreCase))
    {
        PrintSessions(state.Sessions, state.CurrentIndex);
        return;
    }

    if (TryParseIndex(trimmed, out var index) || TryParseUseCommand(trimmed, out index))
    {
        if (index < 0 || index >= state.Sessions.Count)
        {
            Console.WriteLine($"序号超出范围: {index},范围 0 - {state.Sessions.Count - 1}");
            return;
        }

        state.CurrentIndex = index;
        state.CurrentSession = state.Sessions[state.CurrentIndex];
        Console.WriteLine($"已切换到: [{state.CurrentIndex}] {GetSessionName(state.CurrentSession)}");
        return;
    }

    if (state.CurrentSession == null)
    {
        Console.WriteLine("当前没有可控制的媒体会话,请先刷新。");
        return;
    }

    await ExecuteCommand(state.CurrentSession, trimmed);
}


static bool TryParseUseCommand(string raw, out int index)
{
    index = -1;
    if (!raw.StartsWith("use ", StringComparison.OrdinalIgnoreCase))
    {
        return false;
    }

    var number = raw.Substring(4).Trim();
    return int.TryParse(number, out index);
}

static bool TryParseIndex(string raw, out int index) => int.TryParse(raw, out index);

static async Task ExecuteCommand(GlobalSystemMediaTransportControlsSession session, string rawCommand)
{
    var command = rawCommand.Trim().ToLowerInvariant();

    switch (command)
    {
        case "l":
        case "play":
            await session.TryPlayAsync();
            break;
        case "a":
        case "pause":
            await session.TryPauseAsync();
            break;
        case "t":
        case "toggle":
        case "playpause":
            await session.TryTogglePlayPauseAsync();
            break;
        case "n":
        case "next":
        case "nexttrack":
            await session.TrySkipNextAsync();
            break;
        case "p":
        case "prev":
        case "previous":
        case "previoustrack":
            await session.TrySkipPreviousAsync();
            break;
        case "i":
        case "info":
            var props = await session.TryGetMediaPropertiesAsync();
            if (props == null)
            {
                Console.WriteLine($"获取歌曲信息失败");
            }
            else {
                string title = props.Title;
                string artist = props.Artist;
                Console.WriteLine($"正在播放歌曲:{title}——{artist}");
            }
            break;
        default:
            Console.WriteLine($"未知命令: {command}");
            PrintHelp();
            break;
    }
}

static void PrintSessions(IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions, int currentIndex)
{
    Console.WriteLine("可控制的媒体会话:");
    for (var i = 0; i < sessions.Count; i++)
    {
        var prefix = i == currentIndex ? "*" : " ";
        Console.WriteLine($"{prefix} [{i}] {GetSessionName(sessions[i])}");
    }
}

static string GetSessionName(GlobalSystemMediaTransportControlsSession session)
{
    var name = session.SourceAppUserModelId;
    return string.IsNullOrWhiteSpace(name) ? "未知应用" : name;
}

sealed class SessionState
{
    public SessionState(IReadOnlyList<GlobalSystemMediaTransportControlsSession> sessions,
        GlobalSystemMediaTransportControlsSession? currentSession,
        int currentIndex)
    {
        Sessions = sessions;
        CurrentSession = currentSession;
        CurrentIndex = currentIndex;
    }

    public IReadOnlyList<GlobalSystemMediaTransportControlsSession> Sessions { get; set; }
    public GlobalSystemMediaTransportControlsSession? CurrentSession { get; set; }
    public int CurrentIndex { get; set; }
}

运行效果:
VsDebugConsole.exe_20260306_101346

posted @ 2026-03-06 10:14  菠萝橙子丶  阅读(68)  评论(0)    收藏  举报