Improve wave length guessing

Instead of assuming that wav files have 44 byte headers (they usually
don't - freeswitch adds some metadata tags), add a super-simple wave
file parser that just finds the offset where the audio data actually
starts.
This commit is contained in:
Calvin Walton 2016-09-02 16:27:30 -04:00
parent f815fd0d70
commit 2cd9565d52

View File

@ -186,7 +186,8 @@ module BigBlueButton
# wav files generated by freeswitch can have incorrect length
# field if longer than 4GB, so recalculate based on filesize (ouch!)
BigBlueButton.logger.debug("Recalculated duration from wav file length")
audio_size = info[:format][:size].to_r - 44 # wav header is 44 bytes
audio_offset = self.get_wave_data_offset(filename)
audio_size = info[:format][:size].to_r - audio_offset
info[:duration] = (audio_size * 8 / info[:audio][:bit_rate].to_i * 1000).to_i
else
info[:duration] = (info[:format][:duration].to_r * 1000).to_i
@ -202,6 +203,32 @@ module BigBlueButton
ms = timestamp % 1000
"%d.%03d" % [s, ms]
end
# Helper function for determining correct length of freeswitch's long wave files
def self.get_wave_data_offset(filename)
File.open(filename, 'rb') do |file|
riff = file.read(4)
wavesize = file.read(4).unpack('V')[0].to_i
wave = file.read(4)
if riff != 'RIFF' or wavesize.nil? or wave != 'WAVE'
return 0
end
while true
# Read chunks until we find one named 'data'
chunkname = file.read(4)
chunksize = file.read(4).unpack('V')[0].to_i
if chunkname.nil? or chunksize.nil?
return 0
end
if chunkname == 'data'
# This is a data chunk; we've found the start of the real audio data
return file.tell
end
file.seek(chunksize, IO::SEEK_CUR)
end
return 0
end
end
end
end
end