2013-04-08 103 views
4

我创建了包含在我玩一些影片的AxWMPLib.AxMediaPlayer一个WinForm应用程序播放声音平行。我还必须在其他线程中播放其他自定义声音。为此,我使用了System.Media.SoundPlayer.PlaySync()。这个线程循环播放几个声音文件。问题是当我暂停/停止视频时,按钮事件声音播放正常。但是当视频正在运行时,有时会跳过一些声音文件。它随机发生。 任何人都可以给出一些关于这个问题的解释,以及如何完成它。我的意思是我怎样才能同时播放这两种声音和视频。与System.Media.SoundPlayer.PlaySync()和AxWindowsMediaPlayer

视频将在UI线程玩和其他声音是从不同的打thread.Please检查出波纹管代码:

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using System.Threading; 
using ElectroQ; 
using ElectroQServer1.Entities; 
using WMPLib; 
using System.Media; 
using System.Windows.Media; 

namespace ElectroQServer1 
{ 
    public partial class Form1 : Form 
    { 
     Thread dbListenerThread; 
     IWMPPlaylist playlist; 

     //string[] tokenNumber = { "A001", "B002", "C003", "D004","E005", "F006", "G007","HAMB" }; 
     //string[] counterNumber = { "01", "02", "03", "04", "05", "06", "07", "MB" }; 
     public Form1() 
     { 
      InitializeComponent(); 
      //ResizeRedraw = true; 
      this.SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, true); 
      this.WindowState = FormWindowState.Maximized; 
      //this.FormBorderStyle = FormBorderStyle.None; 
      //this.TopMost = true; 


      dbListenerThread = new Thread(RefreshQueueBoard); 
      dbListenerThread.Start(); 

     } 
     /// <summary> 
     /// This method is used to prevent the flickering of the window. 
     /// </summary> 
     protected override CreateParams CreateParams 
     { 
      get 
      { 
       CreateParams cp = base.CreateParams; 
       cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED 
       return cp; 
      } 
     } 
     public void RefreshQueueBoard() 
     { 
      //Thread.Sleep(000); 
      while (true) 
      { 
       List<QueueData> lstQData = DA.GetAllQueueData(" where service_status_id = 2 "); 
       printToken(lstQData); 
       printCounter(lstQData); 

       playSound(lstQData); 
       Thread.Sleep(1000); 
      } 
     } 

     public void playSound(List<QueueData> lstQData) 
     { 
      foreach (QueueData qData in lstQData) 
      { 
       if (!qData.SoundPlayed) 
       { 
        string strSoundFile; 
        PlaySoundFIle(@"Sounds/TN.WAV"); 
        foreach (char c in qData.ServiceQueueSerial) 
        { 
         strSoundFile = string.Format(@"Sounds/{0}.WAV", c); 
         PlaySoundFIle(strSoundFile); 
        } 
        PlaySoundFIle(@"Sounds/CN.WAV"); 
        foreach (char c in qData.ServiceCounterID) 
        { 
         strSoundFile = string.Format(@"Sounds/{0}.WAV", c); 
         PlaySoundFIle(strSoundFile); 
        } 
        string strUpdateQuery = string.Format("UPDATE electro_queue SET sound_played = 1 WHERE service_queue_serial = '{0}'", qData.ServiceQueueSerial); 
        DA.UpdateQueueData(strUpdateQuery); 

       } 
      } 
     } 

     public void PlaySoundFIle(string strFile) 
     { 
      //string[] files = new string[4] { @"Sounds/TN.WAV", @"Sounds/CN.WAV", @"Sounds/TN.WAV", @"Sounds/CN.WAV"}; 

      //WaveIO wa = new WaveIO(); 
      //wa.Merge(files, @"tempfile.wav"); 
      //MediaPlayer wowSound = new MediaPlayer(); //Initialize a new instance of MediaPlayer of name wowSound 
      //wowSound.Open(new Uri(@"tempfile.wav", UriKind.Relative)); //Open the file for a media playback 
      //wowSound.Play(); 
      using (var soundPlayer = new SoundPlayer(strFile)) 
      { 
       soundPlayer.PlaySync(); // can also use soundPlayer.Play() but it misses some sound file. 
      } 
     } 

     private void printToken(List<QueueData> lstQData) 
     { 
      if (InvokeRequired) 
      { 
       this.Invoke(new MethodInvoker(delegate 
       { 
        pnlQStat.Controls.Clear(); 
        string dir; 
        //int xpos = 55; 
        //int ypos = 207; 
        int xpos = 10; 
        int ypos = 00; 
        //int k=0; 
        for (int i = 0; i < lstQData.Count; i++) 
        { 
         /* if (i == 4 || i == 8) 
         { 
          ypos = ypos - 360; 
          xpos = 675; 
         }*/ 

         foreach (char c in lstQData[i].ServiceQueueSerial) 
         { 
          if (i == 0) 
          { 
           dir = "Resources/_" + c + ".bmp"; 
          } 
          else 
          { 
           dir = "Resources/" + c + ".bmp"; 
          } 
          createPicBox(dir, "pBox" + i, xpos, ypos); 
          xpos = xpos + 43; 

         } 

         ypos = ypos + 50; 
         xpos = 10; 


        } 
       })); 
       return; 
      } 
     } 

