zoukankan      html  css  js  c++  java
  • 10.QT-QAudioOutput类使用

    本章需要用到的类如下:

    • QAudioDeviceInfo类提供音频输出设备
    • QAudioFormat类提供音频参数设置
    • QAudioOutput类提供了用于将PCM原始音频数据发送到音频输出设备的接口。
     
    1.QAudioDeviceInfo类
    用来提供音频输出设备,并且包含该设备支持的格式,排序,通道,编码器,频率,采样率等, 用户可以通过bool isFormatSupported(const QAudioFormat &settings) 来判断是否支持该格式.用户一般通过defaultOutputDevice()来获取当前默认播放设备.
    如果想获取所有音频输出设备可以通过availableDevices()成员函数,比如:
    foreach(const QAudioDeviceInfo &deviceInfo, QAudioDeviceInfo::availableDevices(QAudio::AudioOutput))
    {
         qDebug() << "Device name: " << deviceInfo.deviceName();
    }    

    2.QAudioOutput类

    常用函数如下所示:
    QAudio::Error QAudioOutput::error(); //获取当前错误信息
    void QAudioOutput::suspend(); //暂停
    void QAudioOutput::resume(); //恢复
    void QAudioOutput::start(QIODevice *device) //启动播放,参数是QIODevice(需要通过write成员写入pcm数据数组)
    QIODevice *QAudioOutput::start(); //打开设备并返回一个指向内部QIODevice的指针,通过write()便可以直接向其写入pcm数据进行播放. QAudio::State QAudioOutput::state(); //获取当前QAudioOutput状态,状态如下所示: //QAudio::ActiveState:正在播放中 //QAudio::SuspendedState:正在暂停中 //QAudio::StoppedState:已被停止,可能是被异常终止了 //QAudio::IdleState:处于空闲中,什么都没干

    void QAudioOutput::setVolume(qreal volume); //设置音量 (0.0~1.0之间,默认音量为1.0)
    void QAudioOutput::setBufferSize(int value); //重新设置缓冲区大小,需要在start()之前设置
    int QAudioOutput::bufferSize() const//获取缓冲区大小,默认为35280,需要start()后,才分配buff
    int QAudioOutput::bytesFree() //返回音频缓冲区中可用的空闲字节数。 //注意:返回值仅在QAudio::ActiveState或QAudio::IdleState状态下有效,否则返回零。

    int QAudioOutput::periodSize(); //周期大小(以字节为单位),每播放一次音频数据所需多少个数据量
                        //periodSize用来防止缓冲区欠运行和确保不间断回放所需的数据量
    3.初始化QAudioOutput
    开始播放音频流只需使用QIODevice调用start()即可。然后QAudioOutput将从io设备中获取所需的数据。所以播放音频文件是简单的如下:
    QFile sourceFile;  
    QAudioOutput* audio; 
    sourceFile.setFileName("/tmp/test.raw");
    sourceFile.open(QIODevice::ReadOnly);
     
    QAudioFormat format;
    // Set up the format, eg.
    format.setSampleRate(44100); //设置采样率
    format.setChannelCount(1); //设置通道数
    format.setSampleSize(16); //样本数据16位
    format.setCodec("audio/pcm"); //播出格式为pcm格式
    format.setByteOrder(QAudioFormat::LittleEndian); //默认小端模式
    format.setSampleType(QAudioFormat::UnSignedInt); //无符号整形数
     
    QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice()); //选择默认输出设备
     
    if (!info.isFormatSupported(format))
    {
    qDebug()<<"输出设备不支持该格式,不能播放音频";
    return;
    }
     
    audio = new QAudioOutput(format, this);
    connect(audio, SIGNAL(stateChanged(QAudio::State)),this,SLOT(handleStateChanged(QAudio::State)));
     
    audio->start(&sourceFile);
    }

    文件在播放过程中, 当遇到错误时,状态更改为QAudio::StoppedState,并发送stateChanged()信号函数,这时可以通过error()函数获取错误信息,注意:文件播放结束(QAudio::IdleState)后,需要停止设备:

    void AudioOutputExample::handleStateChanged(QAudio::State newState)
    {
        switch (newState) {
            case QAudio::IdleState:
                // 数据已经没有了,播放完毕
                audio->stop();
                sourceFile.close();
                delete audio;
                break;
             
            case QAudio::StoppedState:
                    // 音频设备已关闭,检查error是否异常关闭
                    if (audio->error() != QAudio::NoError) {
                    // Error handling
                    }
                    break;
             
            case QAudio::SuspendedState:
                // 音频被暂停
                break;
                
                
            case QAudio::ActiveState:
                // 启动音频播放,正在解析中
                break;
        }
    }

    4.补充说明

    由于QAudioOutput支持的输入数据必须是原始数据,所以播放mp3,WAV,AAC等格式文件,需要解封装后才能支持播放.

    而在QT中,提供了QMediaPlayer类可以支持解封装,但是该类的解码协议都是基于平台的,如果平台自身无法播放,那么QMediaPlayer也无法播放.有兴趣的朋友可以去试试.

    所以接下来,我们使用ffmpeg+QAudioOutput来实现一个简单的音频播放器

    未完待续,下章学习:11.QT-ffmpeg+QAudioOutput实现音频播放器

  • 相关阅读:
    归类常用控件GroupBox、TabControl、Expander
    ScrollViewer控件
    捕获鼠标位置
    5、标记拓展
    如何实现文件增量同步——算法
    常用的 Nand Flash 指令如下:
    Consistent Hashing算法
    循环冗余检验 (CRC) 算法原理
    yaffs2根文件系统的构建过程
    linux内存管理之uboot第一步
  • 原文地址:https://www.cnblogs.com/lifexy/p/13648303.html
Copyright © 2011-2022 走看看