Reputation: 61
I have an Html audio tag where the src is set with a Blob Url of a wav file recorded with the WebAudio Api. When seeking to a different part of the audio, the 206 Partial Content response headers are populated with an incorrect Content-Length and Content-Range.
If I have a ~5 second audio clip that is 483,371 bytes long and seek to 2.4 seconds on the audio element, I am seeing the requests being populated with content-length/range for what it WOULD be if I was seeking to 4.8 seconds (or double whatever I seek to).
What I am getting:
Content-Length: 24620
Content-Range: bytes 458752-483371/483372
Content-Type: audio/wav
What I SHOULD be getting:
Content-Length: 232019
Content-Range: bytes 251353-483371/483372
Content-Type: audio/wav
If I seek to over half of the audio length, my audio doesn't play and the player gets sent back to 0. If I seek to 1 second of a 5 second clip it will get the last 3 seconds of the audio, visually display it playing from 1 second to 4 seconds, then stop playing (since it is for some reason doubling the starting position of the byte range, I am getting bytes for seconds 2-5 instead of 1-5.)
I am debugging in google chrome, has anyone else experienced this issue or have any ideas on what it could be? Would it be easier to just write my own GET requests with the correct response headers?
thoughts: It is a mono channel .Wav file,could it possibly be calculating the start time of a dual channel .wav file?
There are no other audio elements on the page, so it wouldn't be any sort of interference.
Where would I go to debug or override this 206 Partial Content Request?
Upvotes: 1
Views: 1495
Reputation: 61
So, I revisited this after a while because I am redoing a section of my project that NEEDS mono channel audio and I have had nightmares about this weird issue. It turns out there was an error in Recorder.js that would mess up the encoding of mono channel recordings. In the EncodeWav function of recorder.js, I had to change the line view.setUint32(28, sampleRate * 4, true); to view.setUint32(28, sampleRate * numChannels * 2, true);
This made the seeking of the audio files perfect, allows me to have the files in half the size, and keeps me from having to alter it to mono channel down the road.
function encodeWAV(samples) {
var buffer = new ArrayBuffer(44 + samples.length * 2);
var view = new DataView(buffer);
var numChannels = 1;
var sampleRate = 18000;
/* RIFF identifier */
writeString(view, 0, 'RIFF');
/* RIFF chunk length */
view.setUint32(4, 36 + samples.length * 2, true);
/* RIFF type */
writeString(view, 8, 'WAVE');
/* format chunk identifier */
writeString(view, 12, 'fmt ');
/* format chunk length */
view.setUint32(16, 16, true);
/* sample format (raw) */
view.setUint16(20, 1, true);
/* channel count */
view.setUint16(22, numChannels, true);
/* sample rate */
view.setUint32(24, sampleRate, true);
/* byte rate (sample rate * block align) */
//view.setUint32(28, sampleRate * 4, true);
view.setUint32(28, sampleRate * numChannels * 2, true);
/* block align (channel count * bytes per sample) */
view.setUint16(32, numChannels * 2, true);
/* bits per sample */
view.setUint16(34, 16, true);
/* data chunk identifier */
writeString(view, 36, 'data');
/* data chunk length */
view.setUint32(40, samples.length * 2, true);
floatTo16BitPCM(view, 44, samples);
return view;
}
Upvotes: 2
Reputation: 61
Update: It WAS because it was a single channel WAV file. After changing the recording to dual channel the playback worked fine. I initially did this to to reduce file size, so to compensate I recorded in dual channel and reduced the Sample Rate from 48000 to 18000.
Upvotes: 0