Ubuntu18.0.4 QAudioOutput 热插拔导致主界面卡死之解决方案

71 篇文章 4 订阅

QAudioOutput 对象放在主线程中,正在播放的时候,拔出播放器就会导致界面卡死。

一、QAudioOutput卡死的几种情形:

    1.未插入耳机,启动客户端后再插入耳机,客户端卡死

    2.正常播放声音(声音未播放完),热插拔导致界面卡死

    3.在第2点基础上,再插入界面卡死

    4.多线程情况下,不能播放声音,界面不卡死

 

二、解决方法:

使用sdl Mixer,支持多线程下热插拔播放

 

三、代码

#include <QCoreApplication>

#include "SDL2/SDL.h"
#include "SDL2/SDL_mixer.h"
#include <thread>
#include <pthread.h>

void Play()
{
    SDL_Init(SDL_INIT_EVERYTHING);

    /*
    对于那些使用OGG, MOD或者其他非WAV声音格式的人,请使用Mix_Init()来初始化解码器,并使用Mix_Quit()来关闭解码器。因为这里我们仅仅使用了WAV文件,所以我们不必为了用不到的东西来添加更多代码。
    flags:bitwise OR'd set of sample/music formats to support by loading a library now. The values you may OR together to pass in are:
            MIX_INIT_FLAC
            MIX_INIT_MOD
            MIX_INIT_MP3
            MIX_INIT_OGG
    */
    Mix_Init(MIX_INIT_OGG);

    /*
    该函数的第一个参数是我们使用的声音频率,在本课中,它被设为22050,这也是推荐设置的值。第二个参数是声音格式,我们使用了默认的格式。第三个参数是我们计划使用的频道数量。
    我们将它设为2来获得立体声,如果设为1,将只有单声道声音。最后一个参数是样本大小,这里被设为4096。
    frequency:Output sampling frequency in samples per second(Hz). you might use MIX_DEFAULT_FREQUENCY(22050) since that is a good value for most games.
    format:Output sample format.
            AUDIO_U8:	Unsigned 8 - bit samples
            AUDIO_S8:Signed 8 - bit samples
            AUDIO_U16LSB:Unsigned 16 - bit samples, in little - endian byte order
            AUDIO_S16LSB:Signed 16 - bit samples, in little - endian byte order
            AUDIO_U16MSB:Unsigned 16 - bit samples, in big - endian byte order
            AUDIO_S16MSB:Signed 16 - bit samples, in big - endian byte order
            AUDIO_U16:same as AUDIO_U16LSB(for backwards compatability probably)
            AUDIO_S16:same as AUDIO_S16LSB(for backwards compatability probably)
            AUDIO_U16SYS:Unsigned 16 - bit samples, in system byte order
            AUDIO_S16SYS;Signed 16 - bit samples, in system byte order
            MIX_DEFAULT_FORMAT is the same as AUDIO_S16SYS.
    channels:Number of sound channels in output.Set to 2 for stereo, 1 for mono.This has nothing to do with mixing channels.
    */
    Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096);//在初始化函数中,我们调用Mix_OpenAudio() 来初始化SDL_mixer中的声音函数。

    //要加载音乐,我们使用Mix_LoadMUS()。这个函数接受一个音乐文件的文件名并返回其中的音乐数据。如果出错,它会返回NULL。
    //要加载声效,我们使用Mix_LoadWAV()。它加载了传入的文件名所对应的声音文件,并返回了一个Mix_Chunk,如果出错了,则返回NULL。
    Mix_Music *music = Mix_LoadMUS("/opt/code/test/alarm_audio.wav");

    //函数Mix_PlayMusic()的第一个参数是我们将要播放的音乐。第二个参数是音乐将要循环的次数。由于它被设为了-1,音乐将在手动停止前不停地循环下去。
    //如果播放音乐出现问题,该函数会返回 - 1。

    int i = 0;
    while(i++ < 5){
        Mix_PlayMusic(music, 1);

        SDL_Delay(5000);//不延迟不会播放
    }


    Mix_CloseAudio();
    Mix_FreeMusic(music);
    Mix_Quit();
    SDL_Quit();
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    std::thread thread(Play);
    thread.join();
    return a.exec();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值