一、获取PCM音频
ffmpeg -i input.mp3 -acodec pcm_s16le -ar 44100 -ac 2 -f s16le output.pcm
-acodec pcm_s16le
:指定16位小端PCM编码格式(兼容性最佳)-ar 44100
:设置采样率为CD标准44.1kHz(可替换为16000/8000等)-ac 2
:保留立体声(单声道用-ac 1
)-f s16le
:强制输出二进制裸数据格式
二、播放
方式1:
int main(int argc, char *argv[])
{
qSetMessagePattern("[GUI]%{file}(%{line}): %{message}");
QGuiApplication app(argc, argv);
QFile file(argv[1]); // 需要播放的音频
if (file.open(QIODevice::ReadOnly))
{
qDebug() << "打开成功!";
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
qDebug() << info.supportedSampleTypes(); // 输出支持的样本类型列表。
qDebug() << info.supportedByteOrders(); // 输出支持的字节顺序列表
qDebug() << info.supportedCodecs(); // 输出可用编码器
qDebug() << info.supportedSampleRates(); // 输出支持的采样率
QAudioFormat fmt;
fmt.setSampleRate(44100); // 设置采样率
fmt.setSampleSize(16); // 设置样本大小
fmt.setChannelCount(2); // 设置使用双通道
fmt.setCodec("audio/pcm"); // 设置编解码器
fmt.setByteOrder(QAudioFormat::LittleEndian); // 使用小端
fmt.setSampleType(QAudioFormat::SignedInt); //使用无符号整数样本类型(如果在linux下显示支持UnSignedInt,但是实际打开会失败,改用SignedInt就可以了)
if (!info.isFormatSupported(fmt))
{
qDebug() << "输出设备不支持该格式,不能播放音频";
return 0;
}
QAudioOutput* audio = new QAudioOutput(fmt, qApp);
audio->setVolume(QString(argv[2]).toFloat());
audio->start(&file);
}
return app.exec();
}
方式2:
int main(int argc, char *argv[])
{
qSetMessagePattern("[GUI]%{file}(%{line}): %{message}");
QGuiApplication app(argc, argv);
QFile file(argv[1]); // 需要播放的音频
if (file.open(QIODevice::ReadOnly))
{
qDebug() << "打开成功!";
QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
qDebug() << info.supportedSampleTypes(); // 输出支持的样本类型列表。
qDebug() << info.supportedByteOrders(); // 输出支持的字节顺序列表
qDebug() << info.supportedCodecs(); // 输出可用编码器
qDebug() << info.supportedSampleRates(); // 输出支持的采样率
QAudioFormat fmt;
fmt.setSampleRate(44100); // 设置采样率
fmt.setSampleSize(16); // 设置样本大小
fmt.setChannelCount(2); // 设置使用双通道
fmt.setCodec("audio/pcm"); // 设置编解码器
fmt.setByteOrder(QAudioFormat::LittleEndian); // 使用小端
fmt.setSampleType(QAudioFormat::SignedInt); //使用无符号整数样本类型(如果在linux下显示支持UnSignedInt,但是实际打开会失败,改用SignedInt就可以了)
if (!info.isFormatSupported(fmt))
{
qDebug() << "输出设备不支持该格式,不能播放音频";
return 0;
}
QAudioOutput* audio = new QAudioOutput(fmt, qApp);
audio->setVolume(QString(argv[2]).toFloat());
QIODevice* io = audio->start();
int size = audio->periodSize(); // 这是每个周期防止缓冲区欠载和确保不间断播放所需的数据量。
QByteArray buf = file.readAll(); // 将需要播放的音频数据读到buf中
file.close();
while (!buf.isEmpty())
{
if (audio->bytesFree() < size) // 音频缓冲区中可用的空闲字节数,判断缓冲区是否可写入数据。
{
QThread::msleep(1);
continue;
}
io->write(buf.mid(0, size)); // 写入需要播放的数据
buf.remove(0, size);
//qDebug() << buf.count();
}
io->close();
delete audio;
audio = nullptr;
}
return app.exec();
}
觉得有帮助的话,打赏一下呗。。
需要商务合作(定制程序)的欢迎私信!!