MediaElement.NaturalDuration.TimeSpan返回值不准,如何获取精确视频时长?
如何获取MediaElement中视频的精确时长
你遇到的这个问题挺常见的——在MediaOpened事件触发时,MediaElement其实还没完全加载完视频的所有元数据,此时拿到的NaturalDuration只是一个近似值,所以才会出现显示4000ms但实际是4.3秒的偏差。
要获取精确时长,推荐用下面两种方法:
方法一:监听NaturalDurationChanged事件
这个事件会在MediaElement成功获取到完整、精确的媒体时长后触发,比MediaOpened可靠得多。
首先在XAML里给MediaElement绑定这个事件:
<MediaElement x:Name="mediaElement" Source="video.mp4" MediaOpened="mediaElement_MediaOpened" NaturalDurationChanged="mediaElement_NaturalDurationChanged"/>
然后在后台代码里实现事件处理逻辑,记得先检查HasTimeSpan属性,避免因媒体格式不支持或加载失败导致异常:
private void mediaElement_NaturalDurationChanged(object sender, RoutedEventArgs e) { if (mediaElement.NaturalDuration.HasTimeSpan) { double totalTime = mediaElement.NaturalDuration.TimeSpan.TotalMilliseconds; Console.WriteLine("Total video time: {0}", totalTime); } }
方法二:用MediaTimeline提前解析时长
如果需要在视频播放前就获取精确时长,可以用MediaTimeline来预加载媒体信息:
var mediaTimeline = new MediaTimeline(new Uri("video.mp4", UriKind.Relative)); var mediaClock = mediaTimeline.CreateClock(); // 启动时钟以加载媒体元数据 mediaClock.Controller.Begin(); // 等待直到获取到精确时长 while (mediaClock.CurrentState == ClockState.Active && !mediaTimeline.NaturalDuration.HasTimeSpan) { System.Threading.Thread.Sleep(10); } if (mediaTimeline.NaturalDuration.HasTimeSpan) { double totalTime = mediaTimeline.NaturalDuration.TimeSpan.TotalMilliseconds; Console.WriteLine("Total video time: {0}", totalTime); } // 记得停止时钟释放资源 mediaClock.Controller.Stop();
为什么MediaOpened里拿不到精确值?
简单来说,MediaOpened事件只是通知你“媒体已经开始打开了”,但此时底层的媒体解码组件可能还在读取视频的元数据(比如时长、帧率这些),所以返回的是一个临时的估算值。而NaturalDurationChanged会在完整的元数据加载完成后触发,这时候的时长就是准确的了。
内容的提问来源于stack exchange,提问作者HeideKnight
相关产品推荐
相关产品推荐

