audiocscore

CSCore - Play audio from a FileStream or MemoryStream


Using CSCore, how can I play WMA or MP3 from a FileStream or MemoryStream (unlike using a method that take a string for a file path or url).


Solution

  • As the GetCodec(Stream stream, object key)-overload of the CodecFactory-class is internal, you could simply perform the same steps manually and directly choose your decoder. Acutally, CodeFactory is just a helper class for determining the decoders automatically, so if you already know about your codec, you can do this yourself. Internally, when passing a file path, CSCore checks the file extension and then opens up a FileStream (using File.OpenRead) that is handled over to the chosen decoder.

    All you need to do, is using the specific decoder for your codec.

    For MP3, you could use the DmoMP3Decoder which inherits from DmoStream that implements the IWaveSource-interface you need to handle over as sound source.

    Here is an adjusted sample from the docs on Codeplex:

    public void PlayASound(Stream stream)
    {
        //Contains the sound to play
        using (IWaveSource soundSource = GetSoundSource(stream))
        {
            //SoundOut implementation which plays the sound
            using (ISoundOut soundOut = GetSoundOut())
            {
                //Tell the SoundOut which sound it has to play
                soundOut.Initialize(soundSource);
                //Play the sound
                soundOut.Play();
    
                Thread.Sleep(2000);
    
                //Stop the playback
                soundOut.Stop();
            }
        }
    }
    
    private ISoundOut GetSoundOut()
    {
        if (WasapiOut.IsSupportedOnCurrentPlatform)
            return new WasapiOut();
        else
            return new DirectSoundOut();
    }
    
    private IWaveSource GetSoundSource(Stream stream)
    {
        // Instead of using the CodecFactory as helper, you specify the decoder directly:
        return new DmoMp3Decoder(stream);
    
    }

    For WMA, you can use the WmaDecoder. You should check the implementation of the different decoders: https://github.com/filoe/cscore/blob/master/CSCore/Codecs/CodecFactory.cs#L30

    Make sure, that no exceptions are thrown and handle them with the usage of another decoder (Mp3MediafoundationDecoder) as in the linked source code. Also don't forget to dispose your stream in the end.