     private void printCounter(List<QueueData> lstQData) 
     { 
      if (InvokeRequired) 
      { 
       this.Invoke(new MethodInvoker(delegate 
       { 

        //int xpos = 415; 
        //int ypos = 207; 
        //int xpos = 292; 
        int xpos = 220; 
        int ypos = 00; 
        //int k=0; 
        for (int i = 0; i < lstQData.Count; i++) 
        { 
         /*if (i == 4 || i == 8) 
         { 
          ypos = ypos - 360; 
          xpos = 1035; 
         } 
         */ 
         foreach (char c in lstQData[i].ServiceCounterID) 
         { 
          string dir; 
          if (i == 0) 
          { 
           dir = "Resources/_" + c + ".bmp"; 
          } 
          else 
          { 
           dir = "Resources/" + c + ".bmp"; 
          } 
          //string dir = "Resources/" + c + ".bmp"; 
          createPicBox(dir, "pBox" + i, xpos, ypos); 
          xpos = xpos + 63; 

         } 

         ypos = ypos + 50; 
         xpos = xpos - 63; 


        } 
       })); 
       return; 
      } 
     } 
     private void createPicBox(string directory, string name, int xposition, int yposition) 
     { 
      PictureBox picBox = new System.Windows.Forms.PictureBox(); 
      picBox.Name = name; 

      picBox.Location = new System.Drawing.Point(xposition, yposition); 
      picBox.Size = new System.Drawing.Size(40, 50); 

      picBox.BackgroundImage = Image.FromFile(directory); 
      picBox.BackgroundImageLayout = ImageLayout.Stretch; 
      pnlQStat.Controls.Add(picBox); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      createPlayList(); 
      //dbListenerThread.Abort(); // this line of code should be placed in onClosing Event. 
     } 

     private void Form1_FormClosing(object sender, FormClosingEventArgs e) 
     { 
      dbListenerThread.Abort(); 
      player.playlistCollection.remove(playlist); 
     } 

     private void createPlayList() 
     { 
      playlist = player.playlistCollection.newPlaylist("mpl"); 
      playlist.appendItem(player.newMedia(@"E:\SONGS\teri-meri-promo-Muskurahat.Com.wmv")); 
      playlist.appendItem(player.newMedia(@"E:\MOVZZZ\English\The Kid\THE KID FILM_1_0001.avi")); 
      player.currentPlaylist = playlist; 
     } 

     private void btnPlay_Click(object sender, EventArgs e) 
     { 
      // player.URL = @"E:\MOVZZZ\English\The Kid\THE KID FILM_1_0001.avi"; 
      player.Ctlcontrols.play(); 
     } 

     private void btnStop_Click(object sender, EventArgs e) 
     { 
      player.Ctlcontrols.stop(); 
     } 


    } 

} 

我的目标是与视频播放播放循环声音文件顺序在平行下。

+0

您playSound()方法可以正常工作的唯一方法是当它运行在一个单独的线程。在这种情况下,btnPlay_Click缺少代码,它不能确保此线程与视频同步。如果playSound实际上在UI线程上运行,那么您会遇到各种各样的麻烦,包括UI冻结并变得无响应,从而影响视频播放器。 SoundPlayer原本无法正确检测到声音播放完成。大量的音频库可以做得更好。 – 2013-04-08 11:50:16

+0

@HansPassant感谢线程的想法。我正在检查它,并让你知道它是否有效。你应该回答这个问题。 – 2013-04-09 08:42:40

+0

@HansPassant你好,我分开在不同的线程声音播放。但它不能解决问题。我仍然缺少声音。我编辑了这个问题,并添加了新代码,请检查一下。 – 2013-04-09 08:51:10

回答

2

你不应该为此目的使用SoundPlayer; SoundPlayer是一款轻量级的便利课程,用于在应用程序中播放偶然发生的附带声音。如果音频子系统中正在进行其他操作(如播放视频),它偶尔会跳过声音。这里是a good sample that shows how to use the low-level waveOutOpen API for playing sounds

+0

感谢您的回答。我正在检查它。如果它工作..我让你知道。 – 2013-04-18 06:11:21

+0

我已经从代码项目链接下载了源代码。当我运行它并尝试播放wav文件时,程序崩溃。 – 2013-04-18 07:04:57

+0

它在哪里崩溃,错误是什么? – MusiGenesis 2013-04-18 11:41:18