dd4862c9 by Tom Johnson

toms intro to jshint

1 parent 0b06638f
......@@ -3,8 +3,8 @@
ManifestController = window.videojs.hls.ManifestController,
SegmentController = window.videojs.hls.SegmentController,
MediaSource = window.videojs.MediaSource,
SegmentParser = window.videojs.hls.SegmentParser,
M3U8 = window.videojs.hls.M3U8;
SegmentParser = window.videojs.hls.SegmentParser;
window.videojs.hls.HLSPlaybackController = function(player) {
......@@ -23,14 +23,14 @@
self.loadManifest(self.currentRendition.url, self.onM3U8LoadComplete, self.onM3U8LoadError, self.onM3U8Update);
};
self.loadManifest = function(manifestUrl, onDataCallback, onErrorCallback, onUpdateCallback) {
self.mediaSource.addEventListener('sourceopen', function(event) {
self.loadManifest = function(manifestUrl, onDataCallback) {
self.mediaSource.addEventListener('sourceopen', function() {
// feed parsed bytes into the player
self.sourceBuffer = self.mediaSource.addSourceBuffer('video/flv; codecs="vp6,aac"');
self.parser = new SegmentParser();
self.sourceBuffer.appendBuffer(self.parser.getFlvHeader(), video);
self.sourceBuffer.appendBuffer(self.parser.getFlvHeader(), self.player);
if (onDataCallback) {
self.manifestLoadCompleteCallback = onDataCallback;
......@@ -42,7 +42,7 @@
}, false);
self.player.src({
src: videojs.URL.createObjectURL(self.mediaSource),
src: window.videojs.URL.createObjectURL(self.mediaSource),
type: "video/flv"
});
};
......@@ -65,8 +65,18 @@
}
};
self.onM3U8LoadError = function(error) {};
self.onM3U8Update = function(m3u8) {};
self.onM3U8LoadError = function(error) {
if(error)
{
console.log(error);
}
};
self.onM3U8Update = function(m3u8) {
if(m3u8)
{
console.log(m3u8);
}
};
self.loadSegment = function(segment) {
self.segmentController = new SegmentController();
......@@ -88,9 +98,14 @@
self.loadNextSegment = function() {
self.currentSegment++;
self.loadSegment(self.currentManifest.mediaItems[self.currentSegment]);
}
};
self.onSegmentLoadError = function(error) {};
self.onSegmentLoadError = function(error) {
if(error)
{
console.log(error);
}
};
};
})(this);
......
......@@ -38,11 +38,11 @@
lines = rawDataString.split('\n');
lines.forEach(function(value,index) {
var segment, rendition, attribute;
var segment, rendition, attributes;
switch (self.getTagType(value)) {
case tagTypes.EXTM3U:
data.hasValidM3UTag = (index == 0);
data.hasValidM3UTag = (index === 0);
if (!data.hasValidM3UTag) {
data.invalidReasons.push("Invalid EXTM3U Tag");
}
......@@ -95,12 +95,12 @@
if (rendition[attrValue.split('=')[0].toLowerCase()].split('x').length === 2) {
rendition.resolution = {
width: parseInt(rendition[attrValue.split('=')[0].toLowerCase()].split('x')[0]),
height: parseInt(rendition[attrValue.split('=')[0].toLowerCase()].split('x')[1])
}
width: parseInt(rendition[attrValue.split('=')[0].toLowerCase()].split('x')[0],10),
height: parseInt(rendition[attrValue.split('=')[0].toLowerCase()].split('x')[1],10)
};
}
} else {
rendition[attrValue.split('=')[0].toLowerCase()] = parseInt(attrValue.split('=')[1]);
rendition[attrValue.split('=')[0].toLowerCase()] = parseInt(attrValue.split('=')[1],10);
}
});
......@@ -128,7 +128,7 @@
break;
case tagTypes.MEDIA_SEQUENCE:
data.mediaSequence = parseInt(self.getTagValue(value));
data.mediaSequence = parseInt(self.getTagValue(value),10);
break;
case tagTypes.ALLOW_CACHE:
......
(function(window) {
window.videojs.hls.M3U8 = function() {
(function (window) {
window.videojs.hls.M3U8 = function () {
this.directory = "";
this.allowCache = "NO";
this.playlistItems = [];
......
(function (window) {
var
M3U8 = window.videojs.hls.M3U8,
M3U8Parser = window.videojs.hls.M3U8Parser;
window.videojs.hls.ManifestController = function() {
var self = this;
self.parser;
self.data;
self.url;
self.onDataCallback;
self.onErrorCallback;
self.onUpdateCallback;
self.loadManifest = function(manifestUrl, onDataCallback, onErrorCallback, onUpdateCallback) {
self.url = manifestUrl;
......@@ -28,7 +19,7 @@
self.onUpdateCallback = onUpdateCallback;
}
vjs.get(manifestUrl, self.onManifestLoadComplete, self.onManifestLoadError);
window.vjs.get(manifestUrl, self.onManifestLoadComplete, self.onManifestLoadError);
};
self.parseManifest = function(dataAsString) {
......@@ -42,15 +33,15 @@
self.onManifestLoadComplete = function(response) {
var output = self.parseManifest(response);
if (self.onDataCallback != undefined) {
if (self.onDataCallback !== undefined) {
self.onDataCallback(output);
}
};
self.onManifestLoadError = function(err) {
if (self.onErrorCallback != undefined) {
self.onErrorCallback((err != undefined) ? err : null);
if (self.onErrorCallback !== undefined) {
self.onErrorCallback((err !== undefined) ? err : null);
}
};
}
};
})(this);
......
......@@ -14,7 +14,7 @@
request.open('GET', segmentUrl, true);
request.responseType = 'arraybuffer';
request.onload = function(response) {
request.onload = function() {
self.onSegmentLoadComplete(new Uint8Array(request.response));
};
......@@ -29,7 +29,7 @@
self.data.requestTimestamp = self.requestTimestamp;
self.data.responseTimestamp = self.responseTimestamp;
self.data.byteLength = incomingData.byteLength;
self.data.isCached = parseInt(self.responseTimestamp - self.requestTimestamp) < 75;
self.data.isCached = parseInt(self.responseTimestamp - self.requestTimestamp,10) < 75;
self.data.throughput = self.calculateThroughput(self.data.byteLength, self.requestTimestamp ,self.responseTimestamp);
return self.data;
......@@ -37,7 +37,7 @@
self.calculateThroughput = function(dataAmount, startTime, endTime) {
return Math.round(dataAmount / (endTime - startTime) * 1000) * 8;
}
};
self.onSegmentLoadComplete = function(response) {
var output;
......@@ -57,8 +57,8 @@
}
if (self.onErrorCallback !== undefined) {
onErrorCallback(error);
self.onErrorCallback(error);
}
};
}
};
})(this);
......
(function (window) {
/*
======== A Handy Little QUnit Reference ========
http://api.qunitjs.com/
Test methods:
module(name, {[setup][ ,teardown]})
test(name, callback)
expect(numberOfAssertions)
stop(increment)
start(decrement)
Test assertions:
ok(value, [message])
equal(actual, expected, [message])
notEqual(actual, expected, [message])
deepEqual(actual, expected, [message])
notDeepEqual(actual, expected, [message])
strictEqual(actual, expected, [message])
notStrictEqual(actual, expected, [message])
throws(block, [expected], [message])
*/
var
manifestController,
segmentController,
m3u8parser,
parser,
expectedHeader = [
0x46, 0x4c, 0x56, 0x01, 0x05, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00
],
testAudioTag,
testVideoTag,
testScriptTag,
asciiFromBytes,
testScriptString,
testScriptEcmaArray;
module('environment');
test('is sane', function () {
expect(1);
ok(true);
});
module('segment parser', {
setup: function () {
parser = new window.videojs.hls.SegmentParser();
}
});
test('creates an flv header', function () {
var header = Array.prototype.slice.call(parser.getFlvHeader());
ok(header, 'the header is truthy');
equal(9 + 4, header.length, 'the header length is correct');
equal(header[0], 'F'.charCodeAt(0), 'the first character is "F"');
equal(header[1], 'L'.charCodeAt(0), 'the second character is "L"');
equal(header[2], 'V'.charCodeAt(0), 'the third character is "V"');
deepEqual(expectedHeader, header, 'the rest of the header is correct');
});
test('parses the first bipbop segment', function () {
var tag, bytes, i;
parser.parseSegmentBinaryData(window.bcSegment);
ok(parser.tagsAvailable(), 'tags are available');
console.log('h264 tags:', parser.stats.h264Tags(),
'aac tags:', parser.stats.aacTags());
});
testAudioTag = function (tag) {
var
byte = tag.bytes[11],
format = (byte & 0xF0) >>> 4,
soundRate = byte & 0x03,
soundSize = (byte & 0x2) >>> 1,
soundType = byte & 0x1,
aacPacketType = tag.bytes[12];
equal(10, format, 'the audio format is aac');
equal(3, soundRate, 'the sound rate is 44kHhz');
equal(1, soundSize, 'the sound size is 16-bit samples');
equal(1, soundType, 'the sound type is stereo');
ok(aacPacketType === 0 || aacPacketType === 1, 'aac packets should have a valid type');
};
testVideoTag = function (tag) {
var
byte = tag.bytes[11],
frameType = (byte & 0xF0) >>> 4,
codecId = byte & 0x0F,
packetType = tag.bytes[12],
compositionTime = (tag.view.getInt32(13) & 0xFFFFFF00) >> 8,
nalHeader;
// payload starts at tag.bytes[16]
// XXX: I'm not sure that frame types 3-5 are invalid
ok(frameType === 1 || frameType === 2,
'the frame type should be valid');
equal(7, codecId, 'the codec ID is AVC for h264');
ok(packetType <= 2 && packetType >= 0, 'the packet type is within [0, 2]');
if (packetType !== 1) {
equal(0,
compositionTime,
'the composition time is zero for non-NALU packets');
}
// TODO: the rest of the bytes are an NLU unit
if (packetType === 0) {
// AVC decoder configuration record
} else {
// NAL units
testNalUnit(tag.bytes.subarray(16));
}
};
testNalUnit = function (bytes) {
var
nalHeader = bytes[0],
unitType = nalHeader & 0x1F;
equal(0, (nalHeader & 0x80) >>> 7, 'the first bit is always 0');
// equal(90, (nalHeader & 0x60) >>> 5, 'the NAL reference indicator is something');
// ok(unitType > 0, 'NAL unit type ' + unitType + ' is greater than 0');
// ok(unitType < 22 , 'NAL unit type ' + unitType + ' is less than 22');
};
asciiFromBytes = function (bytes) {
var
string = [],
i = bytes.byteLength;
while (i--) {
string[i] = String.fromCharCode(bytes[i]);
}
return string.join('');
};
testScriptString = function (tag, offset, expected) {
var
type = tag.bytes[offset],
stringLength = tag.view.getUint16(offset + 1),
string,
i = expected.length;
equal(2, type, 'the script element is of string type');
equal(stringLength, expected.length, 'the script string length is correct');
string = asciiFromBytes(tag.bytes.subarray(offset + 3,
offset + 3 + stringLength));
equal(expected, string, 'the string value is "' + expected + '"');
};
testScriptEcmaArray = function (tag, start) {
var
numItems = tag.view.getUint32(start),
i = numItems,
offset = start + 4,
length,
type;
while (i--) {
length = tag.view.getUint16(offset);
// advance offset to the property value
offset += 2 + length;
type = tag.bytes[offset];
ok(type === 1 || type === 0,
'the ecma array property value type is number or boolean');
offset++;
if (type) {
// boolean
ok(tag.bytes[offset] === 0 || tag.bytes[offset] === 1,
'the script boolean value is 0 or 1');
offset++;
} else {
// number
ok(!isNaN(tag.view.getFloat64(offset)), 'the value is not NaN');
offset += 8;
}
}
equal(tag.bytes[offset], 0, 'the property array terminator is valid');
equal(tag.bytes[offset + 1], 0, 'the property array terminator is valid');
equal(tag.bytes[offset + 2], 9, 'the property array terminator is valid');
};
testScriptTag = function (tag) {
testScriptString(tag, 11, 'onMetaData');
// the onMetaData object is stored as an 'ecma array', an array with non-
// integer indices (i.e. a dictionary or hash-map).
equal(8, tag.bytes[24], 'onMetaData is of ecma array type');
testScriptEcmaArray(tag, 25);
};
test('the flv tags are well-formed', function () {
var
tag,
byte,
type,
lastTime = 0;
parser.parseSegmentBinaryData(window.bcSegment);
while (parser.tagsAvailable()) {
tag = parser.getNextTag();
type = tag.bytes[0];
// generic flv headers
ok(type === 8 || type === 9 || type === 18,
'the type field specifies audio, video or script');
byte = (tag.view.getUint32(1) & 0xFFFFFF00) >>> 8;
equal(tag.bytes.byteLength - 11 - 4, byte, 'the size field is correct');
byte = tag.view.getUint32(5) & 0xFFFFFF00;
ok(byte >= lastTime, 'the timestamp for the tag is greater than zero');
lastTime = byte;
// tag type-specific headers
({
8: testAudioTag,
9: testVideoTag,
18: testScriptTag
})[type](tag);
// previous tag size
equal(tag.bytes.byteLength - 4,
tag.view.getUint32(tag.bytes.byteLength - 4),
'the size of the previous tag is correct');
}
});
/*
M3U8 Test Suite
*/
module('m3u8 parser', {
setup: function () {
m3u8parser = new window.videojs.hls.M3U8Parser();
}
});
test('should create my parser', function () {
ok(m3u8parser != undefined);
});
test('should successfully parse manifest data', function () {
var parsedData = m3u8parser.parse(window.playlistData);
ok(parsedData);
});
test('test for expected results', function () {
var data = m3u8parser.parse(window.playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.invalidReasons.length, 0, 'data has 0 invalid reasons');
equal(data.hasValidM3UTag, true, 'data has valid EXTM3U');
equal(data.targetDuration, 10, 'data has correct TARGET DURATION');
equal(data.allowCache, "NO", 'acceptable ALLOW CACHE');
equal(data.isPlaylist, true, 'data is parsed as a PLAYLIST as expected');
equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE');
equal(data.mediaItems.length, 16, 'acceptable mediaItem count');
equal(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct');
equal(data.totalDuration, -1, "ZEN TOTAL DURATION is unknown as expected");
equal(data.hasEndTag, true, 'should have ENDLIST tag');
});
module('brightcove playlist', {
setup: function () {
m3u8parser = new window.videojs.hls.M3U8Parser();
}
});
test('should parse a brightcove manifest data', function () {
var data = m3u8parser.parse(window.brightcove_playlist_data);
ok(data);
equal(data.playlistItems.length, 4, 'Has correct rendition count');
equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct');
equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct');
equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct');
equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct');
}
);
module('manifest controller', {
setup: function () {
manifestController = new window.videojs.hls.ManifestController();
this.vjsget = vjs.get;
vjs.get = function (url, success, error) {
success(window.brightcove_playlist_data);
};
},
teardown: function () {
vjs.get = this.vjsget;
}
});
test('should create', function () {
ok(manifestController);
});
test('should return a parsed object', function () {
var data = manifestController.parseManifest(window.brightcove_playlist_data);
ok(data);
equal(data.playlistItems.length, 4, 'Has correct rendition count');
equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct');
equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct');
equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct');
equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct');
});
test('should get a manifest from hermes', function () {
manifestController.loadManifest('http://example.com/16x9-master.m3u8',
function(responseData) {
ok(responseData);
},
function(errorData) {
ok(false, 'does not error');
},
function(updateData) {});
});
module('segment controller', {
setup: function () {
segmentController = new window.videojs.hls.SegmentController();
this.vjsget = vjs.get;
vjs.get = function (url, success, error) {
console.log('load segment url', url);
success(window.bcSegment);
};
},
teardown: function () {
vjs.get = this.vjsget;
}
});
test('bandwidth calulation test', function () {
var
multiSecondData = segmentController.calculateThroughput(10000, 1000, 2000),
subSecondData = segmentController.calculateThroughput(10000, 1000, 1500);
equal(multiSecondData, 80000, 'MULTI-Second bits per second calculation');
equal(subSecondData, 160000, 'SUB-Second bits per second calculation');
});
/*
======== A Handy Little QUnit Reference ========
http://api.qunitjs.com/
Test methods:
module(name, {[setup][ ,teardown]})
test(name, callback)
expect(numberOfAssertions)
stop(increment)
start(decrement)
Test assertions:
ok(value, [message])
equal(actual, expected, [message])
notEqual(actual, expected, [message])
deepEqual(actual, expected, [message])
notDeepEqual(actual, expected, [message])
strictEqual(actual, expected, [message])
notStrictEqual(actual, expected, [message])
throws(block, [expected], [message])
*/
var
manifestController,
segmentController,
m3u8parser,
parser,
expectedHeader = [
0x46, 0x4c, 0x56, 0x01, 0x05, 0x00, 0x00, 0x00,
0x09, 0x00, 0x00, 0x00, 0x00
],
testAudioTag,
testVideoTag,
testScriptTag,
asciiFromBytes,
testScriptString,
testScriptEcmaArray;
module('environment');
test('is sane', function () {
expect(1);
ok(true);
});
module('segment parser', {
setup: function () {
parser = new window.videojs.hls.SegmentParser();
}
});
test('creates an flv header', function () {
var header = Array.prototype.slice.call(parser.getFlvHeader());
ok(header, 'the header is truthy');
equal(9 + 4, header.length, 'the header length is correct');
equal(header[0], 'F'.charCodeAt(0), 'the first character is "F"');
equal(header[1], 'L'.charCodeAt(0), 'the second character is "L"');
equal(header[2], 'V'.charCodeAt(0), 'the third character is "V"');
deepEqual(expectedHeader, header, 'the rest of the header is correct');
});
test('parses the first bipbop segment', function () {
var tag, bytes, i;
parser.parseSegmentBinaryData(window.bcSegment);
ok(parser.tagsAvailable(), 'tags are available');
console.log('h264 tags:', parser.stats.h264Tags(),
'aac tags:', parser.stats.aacTags());
});
testAudioTag = function (tag) {
var
byte = tag.bytes[11],
format = (byte & 0xF0) >>> 4,
soundRate = byte & 0x03,
soundSize = (byte & 0x2) >>> 1,
soundType = byte & 0x1,
aacPacketType = tag.bytes[12];
equal(10, format, 'the audio format is aac');
equal(3, soundRate, 'the sound rate is 44kHhz');
equal(1, soundSize, 'the sound size is 16-bit samples');
equal(1, soundType, 'the sound type is stereo');
ok(aacPacketType === 0 || aacPacketType === 1, 'aac packets should have a valid type');
};
testVideoTag = function (tag) {
var
byte = tag.bytes[11],
frameType = (byte & 0xF0) >>> 4,
codecId = byte & 0x0F,
packetType = tag.bytes[12],
compositionTime = (tag.view.getInt32(13) & 0xFFFFFF00) >> 8,
nalHeader;
// payload starts at tag.bytes[16]
// XXX: I'm not sure that frame types 3-5 are invalid
ok(frameType === 1 || frameType === 2,
'the frame type should be valid');
equal(7, codecId, 'the codec ID is AVC for h264');
ok(packetType <= 2 && packetType >= 0, 'the packet type is within [0, 2]');
if (packetType !== 1) {
equal(0,
compositionTime,
'the composition time is zero for non-NALU packets');
}
// TODO: the rest of the bytes are an NLU unit
if (packetType === 0) {
// AVC decoder configuration record
} else {
// NAL units
testNalUnit(tag.bytes.subarray(16));
}
};
testNalUnit = function (bytes) {
var
nalHeader = bytes[0],
unitType = nalHeader & 0x1F;
equal(0, (nalHeader & 0x80) >>> 7, 'the first bit is always 0');
// equal(90, (nalHeader & 0x60) >>> 5, 'the NAL reference indicator is something');
// ok(unitType > 0, 'NAL unit type ' + unitType + ' is greater than 0');
// ok(unitType < 22 , 'NAL unit type ' + unitType + ' is less than 22');
};
asciiFromBytes = function (bytes) {
var
string = [],
i = bytes.byteLength;
while (i--) {
string[i] = String.fromCharCode(bytes[i]);
}
return string.join('');
};
testScriptString = function (tag, offset, expected) {
var
type = tag.bytes[offset],
stringLength = tag.view.getUint16(offset + 1),
string,
i = expected.length;
equal(2, type, 'the script element is of string type');
equal(stringLength, expected.length, 'the script string length is correct');
string = asciiFromBytes(tag.bytes.subarray(offset + 3,
offset + 3 + stringLength));
equal(expected, string, 'the string value is "' + expected + '"');
};
testScriptEcmaArray = function (tag, start) {
var
numItems = tag.view.getUint32(start),
i = numItems,
offset = start + 4,
length,
type;
while (i--) {
length = tag.view.getUint16(offset);
// advance offset to the property value
offset += 2 + length;
type = tag.bytes[offset];
ok(type === 1 || type === 0,
'the ecma array property value type is number or boolean');
offset++;
if (type) {
// boolean
ok(tag.bytes[offset] === 0 || tag.bytes[offset] === 1,
'the script boolean value is 0 or 1');
offset++;
} else {
// number
ok(!isNaN(tag.view.getFloat64(offset)), 'the value is not NaN');
offset += 8;
}
}
equal(tag.bytes[offset], 0, 'the property array terminator is valid');
equal(tag.bytes[offset + 1], 0, 'the property array terminator is valid');
equal(tag.bytes[offset + 2], 9, 'the property array terminator is valid');
};
testScriptTag = function (tag) {
testScriptString(tag, 11, 'onMetaData');
// the onMetaData object is stored as an 'ecma array', an array with non-
// integer indices (i.e. a dictionary or hash-map).
equal(8, tag.bytes[24], 'onMetaData is of ecma array type');
testScriptEcmaArray(tag, 25);
};
test('the flv tags are well-formed', function () {
var
tag,
byte,
type,
lastTime = 0;
parser.parseSegmentBinaryData(window.bcSegment);
while (parser.tagsAvailable()) {
tag = parser.getNextTag();
type = tag.bytes[0];
// generic flv headers
ok(type === 8 || type === 9 || type === 18,
'the type field specifies audio, video or script');
byte = (tag.view.getUint32(1) & 0xFFFFFF00) >>> 8;
equal(tag.bytes.byteLength - 11 - 4, byte, 'the size field is correct');
byte = tag.view.getUint32(5) & 0xFFFFFF00;
ok(byte >= lastTime, 'the timestamp for the tag is greater than zero');
lastTime = byte;
// tag type-specific headers
({
8: testAudioTag,
9: testVideoTag,
18: testScriptTag
})[type](tag);
// previous tag size
equal(tag.bytes.byteLength - 4,
tag.view.getUint32(tag.bytes.byteLength - 4),
'the size of the previous tag is correct');
}
});
/*
M3U8 Test Suite
*/
module('m3u8 parser', {
setup: function () {
m3u8parser = new window.videojs.hls.M3U8Parser();
}
});
test('should create my parser', function () {
ok(m3u8parser != undefined);
});
test('should successfully parse manifest data', function () {
var parsedData = m3u8parser.parse(window.playlistData);
ok(parsedData);
});
test('test for expected results', function () {
var data = m3u8parser.parse(window.playlistData);
notEqual(data, null, 'data is not NULL');
equal(data.invalidReasons.length, 0, 'data has 0 invalid reasons');
equal(data.hasValidM3UTag, true, 'data has valid EXTM3U');
equal(data.targetDuration, 10, 'data has correct TARGET DURATION');
equal(data.allowCache, "NO", 'acceptable ALLOW CACHE');
equal(data.isPlaylist, true, 'data is parsed as a PLAYLIST as expected');
equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE');
equal(data.mediaItems.length, 16, 'acceptable mediaItem count');
equal(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct');
equal(data.totalDuration, -1, "ZEN TOTAL DURATION is unknown as expected");
equal(data.hasEndTag, true, 'should have ENDLIST tag');
});
module('brightcove playlist', {
setup: function () {
m3u8parser = new window.videojs.hls.M3U8Parser();
}
});
test('should parse a brightcove manifest data', function () {
var data = m3u8parser.parse(window.brightcove_playlist_data);
ok(data);
equal(data.playlistItems.length, 4, 'Has correct rendition count');
equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct');
equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct');
equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct');
equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct');
}
);
module('manifest controller', {
setup: function () {
manifestController = new window.videojs.hls.ManifestController();
this.vjsget = vjs.get;
vjs.get = function (url, success, error) {
success(window.brightcove_playlist_data);
};
},
teardown: function () {
vjs.get = this.vjsget;
}
});
test('should create', function () {
ok(manifestController);
});
test('should return a parsed object', function () {
var data = manifestController.parseManifest(window.brightcove_playlist_data);
ok(data);
equal(data.playlistItems.length, 4, 'Has correct rendition count');
equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct');
equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct');
equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct');
equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct');
});
test('should get a manifest from hermes', function () {
manifestController.loadManifest('http://example.com/16x9-master.m3u8',
function (responseData) {
ok(responseData);
},
function (errorData) {
ok(false, 'does not error');
},
function (updateData) {
});
});
module('segment controller', {
setup: function () {
segmentController = new window.videojs.hls.SegmentController();
this.vjsget = vjs.get;
vjs.get = function (url, success, error) {
console.log('load segment url', url);
success(window.bcSegment);
};
},
teardown: function () {
vjs.get = this.vjsget;
}
});
test('bandwidth calulation test', function () {
var
multiSecondData = segmentController.calculateThroughput(10000, 1000, 2000),
subSecondData = segmentController.calculateThroughput(10000, 1000, 1500);
equal(multiSecondData, 80000, 'MULTI-Second bits per second calculation');
equal(subSecondData, 160000, 'SUB-Second bits per second calculation');
});
})(this);
......