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