C# UWP中自定义MediaPlayerElement的TransportControls:如何在CCSelectionButton的MenuFlyoutItem中添加按钮以实现视频加载后添加字幕
我太懂这种找不到官方文档的憋屈了!你自定义了MediaPlayerElement的TransportControls,想在字幕选择按钮(CCSelectionButton)的下拉菜单里加个按钮,实现视频加载后手动添加字幕——就像系统自带播放器那样,对吧?这就给你唠唠具体怎么实现:
第一步:获取自定义TransportControls里的CCSelectionButton
首先得在自定义的TransportControls里拿到系统自带的字幕选择按钮,我们可以重写OnApplyTemplate方法来获取这个控件:
private CCSelectionButton _ccSelectionButton; protected override void OnApplyTemplate() { base.OnApplyTemplate(); // 从控件模板中取出字幕选择按钮 _ccSelectionButton = GetTemplateChild("CCSelectionButton") as CCSelectionButton; if (_ccSelectionButton != null) { // 拿到按钮后就可以开始自定义菜单了 CustomizeCCMenuFlyout(); } }
第二步:给字幕菜单添加“添加字幕”按钮
系统默认的字幕菜单是MenuFlyout类型,我们可以监听它的Opening事件(防止系统刷新菜单后自定义按钮消失),在菜单打开时插入我们的自定义按钮:
private void CustomizeCCMenuFlyout() { if (_ccSelectionButton.Flyout is MenuFlyout ccMenu) { // 绑定菜单打开事件,确保每次打开都能看到我们的按钮 ccMenu.Opening += CcMenu_Opening; } } private void CcMenu_Opening(object sender, object e) { if (sender is MenuFlyout ccMenu) { // 先检查按钮是否已存在,避免重复添加 var hasAddButton = ccMenu.Items.Any(item => (item as MenuFlyoutItem)?.Tag?.ToString() == "CustomAddSubtitleBtn"); if (!hasAddButton) { // 创建分隔线,区分系统选项和自定义选项 ccMenu.Items.Add(new MenuFlyoutSeparator()); // 创建“添加字幕”按钮 var addSubtitleItem = new MenuFlyoutItem { Text = "添加字幕", Tag = "CustomAddSubtitleBtn" // 标记我们的按钮,方便后续判断 }; // 绑定点击事件 addSubtitleItem.Click += AddSubtitleItem_Click; // 把按钮加到菜单最后 ccMenu.Items.Add(addSubtitleItem); } } }
第三步:实现“添加字幕”的核心逻辑
接下来就是处理按钮的点击事件,我们可以调用文件选择器让用户选本地字幕文件(比如.srt、.vtt格式),然后把字幕加载到MediaPlayer里:
private async void AddSubtitleItem_Click(object sender, RoutedEventArgs e) { // 初始化文件选择器,只允许选择字幕格式文件 var filePicker = new FileOpenPicker(); filePicker.FileTypeFilter.Add(".srt"); filePicker.FileTypeFilter.Add(".vtt"); filePicker.SuggestedStartLocation = PickerLocationId.VideosLibrary; var selectedFile = await filePicker.PickSingleFileAsync(); if (selectedFile != null) { // 把本地文件转换成MediaPlayer能识别的TimedMetadataTrack var subtitleTrack = await ConvertFileToSubtitleTrack(selectedFile); if (subtitleTrack != null && GetCurrentMediaPlayer() != null) { var mediaPlayer = GetCurrentMediaPlayer(); // 添加字幕轨道到播放器 mediaPlayer.AddTimedMetadataTrack(subtitleTrack, "zh-CN", TimedMetadataTrackPresentationMode.PlatformPresented); // 自动切换到刚添加的字幕 mediaPlayer.TimedMetadataTracks.SetPresentationMode(subtitleTrack, TimedMetadataTrackPresentationMode.PlatformPresented); } } } // 辅助方法:将本地字幕文件转为TimedMetadataTrack private async Task<TimedMetadataTrack> ConvertFileToSubtitleTrack(StorageFile subtitleFile) { try { var fileStream = await subtitleFile.OpenReadAsync(); // 根据文件后缀判断字幕类型 var trackType = subtitleFile.FileType == ".srt" ? TimedMetadataTrackType.Subtitle : TimedMetadataTrackType.Caption; // 创建字幕轨道 var track = TimedMetadataTrack.CreateFromStream(fileStream, trackType, subtitleFile.DisplayName, "zh-CN"); return track; } catch (Exception ex) { // 加载失败时给用户提示 await new MessageDialog($"字幕加载失败:{ex.Message}").ShowAsync(); return null; } } // 辅助方法:获取当前关联的MediaPlayer private MediaPlayer GetCurrentMediaPlayer() { if (Owner is MediaPlayerElement mediaElement) { return mediaElement.MediaPlayer; } return null; }
第四步:处理边界情况
最后还要注意几个细节:
- 如果MediaPlayer还没初始化,点击“添加字幕”按钮要做空判断,避免报错
- 如果系统默认隐藏了CCSelectionButton(比如视频没有内置字幕时),要确保我们的自定义逻辑不会触发异常
- 可以给“添加字幕”按钮加个图标,和系统菜单风格统一,比如用
Icon属性设置Symbol.Add
备注:内容来源于stack exchange,提问作者tAMBI99
相关产品推荐
相关产品推荐

