ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CodeGo.net>如何播放声音异步,但自己在队列中?

2019-11-22 02:08:29  阅读:99  来源: 互联网

标签:asynchronous audio c net


我只想互相播放4个声音(sounds1> sound2> sound3),但又不想在每次播放过程中停止代码流或不等待每个声音结束.

我到处都在搜索此内容,但是我阅读的每个方向都陷入了其他问题.

到目前为止,我最好的选择是:使用System.Media上已经使用过的SoundPlayer并设置自己的队列功能,但是Soundplayer没有“完成播放”事件,因此我不知道何时开始播放下一个声音. (真的,微软吗?)

其他解决方案和问题:
DirectSound在.NET(c#)中工作似乎很复杂.
Win Playsound并没有真正的帮助,因为它也不能排队.

解决方法:

您可以尝试在UI外部的线程上使用PlaySync,例如:正如某些人评论的那样,是后台线程.

这是对线程使用线程安全* BlockingCollection的示例(未经测试)
   *您可以在线程内外使用

您可能需要制作自己的类或方法,以便在每次声音结束时触发一个事件.或者,您可以只在线程中循环队列,因为PlaySync只会自己等待.

using System.Threading;
using System.Collections.Concurrent;
namespace PlaySound
{
    public partial class Form1 : Form
    {
        private Thread soundPlayThread;
        private BlockingCollection<string> speakQueue = new BlockingCollection<string>();
        private CancellationTokenSource cancelSoundPlay;
        private int soundPlayCount = 0;

        public Form1()
        {
            InitializeComponent();
            cancelSoundPlay = new CancellationTokenSource();
        }

        private void btnStartSoundPlay_Click(object sender, EventArgs e)
        {
            StartSoundPlay();
        }

        private void btnStopSoundPlay_Click(object sender, EventArgs e)
        {
            cancelSoundPlay.Cancel();
            Console.WriteLine("Sound play cancelled.");
        }

        private void btnAddToQueue_Click(object sender, EventArgs e)
        {
            speakQueue.Add("MyFile.wav");
        }

        private void queueAndPlay(string loc)
        {
            if (!File.Exists(loc=loc+".wav"))
                loc=configPath+"soundnotfound.wav";
            speakQueue.Add(loc);
            StartSoundPlay();
        }


        private void StartSoundPlay()
        {
            //Sound Player Loop Thread
            if (this.soundPlayThread == null || !this.soundPlayThread.IsAlive)
            {
                this.soundPlayThread = new Thread(SoundPlayerLoop);
                this.soundPlayThread.Name = "SoundPlayerLoop";
                this.soundPlayThread.IsBackground = true;
                this.soundPlayThread.Start();
                Console.WriteLine("Sound play started");
            }
        }
        //Method that the outside thread will use outside the thread of this class
        private void SoundPlayerLoop()
        {
            var sound = new SoundPlayer();
            foreach (String soundToPlay in this.speakQueue.GetConsumingEnumerable(cancelSoundPlay.Token))
            {
                //http://msdn.microsoft.com/en-us/library/system.media.soundplayer.playsync.aspx
                speaker.SoundLocation=soundToPlay;
                //Here the outside thread waits for the following play to end before continuing.
                sound.PlaySync();
                soundPlayCount++;
                Console.WriteLine("Sound play end. Count: " + soundPlayCount);
            }
        }
    }
}

标签:asynchronous,audio,c,net
来源: https://codeday.me/bug/20191122/2056401.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有