zoukankan      html  css  js  c++  java
  • Qt 播放音频文件

    Qt播放音频文件的方法有好多中,简单介绍几种

    不过一下几种方式都需要在Qt工程文件中添加

    QT       += multimedia



    第一

    QMediaPlayer类

    可以播放MP3文件,同时使用也是最简单的了,具体代码

    {
        player = new QMediaPlayer;
        connect(player, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
        player->setMedia(QUrl::fromLocalFile("E:\CloudMusic\林沁简介 - 太阳的后裔 MIX.mp3"));
        player->setVolume(30);
        player->play();
    }


    该中实现方式适合单个文件的,如果有多个文件需要播放,那么需要使用下面的方式

    {
            playlist = new QMediaPlaylist;
            playlist->addMedia(QUrl::fromLocalFile("E:\CloudMusic\林沁简介 - 太阳的后裔 MIX.mp3"));
            playlist->addMedia(QUrl::fromLocalFile("E:\CloudMusic\芭比 - 触电 (完整版).mp3"));
            playlist->addMedia(QUrl::fromLocalFile("E:\CloudMusic\郭芯语 - 快点告诉你.mp3"));
            playlist->setCurrentIndex(1);
    
            player = new QMediaPlayer;
            player->setPlaylist(playlist);
    
            player->play();
        }


    源代码工程:http://download.csdn.net/detail/z609932088/9502687

    第二

    使用QsoundEffect类

    核心代码

        effect.setSource(QUrl::fromLocalFile("E:\CloudMusic\林沁简介 - 太阳的后裔 MIX.wav"));
        effect.setLoopCount(QSoundEffect::Infinite);
        effect.setVolume(1.0f);
        effect.play();


    源代码工程:http://download.csdn.net/detail/z609932088/9502709

    第三种,是播放pcm裸流的

    详见“灿哥哥的博客”

    连接地址:http://blog.csdn.net/caoshangpa/article/details/51224678

    原文连接内容

    这两种方法都需要在.pro文件中加入multimedia模块。方法一是通过QAudioOutput实现的,先用QFile打开PCM文件,然后进行音频参数设置,最后调用QAudioOutput的start函数进行播放;方法二也用到了QAudioOutput,先将PCM文件读取到内存,然后进行音频参数设置,最后从内存中定时读取部分数据,调用QIODevice的write函数将这部分数据写入到扬声器。与方法一相比,方法二虽然麻烦,但是这种方法是进行语音编解码和语音网络传输的基础。

    方法一:

     

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. #include <QApplication>  
    2. #include <QFile>  
    3. #include <QAudioFormat>  
    4. #include <QAudioOutput>  
    5.   
    6. int main(int argc, char *argv[])  
    7. {  
    8.     QApplication a(argc, argv);  
    9.     QFile inputFile;  
    10.     inputFile.setFileName("test.pcm");  
    11.     inputFile.open(QIODevice::ReadOnly);  
    12.   
    13.     //设置采样格式  
    14.     QAudioFormat audioFormat;  
    15.     //设置采样率  
    16.     audioFormat.setSampleRate(44100);  
    17.     //设置通道数  
    18.     audioFormat.setChannelCount(2);  
    19.     //设置采样大小,一般为8位或16位  
    20.     audioFormat.setSampleSize(16);  
    21.     //设置编码方式  
    22.     audioFormat.setCodec("audio/pcm");  
    23.     //设置字节序  
    24.     audioFormat.setByteOrder(QAudioFormat::LittleEndian);  
    25.     //设置样本数据类型  
    26.     audioFormat.setSampleType(QAudioFormat::UnSignedInt);  
    27.   
    28.     QAudioOutput *audio = new QAudioOutput( audioFormat, 0);  
    29.     audio->start(&inputFile);  
    30.     return a.exec();  
    31. }  

    方法二:

     

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. Widget::Widget(QWidget *parent) :  
    2.     QWidget(parent),  
    3.     ui(new Ui::Widget)  
    4. {  
    5.     ui->setupUi(this);  
    6.   
    7.     //获取文件的指针  
    8.     FILE *file=fopen("test.pcm","rb");  
    9.     if(!file)  
    10.     {  
    11.         qDebug()<<"Open Failed";  
    12.         return;  
    13.     }  
    14.     //把指针移动到文件的结尾 ,获取文件长度  
    15.     fseek(file,0,SEEK_END);  
    16.     //获取文件长度  
    17.     fileLength=ftell(file);  
    18.     //定义数组长度  
    19.     fileBuffer=new char[fileLength+1];  
    20.     //把指针移动到文件开头 因为我们一开始把指针移动到结尾,如果不移动回来 会出错  
    21.     rewind(file);  
    22.     //读文件  
    23.     fread(fileBuffer,1,fileLength,file);  
    24.     //把读到的文件最后一位 写为0 要不然系统会一直寻找到0后才结束  
    25.     fileBuffer[fileLength]=0;  
    26.     //关闭文件  
    27.     fclose(file);  
    28.     qDebug()<<fileLength;  
    29.   
    30.     //设置采样格式  
    31.     QAudioFormat audioFormat;  
    32.     //设置采样率  
    33.     audioFormat.setSampleRate(44100);  
    34.     //设置通道数  
    35.     audioFormat.setChannelCount(2);  
    36.     //设置采样大小,一般为8位或16位  
    37.     audioFormat.setSampleSize(16);  
    38.     //设置编码方式  
    39.     audioFormat.setCodec("audio/pcm");  
    40.     //设置字节序  
    41.     audioFormat.setByteOrder(QAudioFormat::LittleEndian);  
    42.     //设置样本数据类型  
    43.     audioFormat.setSampleType(QAudioFormat::UnSignedInt);  
    44.     //音频设备信息  
    45.     QAudioDeviceInfo info = QAudioDeviceInfo::defaultOutputDevice();  
    46.     if (!info.isFormatSupported(audioFormat)) {  
    47.         qDebug()<<"default format not supported try to use nearest";  
    48.         audioFormat = info.nearestFormat(audioFormat);  
    49.     }  
    50.     audioOutput = new QAudioOutput(audioFormat, this);  
    51.     streamOut = audioOutput->start();  
    52.     //定时器  
    53.     timer=new QTimer(this);  
    54.     connect(timer, SIGNAL(timeout()), SLOT(slotTimeout()));    
    55. }  
    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. void Widget::slotTimeout()  
    2. {  
    3.     static int i=0;  
    4.     if(i<fileLength/1764)  
    5.     {  
    6.         tempBuffer.append(fileBuffer+i*1764,1764);  
    7.   
    8.         if(audioOutput&&audioOutput->state()!=QAudio::StoppedState&&  
    9.                 audioOutput->state()!=QAudio::SuspendedState)  
    10.         {  
    11.             int chunks = audioOutput->bytesFree()/audioOutput->periodSize();  
    12.             while (chunks)  
    13.             {  
    14.                 if (tempBuffer.length() >= audioOutput->periodSize())  
    15.                 {  
    16.                     //写入到扬声器  
    17.                     streamOut->write(tempBuffer.data(),audioOutput->periodSize());  
    18.                     tempBuffer = tempBuffer.mid(audioOutput->periodSize());  
    19.                 }  
    20.                 else  
    21.                 {  
    22.                     //写入到扬声器  
    23.                     streamOut->write(tempBuffer);  
    24.                     tempBuffer.clear();  
    25.                     break;  
    26.                 }  
    27.                 --chunks;  
    28.             }  
    29.         }  
    30.     }  
    31.     i++;  
    32. }  

    PCM裸流1秒的数据量是44100×16×2/8=176400字节,那么10毫秒的数据量就是1764字节,所以定时器定时10毫秒,每隔10毫秒从数组中顺序读取1746个字节。

    PCM音频文件的制作参考:http://blog.csdn.net/caoshangpa/article/details/51218994

    音频参数解析参考:http://blog.csdn.net/caoshangpa/article/details/51218597

    测试用PCM音频文件下载链接:http://download.csdn.net/detail/caoshangpa/9497751

    方法二源码:见http://blog.csdn.net/caoshangpa/article/details/51224678的评论

  • 相关阅读:
    怎样从外网访问内网MongoDB数据库?
    怎样从外网访问内网MySQL数据库?
    怎样从外网访问内网Tomcat?
    怎样从外网访问内网Oracle数据库?
    怎样从外网访问内网WampServer?
    怎样从外网访问内网Jupyter Notebook?
    怎样从外网访问内网RESTful API?
    怎样从外网访问内网WebSphere?
    系统性能测试步骤
    性能相关面试题
  • 原文地址:https://www.cnblogs.com/DreamDog/p/9160136.html
Copyright © 2011-2022 走看看