0

我想在 gui 线程上同步播放 wav 文件,但我对 PlaySync 的调用提前返回(并且过早停止播放)。wav文件是2-3分钟。

这是我的代码的样子:

        //in gui code (event handler)
        //play first audio file
        JE_SP.playSound("example1.wav");

        //do a few other statements
        doSomethingUnrelated();

        //play another audio file
        JE_SP.playSound("example2.wav");

    //library method written by me, called in gui code, but located in another assembly
    public static int playSound(string wavFile, bool synchronous = true,
        bool debug = true, string logFile = "", int loadTimeout = FIVE_MINUTES_IN_MS)
    {
        SoundPlayer sp = new SoundPlayer();
        sp.LoadTimeout = loadTimeout;
        sp.SoundLocation = wavFile;
        sp.Load();

        switch (synchronous)
        {
            case true:
                sp.PlaySync();
                break;
            case false:
                sp.Play();
                break;
        }

        if (debug)
        {
            string writeMe = "JE_SP: \r\n\tSoundLocation = " + sp.SoundLocation
                + "\r\n\t" + "Synchronous = " + synchronous.ToString();
            JE_Log.logMessage(writeMe);
        }

        sp.Dispose();
        sp = null;

        return 0;
    }

我想到的一些事情是加载超时,并在另一个线程上播放音频,然后通过强制 gui 线程等待声音文件的持续时间来手动“冻结”gui。我尝试延长加载超时,但没有任何效果。

我不太确定在不使用不是我/微软的人编写的代码的情况下获得 wav 文件持续时间的最佳方法是什么。我想这是可以计算出来的,因为我知道文件大小,并且所有编码属性(比特率、采样率、采样大小等)在我打算播放的所有文件中都是一致的。有人可以详细说明如何使用此信息计算 wav 文件的持续时间吗?也就是说,如果没有人知道为什么 PlaySync 会提前返回。

编辑:

注意:我前段时间在 VB 6 中遇到了类似的问题,但这是由超时引起的,我不怀疑这里有问题。较短(< 1 分钟)的文件似乎可以正常播放,所以我可能决定手动编辑较长的文件,然后通过多次调用分别播放它们。

附加信息:我注意到同一个文件同时停止。这些文件是使用 Audacity 创建的。PlaySync 是否有可能期望文件的某种编码与我 Audacity 产生的不同?

4

1 回答 1

0

以防万一其他人在同步播放大型 wav 文件时遇到问题,这是我编写的一种方法,它使用 WMP 作为替代方案:

public static int playSoundWMP(string soundFile, bool synchronous = true)
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        wmp.URL = soundFile;
        wmp.controls.play();

        Thread.Yield();

        while (wmp.playState == WMPLib.WMPPlayState.wmppsTransitioning)
        {
            Application.DoEvents();
            Thread.Yield();
        }

        int duration = Convert.ToInt32(wmp.currentMedia.duration * 1000);
        double waitTime = wmp.currentMedia.duration;

        if (synchronous)
        {
            Thread.Sleep(duration);
        }

        long elapsed = sw.ElapsedMilliseconds;
        sw.Stop();
        sw = null;

        return (int) wmp.currentMedia.duration * 1000;
    }

此方法使用 WMP 播放音频文件而不是 SoundPlayer 类,因此它可以更可靠地播放较大的 wav 文件...

于 2011-01-31T20:40:13.593 回答