您的位置:首页 > 编程语言 > Qt开发

Qt 播放音频文件

2017-03-10 10:37 330 查看
Qt播放音频文件的方法有好多中,简单介绍几种

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

[cpp] view
plain copy

 





QT       += multimedia  

第一

QMediaPlayer类

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

[cpp] view
plain copy

 





{  

    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();  

}  

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

[cpp] view
plain copy

 





{  

        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类

核心代码

[cpp] view
plain copy

 





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

 

 





#include <QApplication>  

#include <QFile>  

#include <QAudioFormat>  

#include <QAudioOutput>  

  

int main(int argc, char *argv[])  

{  

    QApplication a(argc, argv);  

    QFile inputFile;  

    inputFile.setFileName("test.pcm");  

    inputFile.open(QIODevice::ReadOnly);  

  

    //设置采样格式  

    QAudioFormat audioFormat;  

    //设置采样率  

    audioFormat.setSampleRate(44100);  

    //设置通道数  

    audioFormat.setChannelCount(2);  

    //设置采样大小,一般为8位或16位  

    audioFormat.setSampleSize(16);  

    //设置编码方式  

    audioFormat.setCodec("audio/pcm");  

    //设置字节序  

    audioFormat.setByteOrder(QAudioFormat::LittleEndian);  

    //设置样本数据类型  

    audioFormat.setSampleType(QAudioFormat::UnSignedInt);  

  

    QAudioOutput *audio = new QAudioOutput( audioFormat, 0);  

    audio->start(&inputFile);  

    return a.exec();  

}  

方法二:

[cpp] view
plain copy

 

 





Widget::Widget(QWidget *parent) :  

    QWidget(parent),  

    ui(new Ui::Widget)  

{  

    ui->setupUi(this);  

  

    //获取文件的指针  

    FILE *file=fopen("test.pcm","rb");  

    if(!file)  

    {  

        qDebug()<<"Open Failed";  

        return;  

    }  

    //把指针移动到文件的结尾 ,获取文件长度  

    fseek(file,0,SEEK_END);  

    //获取文件长度  

    fileLength=ftell(file);  

    //定义数组长度  

    fileBuffer=new char[fileLength+1];  

    //把指针移动到文件开头 因为我们一开始把指针移动到结尾,如果不移动回来 会出错  

    rewind(file);  

    //读文件  

    fread(fileBuffer,1,fileLength,file);  

    //把读到的文件最后一位 写为0 要不然系统会一直寻找到0后才结束  

    fileBuffer[fileLength]=0;  

    //关闭文件  

    fclose(file);  

    qDebug()<<fileLength;  

  

    //设置采样格式  

    QAudioFormat audioFormat;  

    //设置采样率  

    audioFormat.setSampleRate(44100);  

    //设置通道数  

    audioFormat.setChannelCount(2);  

    //设置采样大小,一般为8位或16位  

    audioFormat.setSampleSize(16);  

    //设置编码方式  

    audioFormat.setCodec("audio/pcm");  

    //设置字节序  

    audioFormat.setByteOrder(QAudioFormat::LittleEndian);  

    //设置样本数据类型  

    audioFormat.setSampleType(QAudioFormat::UnSignedInt);  

    //音频设备信息  

    QAudioDeviceInfo info = QAudioDeviceInfo::defaultOutputDevice();  

    if (!info.isFormatSupported(audioFormat)) {  

        qDebug()<<"default format not supported try to use nearest";  

        audioFormat = info.nearestFormat(audioFormat);  

    }  

    audioOutput = new QAudioOutput(audioFormat, this);  

    streamOut = audioOutput->start();  

    //定时器  

    timer=new QTimer(this);  

    connect(timer, SIGNAL(timeout()), SLOT(slotTimeout()));    

}  

[cpp] view
plain copy

 

 





void Widget::slotTimeout()  

{  

    static int i=0;  

    if(i<fileLength/1764)  

    {  

        tempBuffer.append(fileBuffer+i*1764,1764);  

  

        if(audioOutput&&audioOutput->state()!=QAudio::StoppedState&&  

                audioOutput->state()!=QAudio::SuspendedState)  

        {  

            int chunks = audioOutput->bytesFree()/audioOutput->periodSize();  

            while (chunks)  

            {  

                if (tempBuffer.length() >= audioOutput->periodSize())  

                {  

                    //写入到扬声器  

                    streamOut->write(tempBuffer.data(),audioOutput->periodSize());  

                    tempBuffer = tempBuffer.mid(audioOutput->periodSize());  

                }  

                else  

                {  

                    //写入到扬声器  

                    streamOut->write(tempBuffer);  

                    tempBuffer.clear();  

                    break;  

                }  

                --chunks;  

            }  

        }  

    }  

    i++;  

}  

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的评论
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: