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




