很明显我在下面尝试做什么,但是我得到以下异常:
无法为"持续时间"值"自动"返回TimeSpan属性值.
我很沮丧地读到这个
在MediaOpened发生之后才能确定NaturalDuration.(链接)
这是否意味着我必须想出一个人工打开文件的方法,在单独的线程中等待媒体打开事件,然后仅在事件触发后返回持续时间?
public static int PlayAudio(string fileName)
{
try
{
myMediaPlayer.Stop();
myMediaPlayer.Close();
myMediaPlayer.Open(new Uri(filename));
myMediaPlayer.Play();
return myMediaPlayer.NaturalDuration.TimeSpan.Milliseconds;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return -1;
}
}
Run Code Online (Sandbox Code Playgroud)
我必须想出一个人为的打开文件的方法,在单独的线程中等待媒体打开事件,然后只在事件被触发后返回持续时间
不幸的是,这正是它的意思.以下是我刚才想到的:
using System;
using System.Threading;
using System.Windows.Media;
using System.Windows.Threading;
class Program
{
static void Main(string[] args)
{
var mediaFile = @"c:\path\to\mediafile.mp3";
var duration = GetMediaDuration(mediaFile, TimeSpan.FromMilliseconds(500));
Console.WriteLine(duration.ToString());
Console.ReadKey();
}
static TimeSpan GetMediaDuration(string mediaFile)
{
return GetMediaDuration(mediaFile, TimeSpan.Zero);
}
static TimeSpan GetMediaDuration(string mediaFile, TimeSpan maxTimeToWait)
{
var mediaData = new MediaData() {MediaUri = new Uri(mediaFile)};
var thread = new Thread(GetMediaDurationThreadStart);
DateTime deadline = DateTime.Now.Add(maxTimeToWait);
thread.Start(mediaData);
while (!mediaData.Done && ((TimeSpan.Zero == maxTimeToWait) || (DateTime.Now < deadline)))
Thread.Sleep(100);
Dispatcher.FromThread(thread).InvokeShutdown();
if (!mediaData.Done)
throw new Exception(string.Format("GetMediaDuration timed out after {0}", maxTimeToWait));
if (mediaData.Failure)
throw new Exception(string.Format("MediaFailed {0}", mediaFile));
return mediaData.Duration;
}
static void GetMediaDurationThreadStart(object context)
{
var mediaData = (MediaData) context;
var mediaPlayer = new MediaPlayer();
mediaPlayer.MediaOpened +=
delegate
{
if (mediaPlayer.NaturalDuration.HasTimeSpan)
mediaData.Duration = mediaPlayer.NaturalDuration.TimeSpan;
mediaData.Success = true;
mediaPlayer.Close();
};
mediaPlayer.MediaFailed +=
delegate
{
mediaData.Failure = true;
mediaPlayer.Close();
};
mediaPlayer.Open(mediaData.MediaUri);
Dispatcher.Run();
}
}
class MediaData
{
public Uri MediaUri;
public TimeSpan Duration = TimeSpan.Zero;
public bool Success;
public bool Failure;
public bool Done { get { return (Success || Failure); } }
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3452 次 |
| 最近记录: |