使用ffmpeg创建一个44字节的报头

Create a 44-byte header with ffmpeg

本文关键字:一个 字节 报头 ffmpeg 创建 使用      更新时间:2023-10-16

我编写了一个程序,使用ffmpeg库将音频文件转换为wav文件。唯一的问题是它不创建一个44字节的头。当将文件输入Kaldi语音识别时,它产生错误:

ERROR (online2-wav-nnet2-latgen-faster:Read4ByteTag():wave-reader.cc:74) WaveData: expected 4-byte chunk-name, got read errror

我通过shntool运行这个文件,它报告了一个78字节的头。无论如何,我可以得到标准的44字节头使用ffmpeg库?

FFmpeg在头文件中插入一些关于编码器的元数据。下面是修复前头文件的十六进制转储:

00000000 52 49 46 46 06 90 00 00 57 41 56 45 66 6d 74 20 |RIFF....WAVEfmt | 00000010 10 00 00 00 01 00 01 00 40 1f 00 00 80 3e 00 00 |........@....>..| 00000020 02 00 10 00 4c 49 53 54 1a 00 00 00 49 4e 46 4f |....LIST....INFO| 00000030 49 53 46 54 0e 00 00 00 4c 61 76 66 35 36 2e 33 |ISFT....Lavf56.3| 00000040 36 2e 31 30 30 00 64 61 74 61 c0 8f 00 00 00 00 |6.100.data......|

如您所见,

Lavf56.36.100是报头中的编码器。下面是我用来去掉它的那部分代码。

std::cout<<"------------------BEFORE-----------------------"<<std::endl;
std::cout<< av_dict_count ( (*ofmt_ctx)->metadata) <<std::endl;
std::cout<<"-------------------------------------------"<<std::endl; 
if(av_dict_set(&(*ofmt_ctx)->metadata,"ISFT",NULL, AV_DICT_IGNORE_SUFFIX)){
 std::cerr<<"Nope it, didn't work :("<<std::endl;
}
ret = avformat_write_header(*ofmt_ctx,&(*ofmt_ctx)->metadata );
if (ret < 0) {
  std::cout<<"-------------------------------------------"<<std::endl;
  av_log(NULL, AV_LOG_ERROR, "Error occurred when writing header to filen");
  return ret;
}
std::cout<<"------------------AFTER-----------------------"<<std::endl;
std::cout<< av_dict_count ( (*ofmt_ctx)->metadata) <<std::endl;
std::cout<<"-------------------------------------------"<<std::endl;

下面是后面的hexdump: 00000000 52 49 46 46 e4 8f 00 00 57 41 56 45 66 6d 74 20 |RIFF....WAVEfmt | 00000010 10 00 00 00 01 00 01 00 40 1f 00 00 80 3e 00 00 |........@....>..| 00000020 02 00 10 00 64 61 74 61 c0 8f 00 00 00 00 00 00 |....data........| 00000030 00 00 00 00 00 00 00 00 ff ff 00 00 00 00 00 00 |................|

shntool现在报告44字节

(注意:ofmt_ctx在这个函数中是**,因此为什么将元数据字典引用为&(*ofmt_ctx)->metadata)