我正在尝试读取由 ffmpeg 生成的 wav 文件
ffmpeg -i av
FFmpeg 生成一个头大小为 18 但没有任何扩展数据的 wav 文件。
这是我的数据结构:
struct wav_header {
uint32_t chunk_id;
uint32_t chunk_data_size;
uint32_t riff_type;
uint32_t fmt;
uint32_t fmt_chunk_size;
uint16_t format_tag;
uint16_t channels;
uint32_t samples_per_second;
uint32_t bytes_per_second;
uint16_t block_align; /* 1 => 8-bit mono, 2 => 8-bit stereo or 16-bit mono, 4 => 16-bit stereo */
uint16_t bits_per_sample;
};
struct fact_header {
uint32_t chunk_id;
uint32_t chunk_data_size;
uint32_t sample_length;
};
struct data_header {
uint32_t id;
uint32_t size;
};
如果我把它们读出来,我会得到我的 wav 文件的以下结果:
chunk_data_size: 40836134
ftm_chunk_size: 18
channels: 2
samples_per_second (samplerate): 48000
bytes_per_second: 192000
block_align: 4
bits_per_sample: 16
data_id: 61746164 -> 'data' OK
data_size: 40836096
我现在尝试使用公式计算以秒为单位的长度
data_size / bytes_per_second
并获得以下输出:
length_in_seconds: 212.68800354
length_in_minutes: 3.54480004 (length_in_seconds / 60)
但是当我在 iTunes 中打开我的文件时,我得到的长度是 3:31。我也尝试过使用其他声音文件,但我总是有点过分。
我还尝试过对我的 wav 文件进行 hexdump。与我执行 for (i < data_size; i += 2) printf("%02x", data[i]) 相比,hexdump 显示的输出更少
所以我不知何故读得太远了?
我在整个互联网上搜索了有关公式的信息,但我有点卡住了,因为我总是得出相同的结果。
http://www-mmsp.ece.mcgill.ca/documents/audioformats/wave/wave.html
您可以阅读以下声明:
“WAVE 文件通常具有在声音数据(数据块)之前或之后的信息块。一些程序(天真地)假设对于 PCM 数据,文件头正好是 44 字节长,并且文件的其余部分包含声音数据。这不是一个安全的假设。”
这可能是我做错了什么。但是我怎样才能得到正确的 sound_chuck_data_size 呢?
编辑
lile gcb在下面指出一切都很好。解决方案是时间以十进制时间存储,我必须将其转换为常规时间:-) 这就是我想出的,它工作正常:
track.duration_dec = (float)data.size / (header.bytes_per_second * 60);
track.duration_time = convert_time(track.duration_dec);
static double convert_time(double input) {
double integral;
double frac;
char buffer[48];
frac = modf(input, &integral);
sprintf(buffer, "%d.%1.f", (int)integral, frac*60);
return atof(buffer);
}