Можно ли воспроизводить 2 звука подряд с помощью SoundPlayer?

1

Я ищу способ воспроизвести многократный звук назад к спине асинхронно.

У меня есть:

jouerSon("_" + nbre1);
jouerSon(operateur);
jouerSon("_" + nbre2);
jouerSon("equal");

public void jouerSon(String son)
{
    System.Media.SoundPlayer player = new SoundPlayer();
    player.Stream = Properties.Resources.ResourceManager.GetStream(son);
    // player.LoadAsync();
    player.Play();
    //Thread.Sleep(500);
    //player.Stop();
 }

Я хотел бы воспроизвести первый звук, затем, когда он будет поверх второго и т.д., Пока программа по-прежнему реагирует.

Мне удалось воспроизвести каждый звук один за другим, но только с использованием синхронного воспроизведения, которое не позволяет пользователю ничего делать, пока не будет воспроизведен весь звук.

И если я попытаюсь использовать с асинхронным воспроизведением, вместо каждого будет воспроизводиться только последний звук.

Я искал решение, но, похоже, не нашел. Может кто-нибудь мне помочь?

  • 0
    Смотрите это tophic: stackoverflow.com/questions/1285294/…
  • 0
    Вы должны быть в состоянии сделать это с Windows Media Player, который немного более программируемый, чем SoundPlayer. У него есть событие PlayStateChange, для которого вы можете создать обработчик события, а затем вы можете проверить WMPPlayState.wmppsStopped и, если это так, запустить второй звук. msdn.microsoft.com/en-us/library/windows/desktop/… Если это предложение представляет интерес, я могу опубликовать пример кода, дайте мне знать.
Показать ещё 7 комментариев
Теги:
visual-studio
soundplayer

2 ответа

0
Лучший ответ

Играйте в другую тему:

    private void button1_Click(object sender, EventArgs e)
    {
        // ...
        jouerSon(new String[] { "_" + nbre1, operateur, "_" + nbre2, "equal" });
        // ...
    }

    public void jouerSon(String[] sons)
    {
        Task t = new Task(() =>
        {
            System.Media.SoundPlayer player = new System.Media.SoundPlayer();
            foreach (String son in sons)
            {
                player.Stream = Properties.Resources.ResourceManager.GetStream(son);
                player.PlaySync();
            }    
        });
        t.Start();
    }

Или, возможно, что-то более конкретно скроенное, например:

    private void button1_Click(object sender, EventArgs e)
    {
        // ...
        jouerSon(nbre1, operateur, nbre2);
        // ...
    }

    public void jouerSon(string nbre1, string operateur, string nbre2)
    {
        Task t = new Task(() =>
        {
            System.Media.SoundPlayer player = new System.Media.SoundPlayer();
            player.Stream = Properties.Resources.ResourceManager.GetStream("_" + nbre1);
            player.PlaySync();
            player.Stream = Properties.Resources.ResourceManager.GetStream(operateur);
            player.PlaySync();
            player.Stream = Properties.Resources.ResourceManager.GetStream("_" + nbre2);
            player.PlaySync();
            player.Stream = Properties.Resources.ResourceManager.GetStream("equal");
            player.PlaySync();
        });
        t.Start();
    }
  • 0
    Работал отлично, спасибо!
0

Хорошо, как и было обещано, вот пример кода для использования проигрывателя Windows Media. Но теперь, когда я смотрю на это, я вижу, что это немного сложнее, чем я думал - может быть, слишком сложно?

Эта программа может использоваться для воспроизведения звукового файла 1 раз или 2 раза или n раз или неопределенного количества раз, пока вызывающая программа не вызовет метод StopPlayer(). Это должно быть довольно легко изменить, чтобы воспроизвести первый звуковой файл, а затем еще один.

using WMPLib;

using System;


namespace Merlinia.CommonClasses
{
   /// <summary>
   /// This class provides a very simple wrapper layer for the Microsoft Windows Media Player.
   /// 
   /// Remember to call Dispose() when the player is no longer needed. (Actually, this may not be 
   /// necessary.)
   /// </summary>
   public class MMediaPlayer : IDisposable
   {
      #region Private variables

      // Reference to an Interop object for the COM object that interfaces with Microsoft Windows 
      //  Media Player
      private readonly WindowsMediaPlayer _windowsMediaPlayer = null;

      // Number of repeats left, negative = keep looping
      private int _repeatCount = -1;

      // Part of the IDisposable pattern
      private bool _isDisposed = false;

      #endregion Private variables


      #region Constructor

