2017-05-05 92 views
0

我有以下代码和注释。我正在寻找一种更好的方式来做到这一点,而无需调用Application.DoEvents()。如何正确等待MediaPlayer打开

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

如果'MediaOpen'是一个事件,然后代替轮询'IsOpen'属性,订阅该事件(添加事件处理程序),并继续从那里执行(即,将'GetNextFrame'部分向上移动到您当前将'IsOpen'设置为true的位置,并且完全省略循环) – dlatikay

+0

是的,如果出现这种情况,那就是我要做的。但我实际上开放了其中的7个,这样可能会变得很麻烦。 – user7049117

回答

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(); 

更多ressources herehere