Skip to content

Instantly share code, notes, and snippets.

@pkulak
Created February 10, 2015 23:41
Show Gist options
  • Save pkulak/61de475a74d824a9d875 to your computer and use it in GitHub Desktop.
Save pkulak/61de475a74d824a9d875 to your computer and use it in GitHub Desktop.
Roku BIF File JavaScript Parser
// Takes an ArrayBuffer; returns an array of these objects:
// {
// seconds: *number of seconds into the video of this image*,
// bytes: *the bytes of this image, as an ArrayBuffer*
// }
var parseBif = function(buffer) {
var data = new Uint8Array(buffer);
// Make sure this really is a BIF.
var magicNumber = [0x89, 0x42, 0x49, 0x46, 0x0d, 0x0a, 0x1a, 0x0a];
for (var i = 0; i < magicNumber.length; i++) {
if (data[i] != magicNumber[i]) {
return false;
}
}
var version = sliceToLong(data, 8, 12);
if (version != 0) {
return false;
}
var separation = sliceToLong(data, 16, 20);
if (separation == 0) {
separation = 1000;
}
var refs = [];
var lastRef = null;
for (var i = 64; true; i += 8) {
var ts = sliceToLong(data, i, i + 4);
var offset = sliceToLong(data, i + 4, i + 8);
if (ts == 0xFFFFFFFF) {
lastRef.end = offset;
break;
}
var ref = {
timestamp: ts,
start: offset
};
if (lastRef != null) {
lastRef.end = offset;
}
refs.push(ref);
lastRef = ref;
}
var images = [];
for (var i = 0; i < refs.length; i++) {
var ref = refs[i];
images.push({
seconds: (ref.timestamp * separation) / 1000,
bytes: buffer.slice(ref.start, ref.end)
});
}
return images;
};
var sliceToLong = function(data, start, end) {
var value = 0;
for (var i = end - 1; i >= start; i--) {
value = (value * 256) + data[i];
}
return value;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment