winforms - 使用 System.Media.SoundPlayer.PlaySync() 和 AxWindowsMediaPlayer 并行播放声音

标签 winforms c#-4.0

我创建了一个 WinForm 应用程序,其中包含一个 AxWMPLib.AxMediaPlayer,我在其中播放一些视频。我还必须在不同的线程中播放一些其他自定义声音。为此,我使用了 System.Media.SoundPlayer.PlaySync()。该线程循环播放几个声音文件。问题是当我暂停/停止视频时,按钮事件声音播放正常。但视频运行时,有时会跳过一些声音文件。而且它是随机发生的。 谁能解释一下这个问题以及如何解决它。我的意思是我怎样才能并行播放声音和视频。

视频在 UI 线程中播放,其他声音在不同线程中播放。请查看以下代码:

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


    }

}

我的目标是顺序播放循环的声音文件,同时并行播放视频。

最佳答案

您不应将 SoundPlayer 用于此目的; SoundPlayer 是一个轻量级、方便的类,用于在应用程序中偶尔播放偶然的声音。如果音频子系统中发生其他事情(例如播放视频),它偶尔会跳过声音。这是a good sample that shows how to use the low-level waveOutOpen API for playing sounds .

关于winforms - 使用 System.Media.SoundPlayer.PlaySync() 和 AxWindowsMediaPlayer 并行播放声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15876760/

相关文章:

c# - 使用动态类型

c# - Checkedlistbox 多列

.net - 如何更改 MonthCalendar 控件中某些日期的颜色?

c# - 为 Windows 窗体实现 TypeConverter

c# - 第二个窗体首先加载,主窗体在第一个窗体关闭之前不可见

c# - 如何从 list<string> 中获取第一个和最后一个值?

c#-4.0 - Entity Framework 4.1 修改每个开发人员单元测试环境的连接字符串