      /// <summary>
      /// Constructor.
      /// </summary>
      public MMediaPlayer()
      {
         try
         {
            // Instantiate the Windows Media Player Interop object 
            _windowsMediaPlayer = new WindowsMediaPlayer();

            // Hook up a couple of event handlers
            _windowsMediaPlayer.MediaError += WindowsMediaPlayer_MediaError;
            _windowsMediaPlayer.PlayStateChange += WindowsMediaPlayer_PlayStateChange;
         }
         catch (Exception e)
         {
            _cLog.Error(0x3ad3a52u, e);
         }
      }

      #endregion Constructor


      #region Public methods

      /// <summary>
      /// Method to start the media player playing a file.
      /// </summary>
      /// <param name="fileName">complete file name</param>
      /// <param name="repeatCount">zero = repeat indefinitely, else number of times to repeat</param>
      public void PlayMediaFile(string fileName, int repeatCount)
      {
         if (_windowsMediaPlayer == null)
            return;

         _repeatCount = --repeatCount;  // Zero -> -1, 1 -> zero, etc.

         if (_windowsMediaPlayer.playState == WMPPlayState.wmppsPlaying)
            _windowsMediaPlayer.controls.stop();  // Probably unnecessary

         _windowsMediaPlayer.URL = fileName;
         _windowsMediaPlayer.controls.play();
      }


      /// <summary>
      /// Method to stop the media player.
      /// </summary>
      public void StopPlayer()
      {
         if (_windowsMediaPlayer == null)
            return;

         _repeatCount = 0;
         _windowsMediaPlayer.controls.stop();
      }

      #endregion Public methods


      #region Private methods

      /// <summary>
      /// Event-handler method called by Windows Media Player when the media file can't be opened, 
      /// or some other error. This is logged, but otherwise ignored - the calling module is not 
      /// signaled in any way.
      /// </summary>
      private static void WindowsMediaPlayer_MediaError(object pMediaObject)
      {
         _cLog.Error(0x3ad1d3bu);
      }


      /// <summary>
      /// Event-handler method called by Windows Media Player when the "state" of the media player 
      /// changes. This is used to repeat the playing of the media for the specified number of 
      /// times, or maybe for an indeterminate number of times.
      /// </summary>
      private void WindowsMediaPlayer_PlayStateChange(int newState)
      {
         if ((WMPPlayState)newState == WMPPlayState.wmppsStopped)
         {
            if (_repeatCount != 0)
            {
               _repeatCount--;
               _windowsMediaPlayer.controls.play();
            }
         }
      }

      #endregion Private methods


      #region IDisposable stuff

      // This copied from here: http://msdn.microsoft.com/en-us/library/system.idisposable.aspx

      /// <summary>
      /// Method to implement IDisposable. Do not make this method virtual - a derived class should 
      /// not be able to override this method.
      /// </summary>
      public void Dispose()
      {
         // Call the following method
         Dispose(true);

         // This object will be cleaned up by the Dispose() method below. Therefore, we call 
         //  GC.SuppressFinalize to take this object off the finalization queue and prevent 
         //  finalization code for this object from executing a second time.
         GC.SuppressFinalize(this);
      }


      /// <summary>
      /// Dispose(bool disposing) executes in two distinct scenarios. If isDisposing equals true, 
      /// the method has been called directly or indirectly by a user code. Managed and unmanaged 
      /// resources can be disposed. If isDisposing equals false, the method has been called by the 
      /// runtime from inside the finalizer and you should not reference other objects - only 
      /// unmanaged resources can be disposed.
      /// </summary>
      protected virtual void Dispose(bool isDisposing)
      {
         // Check to see if Dispose() has already been called
         if (!_isDisposed)
         {
            // If isDisposing equals true, dispose all managed and unmanaged resources
            if (isDisposing && _windowsMediaPlayer != null)
            {
               // Close the media player. (This may not be necessary?)
               _windowsMediaPlayer.close();
            }

            // Note disposing has been done
            _isDisposed = true;
         }
      }

      #endregion IDisposable stuff

   }
}

Игнорируйте утверждения, связанные с протоколированием.

Но для этого вам понадобится DLL Interop для COM-объекта, который взаимодействует с Windows Media Player. Это, к сожалению, немного сложно, если вы никогда этого не делали раньше. Visual Studio может генерировать DLL Interop. В качестве альтернативы вы можете попытаться найти его в Интернете. Это то, что я сделал на самом деле, мне довелось найти его здесь: http://grouplab.cpsc.ucalgary.ca/cookbook/index.php/VisualStudio/HowToUseWindowsMediaPlayerToPlayAudioAndVideo

Удачи, и вы можете спросить, пытаетесь ли вы сделать это и столкнетесь с проблемами.

  • 0
    Пока не удалось заставить мою программу работать с этим, но я постараюсь изо всех сил, чтобы хотя бы понять в будущем. Спасибо за ваше время

Ещё вопросы

Сообщество Overcoder
Наверх
Меню