C++ 将MKA音频文件解码为原始数据(MKA音频到原始音频数据)

C++ 将MKA音频文件解码为原始数据(MKA音频到原始音频数据),c++,audio,ffmpeg,decode,C++,Audio,Ffmpeg,Decode,我的任务是打开一个扩展名为mka的现有音频文件(容器),并提取原始音频数据。示例仅显示从mp2文件中提取原始数据的示例。我不知道如何使用mka容器执行此操作。我想要这样的东西: UPD 我找到了一个选项,可以将音频数据保存为音频文件中记录的格式。下面是一个例子 PS。这只是一个测试版本,很可能存在内存泄漏和其他问题。 #包括 #包括 #包括“audiodecoder.h” int main(int argc,char*argv[]) { 音频解码器(“/home/test/test.mka”)

我的任务是打开一个扩展名为mka的现有音频文件(容器),并提取原始音频数据。示例仅显示从mp2文件中提取原始数据的示例。我不知道如何使用
mka
容器执行此操作。我想要这样的东西:

UPD

我找到了一个选项,可以将音频数据保存为音频文件中记录的格式。下面是一个例子

PS。这只是一个测试版本,很可能存在内存泄漏和其他问题。


#包括
#包括
#包括“audiodecoder.h”
int main(int argc,char*argv[])
{
音频解码器(“/home/test/test.mka”);
bool start=decoder.start();
如果(!已启动){
返回退出失败;
}
QFile文件(“/home/test/rawData.bin”);
打开(QIODevice::WriteOnly);
while(true){
自动数据=解码器.getData(255);
if(data.isEmpty()){
打破
}
file.write(data.data(),data.size());
}
file.close();
返回退出成功;
}
音频解码器.h

类音频解码器{
公众:
音频解码器(常量QString和文件名);
音频解码器和运算符=(常量音频解码器和rhs)=删除;
音频解码器和运算符=(音频解码器和rhs)=删除;
音频解码器(常量音频解码器和rhs)=删除;
音频解码器(音频解码器和rhs)=删除;
虚拟音频解码器(void);
虚拟bool启动(void)无异常;
虚拟QByteArray getData(常量quint16和大小)无例外;
虚拟布尔停止(无效)无例外;
受保护的:
布尔穆初始化;
QString m_文件名;
AVFrame*p_frame=nullptr;
AVPacket*p_packet=nullptr;
AVCodecContext*p_cdcCtx=nullptr;
AVFormatContext*p_frmCtx=nullptr;
};
音频解码器.cpp


静态无效日志记录(常量字符*消息)
{
qDebug()=0){
//日志记录(QString(“AVPacket->pts%1”).arg(p_packet->pts.tostString().c_str());
//响应=解码_数据包(p_数据包、p_cdcCtx、p_帧);
响应=avcodec_发送_数据包(p_cdcCtx,p_数据包);
如果(响应<0){
记录(“向解码器发送数据包时出错”);
返回{};
}
而(响应>=0){
响应=avcodec_接收_帧(p_cdcCtx,p_帧);
if(response==AVERROR(EAGAIN)| response==AVERROR_EOF){
打破
}
否则如果(响应<0){
记录(“从解码器接收帧时出错”);
返回{};
}
如果(响应>=0){
日志记录(QString(“帧%1(类型=%2,大小=%3字节)pts%4关键帧%5[DTS%6],持续时间[%7]”)
.arg(p_cdcCtx->帧号)
.arg(av_get_picture_type_char(p_frame->pict_type))
.arg(p_框架->包装尺寸)
.arg(p_帧->pts)
.arg(p\U帧->关键帧)
.arg(p_帧->编码图片编号)
.arg(p_帧->pkt_持续时间)
.toStdString()
.c_str());
对于(int i=0;ilinesize[0];++i){
data.push_back(p_frame->data[0][i]);
}
}
}
av_数据包(p_数据包);
返回数据;
}
返回{};
}
bool音频解码器::开始(无效)无例外
{
如果(m_已初始化){
返回true;
}
整数误差;
//打开输入文件以从中读取。
如果((错误=avformat\u open\u输入(&p\u frmCtx),
m_fileName.toStdString().c_str(),nullptr,nullptr))
< 0) {
qDebug()编解码器类型!=AVMEDIA类型音频){
avformat_close_输入(&p_frmCtx);
qDebug()流[0]->codepar->codec_id))){
avformat_close_输入(&p_frmCtx);
qDebug()codecpar);
如果(错误<0){
avformat_close_输入(&p_frmCtx);
avcodec_free_上下文(&avctx);

qDebug()如果要提取音频文件中的音频数据编码格式,则应查看示例。在此示例中,您需要将输出类型从
acc
更改为
alaw
。压缩流将为:

对存储分组数据的引用计数缓冲器的引用


我还建议您阅读这篇文章。它将帮助您:)

您必须给我们更多的信息才能继续。您的具体问题是什么?@metal,我想打开任何扩展名的音频文件。之后,我想从这个音频文件中提取音频数据,并将其保存到临时缓冲区以供进一步工作。我想根据n请求的数据的特定大小。例如,在我的情况下,我需要从文件中请求1000字节的音频数据(在我的情况下,这是pcm_alaw类型的音频数据)然后处理它们。在处理它们之后,你需要请求下一个1000字节,依此类推,直到我读取整个文件。很好。现在你在该算法中停留的是什么?我们不会为你编写程序或谷歌教程,但如果你被某个特定的难题绊倒,我们会来帮助你。你只需要一个m更具体的问题。@metal,我更新了我的问题。我遇到了一个问题,如何实现获取一定大小的数据并写入
QByteArray
@metal,目前,我理解数据本身(在我的情况下,
pcm\u alaw
)是在
AVPacket::buf
中,它输出
avcodec\u receive\u packet
。对吗?