尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Windows-universal-samples 系统媒体传输控件(SMTC)手动集成指南:JavaScript 示例源码级解析

发布时间:2026/9/26 2:04:22

资讯中心
01
ARTICLE

Windows-universal-samples 系统媒体传输控件(SMTC)手动集成指南:JavaScript 示例源码级解析

Windows-universal-samples 系统媒体传输控件(SMTC)手动集成指南:JavaScript 示例源码级解析
示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载本指南围绕 Windows-universal-samples 仓库中 archived/SystemMediaTransportControls/README.md 所描述的手动集成示例展开深入剖析如何通过Windows.Media命名空间下的 SystemMediaTransportControlsSMTCAPI让 UWP 应用响应键盘媒体键、系统媒体浮出控件flyout事件并向系统上报当前播放状态、时间轴位置与媒体元数据。读完本文你将掌握 SMTC 的完整手动集成流程并能在不使用 MediaPlayer 自动集成的情况下将基于 HTML5video/audio元素的播放器接入系统媒体控制中心。背景为什么需要手动集成 SMTCSystemMediaTransportControls 是 Windows 10 提供的系统级媒体控制入口。用户在键盘上按下 Play/Pause、Next、Previous 等媒体键或在屏幕右上角弹出的系统媒体浮出控件中点击按钮时这些操作会通过 SMTC 转发给当前正在播放媒体的应用反过来应用也必须通过 SMTC 把播放状态、时间轴进度、标题与封面等元数据同步给系统系统 UI 才能正确展示。该示例核心演示的是manual手动集成。与之相对的是 MediaPlayer 的automatic自动集成——MediaPlayer 内置的 CommandManager 会自动完成状态同步、按钮状态推断和元数据上报。手动集成意味着应用需要自己更新所有状态并处理 SMTC 的全部事件。正如 archived/SystemMediaTransportControls/README.md 所指出的除非你确实需要手动集成例如使用 WASAPI 或 AudioGraph 这类不经过 MediaPlayer 的音频 API官方推荐优先使用 CommandManager 提供的内置集成。两种方式的差异可以归纳为维度自动集成CommandManager手动集成本示例时间轴属性同步从播放器自动同步应用自行调用updateTimelineProperties按钮状态自动推断可再自定义应用通过isXxxEnabled属性自行维护元数据更新通过MediaPlaybackItem.ApplyDisplayProperties()直接操作displayUpdater事件处理内置应用注册buttonpressed等事件处理器无论哪种方式都需要注意一点SMTC 只有在应用开始一次音频播放会话后才会首次显示数据该限制在 archived/SystemMediaTransportControls/README.md 中有明确说明。示例工程结构速览本示例位于仓库的archived/SystemMediaTransportControls目录下仅提供 JavaScriptWinJS实现archived/SystemMediaTransportControls/ ├── README.md └── js/ ├── SystemMediaTransportControls.jsproj # 工程文件 ├── SystemMediaTransportControls.sln # 解决方案文件 ├── package.appxmanifest # 应用清单 ├── css/scenario1.css ├── html/scenario1.html # 场景页面含 video 元素 └── js/ ├── sample-configuration.js # 示例场景注册 └── scenario1.js # SMTC 手动集成核心逻辑从 js/SystemMediaTransportControls.jsproj 可以看到工程通过Content Include引用了仓库 SharedContent 下的 WinJS 运行时base.js、ui.js以及default.html、default.js、sample-utils等共享页面框架构建目标平台为 UAPTargetPlatformVersion为 10.0.18362.0。js/package.appxmanifest 声明了Windows.Universal目标设备家族MinVersion 10.0.10240.0、MaxVersionTested 10.0.18362.0并仅申请了internetClient一项能力——播放本地媒体文件本身不需要额外能力声明。核心流程总览从选文件到系统 UI 更新示例只有一个场景Scenario 1注册于 js/js/sample-configuration.js页面为 js/html/scenario1.html其中放置了一个video idplayer元素msaudiocategoryMedia和一个 Select Files 按钮。整体流程如下页面ready时调用setupSystemMediaTransportControls()获取 SMTC 实例并注册事件、按初始无媒体状态禁用控件用户点击 Select Files 后getFilesWithPicker()打开FileOpenPicker多选媒体文件构成播放列表setNewMediaItem()根据列表位置启停 Next/Previous 按钮将文件设为video的 src 并自动播放updateSystemMediaControlsDisplayAsync()通过displayUpdater.copyFromFileAsync()从文件提取元数据并update()到系统 UI播放过程中通过playerPlaying/playerPaused等事件回写playbackStatus并每隔 5 秒调用updateSmtcPosition()同步时间轴systemMediaControlsButtonPressed等事件处理器响应系统侧的用户操作反向控制播放器。获取并初始化 SMTC 实例在 js/js/scenario1.js 的setupSystemMediaTransportControls()中第一步是通过getForCurrentView()获取 SMTC 对象systemMediaControls Windows.Media.SystemMediaTransportControls.getForCurrentView();值得强调的是每个视图view/window有且仅有一个 SMTC 实例由系统在首次调用getForCurrentView()时创建同视图内后续所有调用都返回同一实例。因此示例中多个场景页共享该实例这也是页面unload时必须移除事件处理器、避免幽灵处理器残留的原因。初始化时示例做了三件事systemMediaControls.isEnabled false; systemMediaControls.isPlayEnabled true; systemMediaControls.isPauseEnabled true; systemMediaControls.isStopEnabled true; systemMediaControls.playbackStatus Windows.Media.MediaPlaybackStatus.closed;isEnabled false初始无媒体时禁用 SMTC系统不会显示媒体控制 UI应用也收不到任何按钮事件。这是一个非常实用的总开关——当用户导航到应用中不涉及播放的页面时可以借此整体关掉系统媒体控件。逐个启用 Play、Pause、Stop 按钮isXxxEnabled默认均为false而isEnabled默认是true。playbackStatus置为closed表示当前没有可播放的媒体。要使应用能收到媒体键/软按钮事件需要同时满足三个条件① 注册buttonpressed事件②isEnabled为true③ 对应按钮的isXxxEnabled为true源码注释中对这三点有完整说明。另外示例注释还提到允许应用在后台播放音频的前提之一就是启用对 Play 和 Pause 按钮事件的处理——这也是 SMTC 与后台音频能力Background Audio联动的基础。建立播放列表并加载媒体项文件选择与格式白名单getFilesWithPicker()创建Windows.Storage.Pickers.FileOpenPicker并设置了列表视图模式、起始位置为音乐库、提交按钮文字为 Playvar filePicker new Windows.Storage.Pickers.FileOpenPicker(); filePicker.viewMode Windows.Storage.Pickers.PickerViewMode.list; filePicker.suggestedStartLocation Windows.Storage.Pickers.PickerLocationId.musicLibrary; filePicker.commitButtonText Play;随后把音频与视频格式白名单逐个append到fileTypeFilter。音频格式包括.3g2/.3gp2/.3gp/.3gpp/.m4a/.mp4/.asf/.wma/.aac/.adt/.adts/.mp3/.wav/.ac3/.ec3视频格式包括.3g2/.3gp2/.3gp/.3gpp/.m4v/.mp4v/.mp4/.mov/.m2ts/.asf/.wmv/.avi支持格式的完整官方列表可查阅 Windows 开发者文档中关于 supported audio and video formats 的说明。pickMultipleFilesAsync()返回用户选择的StorageFile数组示例将其赋给playlist随即systemMediaControls.isEnabled true; // 有播放列表后开启 SMTC player.autoplay true; // 让媒体加载后自动开始播放 setNewMediaItem(0); // 从第一项开始注意源码注释中的设计意图即使部分文件可能加载失败也先启用 SMTC这样用户仍可通过 Next/Previous 跳到列表中的其他项继续尝试。setNewMediaItem按播放列表位置维护按钮状态setNewMediaItem(newItemIndex)的核心职责之一是维护 Next/Previous 按钮的可用性if (newItemIndex playlist.length - 1) { systemMediaControls.isNextEnabled false; newItemIndex playlist.length - 1; } else { systemMediaControls.isNextEnabled true; } if (newItemIndex 0) { systemMediaControls.isPreviousEnabled false; newItemIndex 0; } else { systemMediaControls.isPreviousEnabled true; }即在最后一项时禁用 Next在第一项时禁用 Previous并自动把越界的索引夹取回合法范围。随后把当前文件通过URL.createObjectURL(mediaFile, { oneTimeOnly: true })设为video的src并异步更新系统 UI 元数据。Play、Pause、Stop 按钮已在setupSystemMediaTransportControls()中启用无需重复设置。向系统同步播放状态与时间轴playbackStatus 的准确回写playbackStatus的准确性直接影响系统 UI它决定浮出控件显示播放还是暂停按钮也决定键盘上的播放/暂停切换键会触发 Play 还是 Pause 事件。示例通过监听 HTML5 媒体元素自身的playing/pause/ended/error事件来维护该状态js/js/scenario1.js 中playerPlaying、playerPaused、playerEnded、playerError。源码注释特别强调即便你的应用实现了自定义播放控件、不用元素自带的默认传输控件依然推荐监听元素事件。因为 Windows 支持Play To场景——用户可通过 Devices 选择把媒体流投放到网络设备如电视此时用户可能用电视遥控器暂停/恢复播放元素事件可能是应用唯一能感知到状态变化的途径。// 播放中 systemMediaControls.playbackStatus Windows.Media.MediaPlaybackStatus.playing; // 暂停 systemMediaControls.playbackStatus Windows.Media.MediaPlaybackStatus.paused; // 出错文件无法播放 systemMediaControls.playbackStatus Windows.Media.MediaPlaybackStatus.closed;stopPlayer()演示了本地文件的停止语义暂停 回零 上报stopped状态。源码注释指出对于直播等场景停止可能需要按暂停处理或干脆不支持。时间轴属性与定时同步updateSmtcPosition()构建SystemMediaTransportControlsTimelineProperties对象并调用updateTimelineProperties()上报var timelineProperties new Windows.Media.SystemMediaTransportControlsTimelineProperties(); timelineProperties.startTime 0; timelineProperties.minSeekTime 0; timelineProperties.position player.currentTime * 1000; timelineProperties.maxSeekTime player.duration * 1000; timelineProperties.endTime player.duration * 1000; systemMediaControls.updateTimelineProperties(timelineProperties);本示例是支持任意位置拖动的简单场景因此startTime/minSeekTime均为 0endTime/maxSeekTime均为时长——等于告诉系统整条音轨任意位置都可寻址。源码注释给出了扩展方向更复杂的场景可以只允许在内容的某个区间内 seek将 min/max seek 设为与 start/end 不同的值直播场景则可能频繁更新endTime。注意属性单位为毫秒而 HTML5 媒体的currentTime/duration是秒所以需要乘 1000。同步时机有两种状态变化时立即同步一次以及播放期间用setInterval(updateSmtcPosition, 5000)每 5 秒同步一次暂停时clearInterval停掉定时器这样系统时间轴不至于与真实播放进度偏差过大。媒体元数据DisplayUpdater 的三种用法从文件自动提取copyFromFileAsyncupdateSystemMediaControlsDisplayAsync(mediaFile)先通过getMediaTypeFromFileContentType()依据文件的 MIME 类型contentType判断MediaPlaybackTypeaudio/*→musicvideo/*→videoimage/*→image其他 →unknown注意MediaPlaybackType.unknown不是copyFromFileAsync的合法入参该方法仅作为无法判定类型的哨兵值返回类型合法时调用updatePromise systemMediaControls.displayUpdater.copyFromFileAsync(mediaType, mediaFile);copyFromFileAsync()会按传入的MediaPlaybackType从StorageFile中尽力提取对应元数据例如music类型会提取曲目标题、艺术家、专辑封面等。源码注释给出两点注意事项第一个参数不能是unknown对某些文件错误如用户选完文件后文件被删除导致的 file-not-found该方法可能报错。示例用WinJS.Promise.as(false)构造假失败来统一处理类型未知与提取失败两种分支并在.then的错误分支中把异常转换为false结果。失败兜底与刷新系统 UI如果更新失败示例调用displayUpdater.clearAll()清空之前残留的元数据避免系统 UI 显示上一个媒体项的过期信息最后无论成功与否都调用systemMediaControls.displayUpdater.update();把 DisplayUpdater 中当前的值无论来自copyFromFileAsync、手动赋值还是clearAll之后的空状态真正提交到系统 UI。完全手动设置元数据README 明确指出你可以不依赖文件提取直接操作 DisplayUpdater 的相关属性手动设置全部元数据标题、艺术家、专辑、缩略图等。当应用场景不涉及StorageFile例如网络流媒体或文件类型无法判定时这是推荐的做法——只需选定一个合法的MediaPlaybackType然后给 DisplayUpdater 及关联类如MusicProperties、VideoProperties、Thumbnail的属性赋值最后update()提交。处理系统侧事件五类事件处理器buttonpressed接收媒体键与软按钮命令systemMediaControlsButtonPressed是核心事件处理器eventIn.button为SystemMediaTransportControlsButton枚举值示例用 switch 分派按钮示例动作playplayer.play()pauseplayer.pause()stopstopPlayer()暂停并回零nextsetNewMediaItem(currentItemIndex 1)previoussetNewMediaItem(currentItemIndex - 1)源码注释提醒若要处理更多按钮如fastForward、rewind、record等需在 switch 中补充 case并记得先用对应的isXxxEnabled属性启用该按钮否则系统不会向其派发事件。propertychanged响应系统音量/静音变化systemMediaControlsPropertyChanged监听SystemMediaTransportControlsProperty.soundLevel变化。当系统把应用静音SoundLevel.muted时示例暂停播放并置pausedDueToMute true以释放资源当恢复为full或low时自动续播并复位标志。这是对系统音频会话被抢占/静音这一 UWP 常见场景的标准处理模式。playbackratechangerequested倍速请求systemMediaControlsPlaybackRateChangeRequested校验请求值在 02 倍速范围内后写入player.playbackRate并回写systemMediaControls.playbackRate让系统知道新的倍速值。这里体现了 SMTC 事件处理的通用模式校验请求 → 执行 → 把新状态回写 SMTC。playbackpositionchangerequestedseek 请求systemMediaControlsPlaybackPositionChangeRequested校验请求位置在[0, player.duration]范围内且仅在播放已开始playerState started时执行player.currentTime eventIn.requestedPlaybackPosition随后立即updateSmtcPosition()同步时间轴。源码注释提示这是假设起始时间为 0 的简化版本带偏移起播的场景需要更严谨的边界检查。autorepeatmodechangerequested循环模式请求systemMediaControlsAutoRepeatModeChangeRequested处理MediaPlaybackAutoRepeatMode的三种取值由于 HTML5 元素本身只支持单曲循环loop列表循环需自行实现请求模式实现方式Noneplayer.loop false; repeatPlaylist falseListplayer.loop false; repeatPlaylist true由playerEnded中检测repeatPlaylist回到列表头Trackplayer.loop true; repeatPlaylist false随后回写systemMediaControls.autoRepeatMode eventIn.requestedAutoRepeatMode。playerEnded()中的完整逻辑是未到列表尾则自动播下一项到列表尾且repeatPlaylist为真则回到第 0 项否则stopPlayer()并停止位置同步定时器。页面生命周期事件清理与状态复位由于 SMTC 实例与当前视图一一对应、跨场景页共享示例在 WinJS 页面unload钩子中做了对称清理js/js/scenario1.jsremoveEventListener移除全部五类事件处理器buttonpressed、propertychanged、playbackratechangerequested、playbackpositionchangerequested、autorepeatmodechangerequested防止用户导航到其他场景页后旧处理器仍被触发player.src null清空媒体源清空playlist、复位currentItemIndexclearInterval(positionUpdateTimerId)停止位置同步定时器。这也是手动集成场景下容易被忽略的细节每个处理器都应能感知当前场景是否仍然激活示例通过isScenario1Active标志在进入ready时置真、unload时置假每个事件处理器开头都做检查异步操作完成回调中也应做同样的激活检查避免操作在页面离开后继续污染系统 UI。构建与运行系统要求源自 archived/SystemMediaTransportControls/README.mdWindows 10 版本 1607桌面端与移动端即需要支持 SMTC 时间轴属性等 API 的系统版本。构建步骤若以 ZIP 方式下载整个 samples 集合务必解压整个归档文件而不仅是示例所在文件夹——本工程通过相对链接依赖 SharedContent 中的 WinJS 与页面框架参见 js/SystemMediaTransportControls.jsproj 中的链接项用 Visual Studio 打开解决方案File Open Project/Solution定位到解压目录下的 Samples 子目录、本示例子目录、js语言子目录双击SystemMediaTransportControls.sln按CtrlShiftB或选择Build Build Solution编译。运行步骤仅部署选择Build Deploy Solution部署并调试运行按F5或选择Debug Start Debugging不调试直接运行按CtrlF5或选择Debug Start Without Debugging。验证方式运行后在页面中点击 Select Files 选择音视频文件即可使用键盘媒体键Play/Pause、Previous、Next或平板设备上的硬件按键控制播放并观察屏幕右上角系统浮出控件中的状态与元数据。也可用音量加减键唤起浮出控件再以鼠标或触摸点击其中的软件按钮来控制播放——这正是 js/html/scenario1.html 页面描述中建议的观察方法。关键 API 速查API作用示例中的用法SystemMediaTransportControls.getForCurrentView()获取当前视图的 SMTC 实例每视图唯一setupSystemMediaTransportControls()isEnabledSMTC 总开关初始false选完文件后置trueisPlayEnabled/isPauseEnabled/isStopEnabled/isNextEnabled/isPreviousEnabled逐按钮启用/禁用初始化与setNewMediaItem()中维护playbackStatus播放状态closed/playing/paused/stopped各媒体元素事件处理器中回写playbackRate/autoRepeatMode倍速与循环模式回写对应changerequested处理器SystemMediaTransportControlsTimelinePropertiesupdateTimelineProperties()上报时间轴毫秒updateSmtcPosition()displayUpdater.copyFromFileAsync(type, file)从文件提取元数据updateSystemMediaControlsDisplayAsync()displayUpdater.clearAll()/update()清空 / 提交元数据更新失败兜底与最终提交buttonpressed/propertychanged/playbackratechangerequested/playbackpositionchangerequested/autorepeatmodechangerequested系统侧事件五个对应的事件处理器掌握这套手动集成模式后无论播放内核是 HTML5 媒体元素、WASAPI、AudioGraph 还是其他自定义引擎你都可以把播放状态、时间轴与元数据完整地呈现到 Windows 系统媒体控制中心并正确响应来自键盘、硬件按键与系统浮出控件的全部控制命令。赞分享示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载相关推荐UWP 自定义媒体传输控件实战解析 Windows-universal-samples 的 XamlCustomMediaTransportControls 示例UWP 自定义媒体传输控件实战解析 Windows universal samples 的 XamlCustomMediaTransportControls示例工程深入解析 Windows-universal-samples 的 Background Transfer 示例用 UWP 后台传输 API 完成文件下载与上传深入解析 Windows universal samples 的 Background Transfer 示例用 UWP 后台传输 API 完成文件下载与上传示例工程DirectWrite 行距模式实战Windows-universal-samples 的 DWriteLineSpacingModes 示例源码级解析DirectWrite 行距模式实战Windows universal samples 的 DWriteLineSpacingModes 示例源码级解析 本文示例工程上一篇ECC 之 harness-optimizer用 Eval 驱动方式系统化调优 Agent 工作台配置Harness Audit passk下一篇InspectpackWebpack 前端 JavaScript 包的检查工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。