Qt+mpg123+openal播放MP3流

    添加时间:2013-7-10 点击量:

    #ifndef PLAYSTREAM_H
    
    #define PLAYSTREAM_H

    #include
    <QObject>
    #include
    ../libMPG123/mpg123.h
    #include
    ../openal/include/al.h
    #include
    ../openal/include/alc.h
    #pragma comment (lib, ../openal/lib/OpenAL32.lib)
    #pragma comment (lib, ../libMPG123/libmpg123.lib)

    class PlayStream : public QObject
    {
    Q_OBJECT

    public:
    PlayStream(QObject
    parent);
    ~PlayStream();
    public:
    //打开流
    void OpenStream();
    //播放及时流,需先调用OpenStream()
    void Play(QByteArray datas);
    //停止播放
    void Stop();
    //暂停播放
    void Pasue();
    private:
    void init();
    bool updataQueueBuffer();
    void mpgClose();

    private:
    mpg123_handle
    mh ;
    ALCdevice
    pDevice;
    ALCcontext
    pContext;
    ALuint outSourceID;
    long lRate;
    };

    #endif // PLAYSTREAM_H



    #include StdAfx.h
    
    #include
    PlayStream.h

    PlayStream::PlayStream(QObject
    parent)
    : QObject(parent)
    {
    init();
    }

    PlayStream::
    ~PlayStream()
    {
    mpgClose();
    alcCloseDevice(pDevice);
    alcDestroyContext(pContext);
    }

    void PlayStream::init()
    {
    int err;
    mpg123_init();
    mh
    = mpg123_new(NULL,&err);
    pDevice
    =alcOpenDevice(NULL);
    if (pDevice)
    {
    pContext
    =alcCreateContext(pDevice,NULL);
    alcMakeContextCurrent(pContext);
    }
    alGenSources(
    1, &outSourceID);
    alSourcei(outSourceID, AL_LOOPING, AL_FALSE);
    alSourcef(outSourceID, AL_SOURCE_TYPE, AL_STREAMING);
    }

    void PlayStream::Play(QByteArray datas)
    {
    updataQueueBuffer();
    ALuint bufferID
    = 0;
    alGenBuffers(
    1, &bufferID);
    size_t done
    =0;
    size_t bufferSize
    =1638400;
    void buffer=malloc(bufferSize);
    ALuint ulFormat
    = alGetEnumValue(AL_FORMAT_STEREO16);
    mpg123_decode(mh,(
    const unsigned char)datas.constData(),datas.size(),(unsigned char )buffer,bufferSize,&done);
    if (done)
    {
    alBufferData(bufferID, ulFormat, buffer,done,
    44100);
    alSourceQueueBuffers(outSourceID,
    1, &bufferID);
    }
    ALint values;
    alGetSourcei(outSourceID,AL_SOURCE_STATE,
    &values);
    if (values != AL_PLAYING)
    {
    alSourcePlay(outSourceID);
    }
    alDeleteBuffers(
    1, &bufferID);
    free(buffer);
    buffer
    =NULL;
    }

    bool PlayStream::updataQueueBuffer()
    {
    ALint stateVaue;
    int processed, queued;
    alGetSourcei(outSourceID, AL_SOURCE_STATE,
    &stateVaue);
    if (stateVaue == AL_STOPPED)
    {
    return false;
    }
    alGetSourcei(outSourceID, AL_BUFFERS_PROCESSED,
    &processed);
    alGetSourcei(outSourceID, AL_BUFFERS_QUEUED,
    &queued);
    while(processed--
    {
    ALuint buff;
    alSourceUnqueueBuffers(outSourceID,
    1, &buff);
    alDeleteBuffers(
    1, &buff);
    }
    return true;
    }

    void PlayStream::mpgClose()
    {
    alSourceStop(outSourceID);
    alSourcei(outSourceID, AL_BUFFER,
    0);
    int err=mpg123_close(mh);
    }

    void PlayStream::OpenStream()
    {
    int err=mpg123_open_feed(mh);
    }

    void PlayStream::Stop()
    {
    mpgClose();
    alcCloseDevice(pDevice);
    alcDestroyContext(pContext);
    }

    void PlayStream::Pasue()
    {
    alSourcePause(outSourceID);
    }


    文艺不是炫耀,不是花哨空洞的文字堆砌,不是一张又一张的逆光照片,不是将旅行的意义转化为名牌包和明信片的物质展示;很多时候它甚至完全不美——它嘶吼、扭曲,它会痛苦地抽搐,它常常无言地沉默。——艾小柯《文艺是一种信仰》
    分享到: