)
桌面应用AI 应用插件系统【免费下载链接】WoxA cross-platform launcher that simply works项目地址https://gitcode.com/gh_mirrors/wo/Wox点击查看免费下载本篇技术指南围绕 Wox 内置的媒体播放器Media Player系统插件展开讲解如何通过media关键字或全局命令快速查看当前正在播放的音视频信息封面、标题、进度并在 Action Panel 中执行播放、暂停、切歌等操作。文章同时深入 Linux MPRIS、Windows SMTC、macOS MediaRemote 三套底层实现帮助读者理解 Wox 是如何在三大平台上做到一次输入、全局控媒的。读完本文你将掌握该插件的完整使用方式、全局命令词表、插件间调用接口以及其核心源码结构与数据模型。一、插件定位控制当前正在播放的应用Media Player 是 Wox 内置的系统插件之一其职责非常聚焦控制当前正在播放音频或视频的应用。它不会扫描磁盘上的媒体文件也不管理音乐库而是直接对接操作系统层提供的正在播放会话now-playing session。从源码元数据看mediaplayer.go该插件的核心特征如下元数据项值插件 IDb8f3d4e5-6c7a-4b9c-8d1e-2f3a4b5c6d7e触发关键字*全局查询与media支持平台Windows / macOS / Linux最低 Wox 版本2.0.0运行时Go内置于 Wox 进程注册于plugin.AllSystemPlugin插件在Init阶段会做两件事一是后台预热媒体信息获取器避免用户第一次进入插件时承担首次查询的系统开销二是注册一个每秒触发一次的全局刷新定时器详见下文实时刷新机制。它的出现方式有两种全局出现当系统检测到有媒体正在播放时结果会自然出现在全局查询结果中关键字触发在任何时候输入media关键字都可以主动唤出媒体控制结果。二、快速开始media关键字官方文档给出的最短使用路径只有一个词media输入后Wox 会展示当前正在播放媒体的信息卡片包含封面Artwork来自媒体应用提供的专辑封面在结果中显示为圆形唱片样式的小图标进度Progress以当前位置 / 总时长的文本形式展示在结果尾部播放控制Playback Controls打开 Action Panel 即可执行播放 / 暂停 / 上一曲 / 下一曲等操作完整视图Full Media Player View通过 Action Panel 中的 Open 动作进入独立的媒体详情界面。如果当前没有任何媒体会话插件会返回一条提示性结果i18n 键为plugin_mediaplayer_no_media不会报错也不会空白。三、全局媒体控制命令不用打开面板也能切歌除了media关键字该插件还向全局查询框注入了媒体控制命令。也就是说在任何输入场景下直接输入以下词就可以触发对应操作源码见 mediaplayer.go 与queryGlobalControls实现输入词命令说明playplay播放pausepause暂停toggletoggle播放/暂停切换别名playpause、play/pausenextnext下一曲previousprevious上一曲别名prev、back从实现上可以提炼出三条细节规则输入长度至少 2 个字符才会参与匹配matchMediaControlActions中len(normalized) 2直接返回避免单字母输入产生噪声别名按整词精确匹配例如play不会误匹配playpause防止歧义默认动作跟随用户输入当用户输入next时结果卡片的默认动作就是下一曲而当未输入具体命令、仅由全局查询自然出现时默认动作是状态感知的——正在播放则默认暂停否则默认播放resolvePreferredDefaultCommand与buildMediaActions配合实现。全局媒体控制结果被赋予固定得分200mediaControlGlobalResultScore以保证它能在混合查询结果中稳定出现。四、结果内容与展示细节解析4.1 信息卡片结构结果卡片由buildMediaResult统一构建mediaplayer.goTitle媒体标题SubTitle按优先级展示艺术家 - 专辑、仅艺术家、或仅专辑Icon封面缩略图无封面时使用播放状态图标播放中为StatusPlaying否则为插件默认图标Tails进度文本例如1:23 / 4:05Preview完整媒体视图的 JSON 数据WoxPreviewTypeMedia类型。4.2 封面图的圆形缩略处理插件对封面做了专门的图像处理formatRecordArtworkDataURI见 mediaplayer.go将封面缩放到固定的96×96recordArtworkSize使用 CatmullRom 高质量缩放算法先从原图裁出最大内接正方形centerSquare避免非方形封面变形应用圆形 Alpha 遮罩applyCircleAlpha使其呈现为圆角唱片样式以data:image/png;base64,...的 Data URI 形式交给 UI 渲染。同时decodeArtworkImageData兼容三种输入macOS 返回的 base64 字符串含可选的data:前缀、Windows 的原始图片字节以及 MPRIS 的 data URI——三平台数据最终统一走同一条图片流水线。4.3 进度文本格式formatDurationmediaplayer.go规则小于 1 小时M:SS如4:05大于等于 1 小时H:MM:SS如1:02:33无有效时长时兜底显示0:00。五、Action Panel 动作详解每个媒体结果都带有一组动作buildMediaActions动作图标是否默认行为播放 / 暂停状态感知ActionRun / ActionPause是根据播放状态自动选择 play 或 pause下一曲ActionSkipNext否发送 next 命令上一曲ActionSkipPrevious否发送 previous 命令Open完整视图ActionOpen否全局命令模式才附加将查询框内容切换为media进入完整媒体视图两个值得注意的实现细节所有控制动作都设置了PreventHideAfterAction: true——执行播放/暂停/切歌后不会关闭 Wox 窗口方便连续操作Open 动作通过api.ChangeQuery将查询改为mediamediaplayer.go即从当前卡片平滑跳转到完整播放器视图全程不改变播放状态。六、跨平台底层实现MPRIS / SMTC / MediaRemote官方文档明确指出Linux uses MPRIS. Windows and macOS use the platform media session. 源码将这套差异封装在MediaRetriever接口之后retriever.go三平台各自实现GetCurrentMedia与ControlMedia上层插件逻辑完全与平台无关。type MediaRetriever interface { UpdateAPI(api plugin.API) GetCurrentMedia(ctx context.Context) (*MediaInfo, error) ControlMedia(ctx context.Context, command string) error TogglePlayPause(ctx context.Context) error }6.1 LinuxMPRIS over D-BusLinux 实现位于 mediaplayer_linux.go。它通过MPRISMedia Player Remote Interfacing Specification协议与播放器通信通过org.freedesktop.DBus.ListNames列出所有以org.mpris.MediaPlayer2.开头的会话总线名称逐个读取org.mpris.MediaPlayer2.Player接口属性优先返回正在播放Playing的播放器否则回退到第一个可用的暂停/停止会话元数据字段映射关系getPlayerMediaInfoMPRIS 字段含义xesam:title曲目标题缺失时回退到xesam:urlxesam:artist艺术家字符串列表多艺术家以,拼接xesam:album专辑名mpris:length总时长微秒代码统一转换为秒mpris:artUrl封面地址支持data:URI 与file://本地文件两种形式PlaybackStatus播放状态Playing / Paused / StoppedIdentity根接口播放器应用名控制命令映射mapLinuxMediaControlMethodplay → Play、pause → Pause、toggle → PlayPause、next → Next、previous → Previous所有 D-Bus 调用都带700ms 超时并携带FlagNoAutoStart既保证响应速度又避免 Wox 意外唤醒播放器进程会话总线连接被缓存复用总线级错误时自动重置。6.2 WindowsSMTC 媒体会话Windows 实现分为 Go 层mediaplayer_windows.go与 CGO 层mediaplayer_windows.c对接的是SMTCSystem Media Transport Controls通过 WinRT 激活GlobalSystemMediaTransportControlsSessionManager枚举当前所有媒体会话会话打分机制wox_session_cheap_score用于在多会话时挑选最合适的那个正在播放10000已暂停100已停止10音乐类应用名称含 music / spotify / itunes / netease / foobar / vlc1000浏览器类应用chrome / msedge / firefox / electron在非播放状态时-20避免把网页视频误判为活跃媒体与系统当前会话一致时再加分。控制命令映射play → TryPlayAsync、pause → TryPauseAsync、toggle → TryTogglePlayPauseAsync、next → TrySkipNextAsync、previous → TrySkipPreviousAsync播放位置不是简单快照读取 Timeline 的Position与LastUpdatedTime后会根据 FILETIME 时间差推算当前进度并 clamp 到[0, Duration]mediaplayer_windows.c。Go 层对 Windows 的慢做了针对性优化RequestAsync并发调用可能挂起数秒因此查询被singleflight合并且500ms 内的快照直接复用windowsMediaCacheFreshFor同曲目复用已缓存的封面曲目切换时才重新拉取封面。配合advancePlaybackPositionmedia_info_util.go即使命中缓存快照进度条依然会继续走动。6.3 macOS借助com.apple.perl绕过 MediaRemote 限制macOS 的情况最为特殊详见 woxmr/README.md限制macOS 15 起私有框架 MediaRemote 只允许 bundle ID 以com.apple.*开头的进程调用绕过方案系统自带的/usr/bin/perl其 bundle ID 恰好是com.apple.perl因此 Wox 将 MediaRemote 调用搬进 Perl 进程执行实现仓库携带一个极小的 Perl XS 模块woxmr.bundleObjective-C 编写在 Perl 进程内通过dlopen dlsym动态加载 MediaRemote调用MRMediaRemoteGetNowPlayingInfoMRMediaRemoteGetNowPlayingApplicationIsPlayingMRMediaRemoteGetNowPlayingApplicationPID组装 JSON 后由adapter.pladapter.pl回传给 Wox命令协议/usr/bin/perl adapter.pl get|toggle|play|pause|next|previousGo 侧通过exec.CommandContext调用并解析 JSONmediaplayer_darwin.go。这一设计的优势是终端用户零额外依赖——不需要安装任何框架或工具链仅随 Wox 分发三个小文件woxmr.bundle、WoxMR.pm、adapter.pl。该方案只面向 Apple 平台的私有框架限制不影响其他平台。七、插件间命令接口暂停正在播放的媒体媒体播放器插件还对外提供了一组插件间命令通过api.OnHandlePluginCommand注册见 mediaplayer.go供其他内置插件调用命令行为返回值pause_if_playing仅在媒体正在播放时才发送暂停指令paused/not_playing/no_active_mediaplay/pause/toggle/next/previous直接执行对应媒体控制{Handled: true}或错误信息pause_if_playing的设计很精妙调用方只有在确实改变了播放状态收到paused时才需要在后续恢复播放避免误暂停已处于暂停状态的媒体。源码注释明确指出其典型使用场景——语音输入dictation期间暂停媒体、结束语音后恢复播放。八、实时刷新机制结果如何动起来播放进度、曲目切换都需要结果实时更新。插件通过每秒一次的 ticker 驱动refreshMediaPlayermediaplayer.go仅在主启动器可见时刷新api.IsVisible避免后台空转每个结果通过api.GetUpdatableResult检查是否仍在 UI 上可见不可见则移出跟踪队列拉取最新媒体信息后通过api.UpdateResult推送更新标题、副标题、进度、动作始终更新封面图标仅在播放状态或封面指纹SHA-256变化时才重绘减少不必要的图片解码开销UpdateResult返回 false 表示结果已不在 UI 中随即清理跟踪项。这套机制保证了用户在 Wox 里看着播放进度实时走动而无需反复重新输入查询。九、核心数据模型MediaInfo所有平台的媒体信息最终都归一化到统一的MediaInfo结构retriever.go字段类型说明Titlestring媒体标题Artiststring艺术家Albumstring专辑名Durationint64总时长秒Positionint64当前进度秒StatePlaybackState播放状态stopped / playing / paused / unknownAppNamestring媒体应用名称AppBundleIDstring应用 bundle ID 或进程名Artwork[]byte封面图原始字节 / base64 文本 / data URI播放状态枚举定义于 retriever.go各平台负责将自有状态映射过来MPRIS 的PlaybackStatus字符串、SMTC 的PlaybackStatus整数4playing、5paused、3stopped等都在各自的 retriever 中完成归一。十、参考源码索引如需进一步阅读实现细节可按以下路径深入插件主逻辑与 UI 数据组装mediaplayer.go跨平台接口与统一数据模型retriever.goLinux MPRIS 实现mediaplayer_linux.goWindows SMTCGo 层mediaplayer_windows.goWindows SMTCCGO 层含会话打分与异步等待mediaplayer_windows.cmacOS MediaRemote 桥接Go 层mediaplayer_darwin.gomacOS Perl 适配脚本adapter.plmacOS 桥接设计文档woxmr/README.md缓存快照与进度推算工具media_info_util.go赞分享桌面应用AI 应用插件系统【免费下载链接】WoxA cross-platform launcher that simply works项目地址https://gitcode.com/gh_mirrors/wo/Wox点击查看免费下载相关推荐Ruffty 类型检查器ignore 注释规则详解ignore-comment-unknown-rule 检测拼写错误的抑制注释Ruffty 类型检查器ignore 注释规则详解ignore comment unknown rule 检测拼写错误的抑制注释 ignore comme桌面应用AI 应用插件系统终极免费跨平台媒体播放器Jellyfin Media Player完全指南终极免费跨平台媒体播放器Jellyfin Media Player完全指南 Jellyfin Media Player是一款基于jellyfin web和MP音视频桌面应用Jellyfin Media Player完全手册跨平台媒体播放器终极指南Jellyfin Media Player完全手册跨平台媒体播放器终极指南 Jellyfin Media Player是一款基于Qt WebEngine和li音视频桌面应用上一篇EfficientNetV2_for_PyTorch性能优化秘籍单卡与8卡训练对比分析下一篇10个Qwen2.5-VL-72B-Instruct实用技巧提升图像和视频分析效果创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考