• 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);
    }
  • 相关阅读:
    less @import and extend及mixin详解
    Less的guards and argument matching
    LESS嵌套中的Mixins和classes
    bootstrap colorscheme以及theme自动生成
    C# Winform 获得下拉框 选中的值
    C# 后台按键 视频播放器 全屏后无法 触发
    C# 调用win32API 获取进程句柄 有毛用???
    C# 键盘钩子
    C# SqlParameter 使用
    C# 获得星期几
  • 原文地址:https://www.cnblogs.com/rophie/p/3182045.html
Copyright © 2020-2023  润新知