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