Fix up dist production in Gruntfile and cleanup jshint in test cases
Explicitly list out source files so they are concatenated in the correct order in the final build.
Showing
4 changed files
with
362 additions
and
359 deletions
... | @@ -20,7 +20,19 @@ module.exports = function(grunt) { | ... | @@ -20,7 +20,19 @@ module.exports = function(grunt) { |
20 | stripBanners: true | 20 | stripBanners: true |
21 | }, | 21 | }, |
22 | dist: { | 22 | dist: { |
23 | src: ['src/*.js'], | 23 | src: ['src/video-js-hls.js', |
24 | 'src/flv-tag.js', | ||
25 | 'src/exp-golomb.js', | ||
26 | 'src/h264-stream.js', | ||
27 | 'src/aac-stream.js', | ||
28 | 'src/segment-parser.js', | ||
29 | 'src/segment-controller.js', | ||
30 | 'src/m3u8/m3u8.js', | ||
31 | 'src/m3u8/m3u8-tag-types.js', | ||
32 | 'src/m3u8/m3u8-parser.js', | ||
33 | 'src/manifest-controller.js', | ||
34 | 'src/segment-controller.js', | ||
35 | 'src/hls-playback-controller.js'], | ||
24 | dest: 'dist/videojs.hls.js' | 36 | dest: 'dist/videojs.hls.js' |
25 | }, | 37 | }, |
26 | }, | 38 | }, |
... | @@ -53,7 +65,7 @@ module.exports = function(grunt) { | ... | @@ -53,7 +65,7 @@ module.exports = function(grunt) { |
53 | options: { | 65 | options: { |
54 | jshintrc: 'test/.jshintrc' | 66 | jshintrc: 'test/.jshintrc' |
55 | }, | 67 | }, |
56 | src: ['test/**/*.js', '!test/tsSegment.js'] | 68 | src: ['test/**/*.js', '!test/tsSegment.js', '!test/fixtures/*.js'] |
57 | }, | 69 | }, |
58 | }, | 70 | }, |
59 | watch: { | 71 | watch: { | ... | ... |
... | @@ -6,4 +6,4 @@ window.brightcove_playlist_data = '#EXTM3U\n'+ | ... | @@ -6,4 +6,4 @@ window.brightcove_playlist_data = '#EXTM3U\n'+ |
6 | '#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=440000,RESOLUTION=396x224\n'+ | 6 | '#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=440000,RESOLUTION=396x224\n'+ |
7 | 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001\n'+ | 7 | 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824686593001&videoId=1824650741001\n'+ |
8 | '#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1928000,RESOLUTION=960x540\n'+ | 8 | '#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1928000,RESOLUTION=960x540\n'+ |
9 | 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001' | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
9 | 'http://c.brightcove.com/services/mobile/streaming/index/rendition.m3u8?assetId=1824687660001&videoId=1824650741001'; | ... | ... |
1 | (function (window) { | 1 | (function(window) { |
2 | /* | 2 | /* |
3 | ======== A Handy Little QUnit Reference ======== | 3 | ======== A Handy Little QUnit Reference ======== |
4 | http://api.qunitjs.com/ | 4 | http://api.qunitjs.com/ |
5 | 5 | ||
6 | Test methods: | 6 | Test methods: |
7 | module(name, {[setup][ ,teardown]}) | 7 | module(name, {[setup][ ,teardown]}) |
8 | test(name, callback) | 8 | test(name, callback) |
9 | expect(numberOfAssertions) | 9 | expect(numberOfAssertions) |
10 | stop(increment) | 10 | stop(increment) |
11 | start(decrement) | 11 | start(decrement) |
12 | Test assertions: | 12 | Test assertions: |
13 | ok(value, [message]) | 13 | ok(value, [message]) |
14 | equal(actual, expected, [message]) | 14 | equal(actual, expected, [message]) |
15 | notEqual(actual, expected, [message]) | 15 | notEqual(actual, expected, [message]) |
16 | deepEqual(actual, expected, [message]) | 16 | deepEqual(actual, expected, [message]) |
17 | notDeepEqual(actual, expected, [message]) | 17 | notDeepEqual(actual, expected, [message]) |
18 | strictEqual(actual, expected, [message]) | 18 | strictEqual(actual, expected, [message]) |
19 | notStrictEqual(actual, expected, [message]) | 19 | notStrictEqual(actual, expected, [message]) |
20 | throws(block, [expected], [message]) | 20 | throws(block, [expected], [message]) |
21 | */ | 21 | */ |
22 | var | 22 | var |
23 | manifestController, | 23 | manifestController, |
24 | segmentController, | 24 | segmentController, |
25 | m3u8parser, | 25 | m3u8parser, |
26 | parser, | 26 | parser, |
27 | 27 | ||
28 | expectedHeader = [ | 28 | expectedHeader = [ |
29 | 0x46, 0x4c, 0x56, 0x01, 0x05, 0x00, 0x00, 0x00, | 29 | 0x46, 0x4c, 0x56, 0x01, 0x05, 0x00, 0x00, 0x00, |
30 | 0x09, 0x00, 0x00, 0x00, 0x00 | 30 | 0x09, 0x00, 0x00, 0x00, 0x00 |
31 | ], | 31 | ], |
32 | testAudioTag, | 32 | testAudioTag, |
33 | testVideoTag, | 33 | testVideoTag, |
34 | testScriptTag, | 34 | testScriptTag, |
35 | asciiFromBytes, | 35 | asciiFromBytes, |
36 | testScriptString, | 36 | testScriptString, |
37 | testScriptEcmaArray; | 37 | testScriptEcmaArray, |
38 | 38 | testNalUnit; | |
39 | module('environment'); | 39 | |
40 | 40 | module('environment'); | |
41 | test('is sane', function () { | 41 | |
42 | expect(1); | 42 | test('is sane', function() { |
43 | ok(true); | 43 | expect(1); |
44 | }); | 44 | ok(true); |
45 | 45 | }); | |
46 | module('segment parser', { | 46 | |
47 | setup: function () { | 47 | module('segment parser', { |
48 | parser = new window.videojs.hls.SegmentParser(); | 48 | setup: function() { |
49 | } | 49 | parser = new window.videojs.hls.SegmentParser(); |
50 | }); | 50 | } |
51 | 51 | }); | |
52 | test('creates an flv header', function () { | 52 | |
53 | var header = Array.prototype.slice.call(parser.getFlvHeader()); | 53 | test('creates an flv header', function() { |
54 | ok(header, 'the header is truthy'); | 54 | var header = Array.prototype.slice.call(parser.getFlvHeader()); |
55 | equal(9 + 4, header.length, 'the header length is correct'); | 55 | ok(header, 'the header is truthy'); |
56 | equal(header[0], 'F'.charCodeAt(0), 'the first character is "F"'); | 56 | equal(9 + 4, header.length, 'the header length is correct'); |
57 | equal(header[1], 'L'.charCodeAt(0), 'the second character is "L"'); | 57 | equal(header[0], 'F'.charCodeAt(0), 'the first character is "F"'); |
58 | equal(header[2], 'V'.charCodeAt(0), 'the third character is "V"'); | 58 | equal(header[1], 'L'.charCodeAt(0), 'the second character is "L"'); |
59 | 59 | equal(header[2], 'V'.charCodeAt(0), 'the third character is "V"'); | |
60 | deepEqual(expectedHeader, header, 'the rest of the header is correct'); | 60 | |
61 | }); | 61 | deepEqual(expectedHeader, header, 'the rest of the header is correct'); |
62 | 62 | }); | |
63 | test('parses the first bipbop segment', function () { | 63 | |
64 | var tag, bytes, i; | 64 | test('parses the first bipbop segment', function() { |
65 | parser.parseSegmentBinaryData(window.bcSegment); | 65 | parser.parseSegmentBinaryData(window.bcSegment); |
66 | 66 | ||
67 | ok(parser.tagsAvailable(), 'tags are available'); | 67 | ok(parser.tagsAvailable(), 'tags are available'); |
68 | 68 | }); | |
69 | console.log('h264 tags:', parser.stats.h264Tags(), | 69 | |
70 | 'aac tags:', parser.stats.aacTags()); | 70 | testAudioTag = function(tag) { |
71 | }); | 71 | var |
72 | 72 | byte = tag.bytes[11], | |
73 | testAudioTag = function (tag) { | 73 | format = (byte & 0xF0) >>> 4, |
74 | var | 74 | soundRate = byte & 0x03, |
75 | byte = tag.bytes[11], | 75 | soundSize = (byte & 0x2) >>> 1, |
76 | format = (byte & 0xF0) >>> 4, | 76 | soundType = byte & 0x1, |
77 | soundRate = byte & 0x03, | 77 | aacPacketType = tag.bytes[12]; |
78 | soundSize = (byte & 0x2) >>> 1, | 78 | |
79 | soundType = byte & 0x1, | 79 | equal(10, format, 'the audio format is aac'); |
80 | aacPacketType = tag.bytes[12]; | 80 | equal(3, soundRate, 'the sound rate is 44kHhz'); |
81 | 81 | equal(1, soundSize, 'the sound size is 16-bit samples'); | |
82 | equal(10, format, 'the audio format is aac'); | 82 | equal(1, soundType, 'the sound type is stereo'); |
83 | equal(3, soundRate, 'the sound rate is 44kHhz'); | 83 | |
84 | equal(1, soundSize, 'the sound size is 16-bit samples'); | 84 | ok(aacPacketType === 0 || aacPacketType === 1, 'aac packets should have a valid type'); |
85 | equal(1, soundType, 'the sound type is stereo'); | 85 | }; |
86 | 86 | ||
87 | ok(aacPacketType === 0 || aacPacketType === 1, 'aac packets should have a valid type'); | 87 | testVideoTag = function (tag) { |
88 | }; | 88 | var |
89 | 89 | byte = tag.bytes[11], | |
90 | testVideoTag = function (tag) { | 90 | frameType = (byte & 0xF0) >>> 4, |
91 | var | 91 | codecId = byte & 0x0F, |
92 | byte = tag.bytes[11], | 92 | packetType = tag.bytes[12], |
93 | frameType = (byte & 0xF0) >>> 4, | 93 | compositionTime = (tag.view.getInt32(13) & 0xFFFFFF00) >> 8; |
94 | codecId = byte & 0x0F, | 94 | |
95 | packetType = tag.bytes[12], | 95 | // payload starts at tag.bytes[16] |
96 | compositionTime = (tag.view.getInt32(13) & 0xFFFFFF00) >> 8, | 96 | |
97 | nalHeader; | 97 | // XXX: I'm not sure that frame types 3-5 are invalid |
98 | 98 | ok(frameType === 1 || frameType === 2, | |
99 | // payload starts at tag.bytes[16] | 99 | 'the frame type should be valid'); |
100 | 100 | ||
101 | 101 | equal(7, codecId, 'the codec ID is AVC for h264'); | |
102 | // XXX: I'm not sure that frame types 3-5 are invalid | 102 | ok(packetType <= 2 && packetType >= 0, 'the packet type is within [0, 2]'); |
103 | ok(frameType === 1 || frameType === 2, | 103 | if (packetType !== 1) { |
104 | 'the frame type should be valid'); | 104 | equal(0, |
105 | 105 | compositionTime, | |
106 | equal(7, codecId, 'the codec ID is AVC for h264'); | 106 | 'the composition time is zero for non-NALU packets'); |
107 | ok(packetType <= 2 && packetType >= 0, 'the packet type is within [0, 2]'); | 107 | } |
108 | if (packetType !== 1) { | 108 | |
109 | equal(0, | 109 | // TODO: the rest of the bytes are an NLU unit |
110 | compositionTime, | 110 | if (packetType === 0) { |
111 | 'the composition time is zero for non-NALU packets'); | 111 | // AVC decoder configuration record |
112 | } | 112 | } else { |
113 | 113 | // NAL units | |
114 | // TODO: the rest of the bytes are an NLU unit | 114 | testNalUnit(tag.bytes.subarray(16)); |
115 | if (packetType === 0) { | 115 | } |
116 | // AVC decoder configuration record | 116 | }; |
117 | } else { | 117 | |
118 | // NAL units | 118 | testNalUnit = function(bytes) { |
119 | testNalUnit(tag.bytes.subarray(16)); | 119 | var |
120 | } | 120 | nalHeader = bytes[0]; |
121 | }; | 121 | // unitType = nalHeader & 0x1F; |
122 | 122 | ||
123 | testNalUnit = function (bytes) { | 123 | equal(0, (nalHeader & 0x80) >>> 7, 'the first bit is always 0'); |
124 | var | 124 | // equal(90, (nalHeader & 0x60) >>> 5, 'the NAL reference indicator is something'); |
125 | nalHeader = bytes[0], | 125 | // ok(unitType > 0, 'NAL unit type ' + unitType + ' is greater than 0'); |
126 | unitType = nalHeader & 0x1F; | 126 | // ok(unitType < 22 , 'NAL unit type ' + unitType + ' is less than 22'); |
127 | 127 | }; | |
128 | equal(0, (nalHeader & 0x80) >>> 7, 'the first bit is always 0'); | 128 | |
129 | // equal(90, (nalHeader & 0x60) >>> 5, 'the NAL reference indicator is something'); | 129 | |
130 | // ok(unitType > 0, 'NAL unit type ' + unitType + ' is greater than 0'); | 130 | asciiFromBytes = function(bytes) { |
131 | // ok(unitType < 22 , 'NAL unit type ' + unitType + ' is less than 22'); | 131 | var |
132 | }; | 132 | string = [], |
133 | 133 | i = bytes.byteLength; | |
134 | 134 | ||
135 | asciiFromBytes = function (bytes) { | 135 | while (i--) { |
136 | var | 136 | string[i] = String.fromCharCode(bytes[i]); |
137 | string = [], | 137 | } |
138 | i = bytes.byteLength; | 138 | return string.join(''); |
139 | 139 | }; | |
140 | while (i--) { | 140 | |
141 | string[i] = String.fromCharCode(bytes[i]); | 141 | testScriptString = function(tag, offset, expected) { |
142 | } | 142 | var |
143 | return string.join(''); | 143 | type = tag.bytes[offset], |
144 | }; | 144 | stringLength = tag.view.getUint16(offset + 1), |
145 | 145 | string; | |
146 | testScriptString = function (tag, offset, expected) { | 146 | |
147 | var | 147 | equal(2, type, 'the script element is of string type'); |
148 | type = tag.bytes[offset], | 148 | equal(stringLength, expected.length, 'the script string length is correct'); |
149 | stringLength = tag.view.getUint16(offset + 1), | 149 | string = asciiFromBytes(tag.bytes.subarray(offset + 3, |
150 | string, | 150 | offset + 3 + stringLength)); |
151 | i = expected.length; | 151 | equal(expected, string, 'the string value is "' + expected + '"'); |
152 | 152 | }; | |
153 | equal(2, type, 'the script element is of string type'); | 153 | |
154 | equal(stringLength, expected.length, 'the script string length is correct'); | 154 | testScriptEcmaArray = function(tag, start) { |
155 | string = asciiFromBytes(tag.bytes.subarray(offset + 3, | 155 | var |
156 | offset + 3 + stringLength)); | 156 | numItems = tag.view.getUint32(start), |
157 | equal(expected, string, 'the string value is "' + expected + '"'); | 157 | i = numItems, |
158 | }; | 158 | offset = start + 4, |
159 | 159 | length, | |
160 | testScriptEcmaArray = function (tag, start) { | 160 | type; |
161 | var | 161 | |
162 | numItems = tag.view.getUint32(start), | 162 | while (i--) { |
163 | i = numItems, | 163 | length = tag.view.getUint16(offset); |
164 | offset = start + 4, | 164 | |
165 | length, | 165 | // advance offset to the property value |
166 | type; | 166 | offset += 2 + length; |
167 | 167 | ||
168 | while (i--) { | 168 | type = tag.bytes[offset]; |
169 | length = tag.view.getUint16(offset); | 169 | ok(type === 1 || type === 0, |
170 | 170 | 'the ecma array property value type is number or boolean'); | |
171 | // advance offset to the property value | 171 | offset++; |
172 | offset += 2 + length; | 172 | if (type) { |
173 | 173 | // boolean | |
174 | type = tag.bytes[offset]; | 174 | ok(tag.bytes[offset] === 0 || tag.bytes[offset] === 1, |
175 | ok(type === 1 || type === 0, | 175 | 'the script boolean value is 0 or 1'); |
176 | 'the ecma array property value type is number or boolean'); | 176 | offset++; |
177 | offset++; | 177 | } else { |
178 | if (type) { | 178 | // number |
179 | // boolean | 179 | ok(!isNaN(tag.view.getFloat64(offset)), 'the value is not NaN'); |
180 | ok(tag.bytes[offset] === 0 || tag.bytes[offset] === 1, | 180 | offset += 8; |
181 | 'the script boolean value is 0 or 1'); | 181 | } |
182 | offset++; | 182 | } |
183 | } else { | 183 | equal(tag.bytes[offset], 0, 'the property array terminator is valid'); |
184 | // number | 184 | equal(tag.bytes[offset + 1], 0, 'the property array terminator is valid'); |
185 | ok(!isNaN(tag.view.getFloat64(offset)), 'the value is not NaN'); | 185 | equal(tag.bytes[offset + 2], 9, 'the property array terminator is valid'); |
186 | offset += 8; | 186 | }; |
187 | } | 187 | |
188 | } | 188 | testScriptTag = function(tag) { |
189 | equal(tag.bytes[offset], 0, 'the property array terminator is valid'); | 189 | testScriptString(tag, 11, 'onMetaData'); |
190 | equal(tag.bytes[offset + 1], 0, 'the property array terminator is valid'); | 190 | |
191 | equal(tag.bytes[offset + 2], 9, 'the property array terminator is valid'); | 191 | // the onMetaData object is stored as an 'ecma array', an array with non- |
192 | }; | 192 | // integer indices (i.e. a dictionary or hash-map). |
193 | 193 | equal(8, tag.bytes[24], 'onMetaData is of ecma array type'); | |
194 | testScriptTag = function (tag) { | 194 | testScriptEcmaArray(tag, 25); |
195 | testScriptString(tag, 11, 'onMetaData'); | 195 | }; |
196 | 196 | ||
197 | // the onMetaData object is stored as an 'ecma array', an array with non- | 197 | test('the flv tags are well-formed', function() { |
198 | // integer indices (i.e. a dictionary or hash-map). | 198 | var |
199 | equal(8, tag.bytes[24], 'onMetaData is of ecma array type'); | 199 | tag, |
200 | testScriptEcmaArray(tag, 25); | 200 | byte, |
201 | }; | 201 | type, |
202 | 202 | lastTime = 0; | |
203 | test('the flv tags are well-formed', function () { | 203 | parser.parseSegmentBinaryData(window.bcSegment); |
204 | var | 204 | |
205 | tag, | 205 | while (parser.tagsAvailable()) { |
206 | byte, | 206 | tag = parser.getNextTag(); |
207 | type, | 207 | type = tag.bytes[0]; |
208 | lastTime = 0; | 208 | |
209 | parser.parseSegmentBinaryData(window.bcSegment); | 209 | // generic flv headers |
210 | 210 | ok(type === 8 || type === 9 || type === 18, | |
211 | while (parser.tagsAvailable()) { | 211 | 'the type field specifies audio, video or script'); |
212 | tag = parser.getNextTag(); | 212 | |
213 | type = tag.bytes[0]; | 213 | byte = (tag.view.getUint32(1) & 0xFFFFFF00) >>> 8; |
214 | 214 | equal(tag.bytes.byteLength - 11 - 4, byte, 'the size field is correct'); | |
215 | // generic flv headers | 215 | |
216 | ok(type === 8 || type === 9 || type === 18, | 216 | byte = tag.view.getUint32(5) & 0xFFFFFF00; |
217 | 'the type field specifies audio, video or script'); | 217 | ok(byte >= lastTime, 'the timestamp for the tag is greater than zero'); |
218 | 218 | lastTime = byte; | |
219 | byte = (tag.view.getUint32(1) & 0xFFFFFF00) >>> 8; | 219 | |
220 | equal(tag.bytes.byteLength - 11 - 4, byte, 'the size field is correct'); | 220 | // tag type-specific headers |
221 | 221 | ({ | |
222 | byte = tag.view.getUint32(5) & 0xFFFFFF00; | 222 | 8: testAudioTag, |
223 | ok(byte >= lastTime, 'the timestamp for the tag is greater than zero'); | 223 | 9: testVideoTag, |
224 | lastTime = byte; | 224 | 18: testScriptTag |
225 | 225 | })[type](tag); | |
226 | // tag type-specific headers | 226 | |
227 | ({ | 227 | // previous tag size |
228 | 8: testAudioTag, | 228 | equal(tag.bytes.byteLength - 4, |
229 | 9: testVideoTag, | 229 | tag.view.getUint32(tag.bytes.byteLength - 4), |
230 | 18: testScriptTag | 230 | 'the size of the previous tag is correct'); |
231 | })[type](tag); | 231 | } |
232 | 232 | }); | |
233 | // previous tag size | 233 | |
234 | equal(tag.bytes.byteLength - 4, | 234 | /* |
235 | tag.view.getUint32(tag.bytes.byteLength - 4), | 235 | M3U8 Test Suite |
236 | 'the size of the previous tag is correct'); | 236 | */ |
237 | } | 237 | |
238 | }); | 238 | module('m3u8 parser', { |
239 | 239 | setup: function() { | |
240 | /* | 240 | m3u8parser = new window.videojs.hls.M3U8Parser(); |
241 | M3U8 Test Suite | 241 | } |
242 | */ | 242 | }); |
243 | 243 | ||
244 | module('m3u8 parser', { | 244 | test('should create my parser', function() { |
245 | setup: function () { | 245 | ok(m3u8parser !== undefined); |
246 | m3u8parser = new window.videojs.hls.M3U8Parser(); | 246 | }); |
247 | } | 247 | |
248 | }); | 248 | test('should successfully parse manifest data', function() { |
249 | 249 | var parsedData = m3u8parser.parse(window.playlistData); | |
250 | test('should create my parser', function () { | 250 | ok(parsedData); |
251 | ok(m3u8parser != undefined); | 251 | }); |
252 | }); | 252 | |
253 | 253 | test('test for expected results', function() { | |
254 | test('should successfully parse manifest data', function () { | 254 | var data = m3u8parser.parse(window.playlistData); |
255 | var parsedData = m3u8parser.parse(window.playlistData); | 255 | |
256 | ok(parsedData); | 256 | notEqual(data, null, 'data is not NULL'); |
257 | }); | 257 | equal(data.invalidReasons.length, 0, 'data has 0 invalid reasons'); |
258 | 258 | equal(data.hasValidM3UTag, true, 'data has valid EXTM3U'); | |
259 | test('test for expected results', function () { | 259 | equal(data.targetDuration, 10, 'data has correct TARGET DURATION'); |
260 | var data = m3u8parser.parse(window.playlistData); | 260 | equal(data.allowCache, "NO", 'acceptable ALLOW CACHE'); |
261 | 261 | equal(data.isPlaylist, true, 'data is parsed as a PLAYLIST as expected'); | |
262 | notEqual(data, null, 'data is not NULL'); | 262 | equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE'); |
263 | equal(data.invalidReasons.length, 0, 'data has 0 invalid reasons'); | 263 | equal(data.mediaItems.length, 16, 'acceptable mediaItem count'); |
264 | equal(data.hasValidM3UTag, true, 'data has valid EXTM3U'); | 264 | equal(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct'); |
265 | equal(data.targetDuration, 10, 'data has correct TARGET DURATION'); | 265 | equal(data.totalDuration, -1, "ZEN TOTAL DURATION is unknown as expected"); |
266 | equal(data.allowCache, "NO", 'acceptable ALLOW CACHE'); | 266 | equal(data.hasEndTag, true, 'should have ENDLIST tag'); |
267 | equal(data.isPlaylist, true, 'data is parsed as a PLAYLIST as expected'); | 267 | }); |
268 | equal(data.playlistType, "VOD", 'acceptable PLAYLIST TYPE'); | 268 | |
269 | equal(data.mediaItems.length, 16, 'acceptable mediaItem count'); | 269 | module('brightcove playlist', { |
270 | equal(data.mediaSequence, 0, 'MEDIA SEQUENCE is correct'); | 270 | setup: function() { |
271 | equal(data.totalDuration, -1, "ZEN TOTAL DURATION is unknown as expected"); | 271 | m3u8parser = new window.videojs.hls.M3U8Parser(); |
272 | equal(data.hasEndTag, true, 'should have ENDLIST tag'); | 272 | } |
273 | }); | 273 | }); |
274 | 274 | ||
275 | module('brightcove playlist', { | 275 | test('should parse a brightcove manifest data', function() { |
276 | setup: function () { | 276 | var data = m3u8parser.parse(window.brightcove_playlist_data); |
277 | m3u8parser = new window.videojs.hls.M3U8Parser(); | 277 | |
278 | } | 278 | ok(data); |
279 | }); | 279 | equal(data.playlistItems.length, 4, 'Has correct rendition count'); |
280 | 280 | equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct'); | |
281 | test('should parse a brightcove manifest data', function () { | 281 | equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct'); |
282 | var data = m3u8parser.parse(window.brightcove_playlist_data); | 282 | equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct'); |
283 | 283 | equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct'); | |
284 | ok(data); | 284 | |
285 | equal(data.playlistItems.length, 4, 'Has correct rendition count'); | 285 | } |
286 | equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct'); | 286 | ); |
287 | equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct'); | 287 | |
288 | equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct'); | 288 | module('manifest controller', { |
289 | equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct'); | 289 | setup: function() { |
290 | 290 | manifestController = new window.videojs.hls.ManifestController(); | |
291 | } | 291 | this.vjsget = window.videojs.get; |
292 | ); | 292 | window.videojs.get = function(url, success) { |
293 | 293 | success(window.brightcove_playlist_data); | |
294 | module('manifest controller', { | 294 | }; |
295 | setup: function () { | 295 | }, |
296 | manifestController = new window.videojs.hls.ManifestController(); | 296 | teardown: function() { |
297 | this.vjsget = vjs.get; | 297 | window.videojs.get = this.vjsget; |
298 | vjs.get = function (url, success, error) { | 298 | } |
299 | success(window.brightcove_playlist_data); | 299 | }); |
300 | }; | 300 | |
301 | }, | 301 | test('should create', function() { |
302 | teardown: function () { | 302 | ok(manifestController); |
303 | vjs.get = this.vjsget; | 303 | }); |
304 | } | 304 | |
305 | }); | 305 | test('should return a parsed object', function() { |
306 | 306 | var data = manifestController.parseManifest(window.brightcove_playlist_data); | |
307 | test('should create', function () { | 307 | |
308 | ok(manifestController); | 308 | ok(data); |
309 | }); | 309 | equal(data.playlistItems.length, 4, 'Has correct rendition count'); |
310 | 310 | equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct'); | |
311 | test('should return a parsed object', function () { | 311 | equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct'); |
312 | var data = manifestController.parseManifest(window.brightcove_playlist_data); | 312 | equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct'); |
313 | 313 | equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct'); | |
314 | ok(data); | 314 | }); |
315 | equal(data.playlistItems.length, 4, 'Has correct rendition count'); | 315 | |
316 | equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct'); | 316 | test('should get a manifest from hermes', function() { |
317 | equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct'); | 317 | manifestController.loadManifest('http://example.com/16x9-master.m3u8', |
318 | equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct'); | 318 | function(responseData) { |
319 | equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct'); | 319 | ok(responseData); |
320 | }); | 320 | }, |
321 | 321 | function() { | |
322 | test('should get a manifest from hermes', function () { | 322 | ok(false, 'does not error'); |
323 | manifestController.loadManifest('http://example.com/16x9-master.m3u8', | 323 | }, |
324 | function (responseData) { | 324 | function() {}); |
325 | ok(responseData); | 325 | }); |
326 | }, | 326 | |
327 | function (errorData) { | 327 | module('segment controller', { |
328 | ok(false, 'does not error'); | 328 | setup: function() { |
329 | }, | 329 | segmentController = new window.videojs.hls.SegmentController(); |
330 | function (updateData) { | 330 | this.vjsget = window.videojs.get; |
331 | }); | 331 | window.videojs.get = function(url, success) { |
332 | }); | 332 | success(window.bcSegment); |
333 | 333 | }; | |
334 | module('segment controller', { | 334 | }, |
335 | setup: function () { | 335 | teardown: function() { |
336 | segmentController = new window.videojs.hls.SegmentController(); | 336 | window.videojs.get = this.vjsget; |
337 | this.vjsget = vjs.get; | 337 | } |
338 | vjs.get = function (url, success, error) { | 338 | }); |
339 | console.log('load segment url', url); | 339 | |
340 | success(window.bcSegment); | 340 | test('bandwidth calulation test', function() { |
341 | }; | 341 | var |
342 | }, | 342 | multiSecondData = segmentController.calculateThroughput(10000, 1000, 2000), |
343 | teardown: function () { | 343 | subSecondData = segmentController.calculateThroughput(10000, 1000, 1500); |
344 | vjs.get = this.vjsget; | 344 | equal(multiSecondData, 80000, 'MULTI-Second bits per second calculation'); |
345 | } | 345 | equal(subSecondData, 160000, 'SUB-Second bits per second calculation'); |
346 | }); | 346 | }); |
347 | |||
348 | test('bandwidth calulation test', function () { | ||
349 | var | ||
350 | multiSecondData = segmentController.calculateThroughput(10000, 1000, 2000), | ||
351 | subSecondData = segmentController.calculateThroughput(10000, 1000, 1500); | ||
352 | equal(multiSecondData, 80000, 'MULTI-Second bits per second calculation'); | ||
353 | equal(subSecondData, 160000, 'SUB-Second bits per second calculation'); | ||
354 | }); | ||
355 | })(this); | 347 | })(this); | ... | ... |
-
Please register or sign in to post a comment