我在下面跟随以下代码并附有评论。我正在寻找一种更好的方法,而无需调用Application.DoEvents()。
public class Player : IDisposable
{
public bool IsOpen
{
get; private set;
}
///Opens the media player. This is very fast, but the actually opening takes a bit longer.
///When it does open, it fires the MediaPlayer_MediaOpened event
public bool Open(string fileName)
{
// close previous file
Close();
mediaPlayer = new MediaPlayer();
mediaPlayer.ScrubbingEnabled = true;
mediaPlayer.MediaOpened += MediaPlayer_MediaOpened;
mediaPlayer.Open(new Uri(fileName));
return true;
}
/// <summary>
/// Fires when the MediaPlayer has finished opening.
/// </summary>
private void MediaPlayer_MediaOpened(object sender, EventArgs e)
{
totalMilliseconds = mediaPlayer.NaturalDuration.TimeSpan.TotalMilliseconds;
//40.00 represents 25 frames a second.
int totFrames = (int)(totalMilliseconds / 40.00);
framePixels = new uint[mediaPlayer.NaturalVideoWidth * mediaPlayer.NaturalVideoHeight];
previousFramePixels = new uint[framePixels.Length];
for (int i = 0; i < totFrames; i++)
totalFrames.Add(TimeSpan.FromMilliseconds((((2 * i) + 1) * totalMilliseconds) / (2 * totFrames)));
IsOpen = true;
}
}
所以,当我创建对象并打开它时,我必须等待MediaOpen事件才能触发,然后才能执行任何操作,例如抓取框架。这就是我在下面等待的方式。这是我不喜欢的部分,并希望以不同的方式做。
player = new Player();
player.Open("C:\\FileName.avi");
//This is the part i don't liie. There HAS to be a better way.
DateTime waitStarted = DateTime.Now;
while (!player.IsOpen)
{
Thread.Sleep(5);
if ((DateTime.Now - waitStarted).TotalSeconds >= 5)
throw new Exception("Timed Out While Waiting For Videos To Open.");
Application.DoEvents();
}
Bitmap b = player.GetNextFrame();
先谢谢你的帮助。
答案 0 :(得分:0)
我没有尝试编译此代码,但我认为它会对您有所帮助。
public class Player : IDisposable
{
public bool IsOpen
{
get; private set;
}
///You have to return a task to run this code asynchronously
public Task Open(string fileName)
{
// close previous file
Close();
mediaPlayer = new MediaPlayer();
mediaPlayer.ScrubbingEnabled = true;
mediaPlayer.MediaOpened += MediaPlayer_MediaOpened;
return Task.Run(mediaPlayer.Open(new Uri(fileName)));
}
/// <summary>
/// Fires when the MediaPlayer has finished opening.
/// </summary>
private void MediaPlayer_MediaOpened(object sender, EventArgs e)
{
totalMilliseconds = mediaPlayer.NaturalDuration.TimeSpan.TotalMilliseconds;
//40.00 represents 25 frames a second.
int totFrames = (int)(totalMilliseconds / 40.00);
framePixels = new uint[mediaPlayer.NaturalVideoWidth * mediaPlayer.NaturalVideoHeight];
previousFramePixels = new uint[framePixels.Length];
for (int i = 0; i < totFrames; i++) {
totalFrames.Add(TimeSpan.FromMilliseconds((((2 * i) + 1) * totalMilliseconds) / (2 * totFrames)));
IsOpen = true;
}
}
player = new Player();
//The program wait the player to open before continuing
//you'll need to add the async keyword on the signature method containing this code.
await player.Open("C:\\FileName.avi");
Bitmap b = player.GetNextFrame();