Qt+mpg123+openal播放MP3流

#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);

}

 

你可能感兴趣的:(open)