在 Silverlight 中播放带字幕的视频






4.17/5 (5投票s)
在 Silverlight 中播放带字幕的视频
引言
本文介绍如何在 Silverlight 中播放视频字幕。实现此功能非常容易。
背景
我需要在 Silverlight 视频中播放字幕。
我开始使用计时器实现此功能。我们可以将计时器间隔设置为 500 毫秒,计时器每 500 毫秒触发一次事件。我们可以编写逻辑来显示/隐藏字幕栏,从而实现我们的目标,但此方法存在问题。视频会缓冲,这会导致计时器与视频位置失去同步,因此此方法无法处理媒体缓冲的情况。
我找到了另一种实现方法。MediaElement
具有与当前加载的媒体元素关联的时间线标记集合。每次 MediaElement
打开新的媒体文件时,都会清除并重新填充该集合,并且仅在 MediaOpened
事件发生后才被认为是有效的。有关标记的更多信息,请访问以下链接:http://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement.markers(VS.95).aspx。
读者应该了解 Silverlight 的基础知识和 MediaElement
控件,才能理解本文。
Using the Code
我没有将媒体文件添加到 Zip 文件中,因此在运行解决方案之前,您必须在 Web 项目的 ClientBin 文件夹中添加一个名为 "SUP015.wmv" 的 WMV 文件。
定义字幕类,该类应具有字幕的开始时间、字幕的结束时间和字幕的消息。
public class Title
{
public string Id { get; set; }
public double InTime { get; set; }
public double OutTime { get; set; }
public string Message { get; set; }
}
我们可以使用 MarkerReached
事件,以便在视频到达字幕的开始或结束时间时收到通知。当 MediaElement
跳过时间线标记时,不会引发 MarkerReached
事件。每当到达与媒体关联的标记时,就会引发此事件。该标记可能来自以下三个位置之一:存储在当前打开的媒体的元数据中,与当前打开的媒体关联,或者来自单独的流,使用脚本显式添加到当前打开的媒体的 Markers
集合中。我们可以在 MediaElement
的 loaded 事件中订阅上述事件。
this.MediaEl.MarkerReached +=
new TimelineMarkerRoutedEventHandler(MediaEl_MarkerReached);
在播放媒体之前,我们必须为所有字幕添加标记。我们可以使用标记的两个属性:Time
和 Type
。Time
是 MediaElement
引发 MarkerReached
事件的时间跨度,Type
是一个字符串,可用于在 MarkerReached
事件发生时标识字幕。我们可以使用以下代码将所有字幕添加到 Markers
集合中
private void AddMarker()
{
foreach(Title comment in list)
{
this.MediaEl.Markers.Add(new TimelineMarker(){
Time = TimeSpan.FromSeconds(comment.InTime),
Type = comment.Id.ToString() + ":Start", Text = "Test"});
this.MediaEl.Markers.Add(new TimelineMarker() {
Time = TimeSpan.FromSeconds(comment.OutTime),
Type = comment.Id.ToString() + ":End", Text = "Test" });
}
}
在这里,我们使用 Type
来标识字幕以及它是字幕的开始还是结束。我们将每个字幕两次添加到 Markers
集合中,一次用于字幕的开始,一次用于字幕的结束。
以下是 MarkerReached
事件的代码
private void MediaEl_MarkerReached(object sender, TimelineMarkerRoutedEventArgs e)
{
string[] array = e.Marker.Type.Split(':');
if(array != null && array.Length == 2)
{
if(array[1] == "Start")
{
Title comment = list.SingleOrDefault(x => x.Id == array[0]);
if(comment != null)
{
this.CommentCanas.Visibility = System.Windows.Visibility.Visible;
CommentText.Text = comment.Message + " TimeSpan:" +
this.MediaEl.Position.ToString();
}
}
else if(array[1] == "End")
{
this.CommentCanas.Visibility = System.Windows.Visibility.Collapsed;
CommentText.Text = string.Empty;
}
}
}
我们可以从事件参数中获取标记的 Type
值。Type
包含字幕的唯一 ID 以标识字幕,以及 Start
或 End
以标识字幕的开始或结束。如果是 Start
,那么我们可以将 Canvas
的 Visibility
设置为 Visible
并设置文本。如果是 End
,那么我们可以将 Canvas
的 Visibility
设置为 Collapsed
。