toms working example base
Showing
7 changed files
with
241 additions
and
130 deletions
... | @@ -25,9 +25,11 @@ | ... | @@ -25,9 +25,11 @@ |
25 | 25 | ||
26 | <!-- m3u8 handling --> | 26 | <!-- m3u8 handling --> |
27 | <script src="src/m3u8/m3u8.js"></script> | 27 | <script src="src/m3u8/m3u8.js"></script> |
28 | <script src="src/m3u8/m3u8-parser.js"></script> | ||
29 | <script src="src/m3u8/m3u8-tag-types.js"></script> | 28 | <script src="src/m3u8/m3u8-tag-types.js"></script> |
29 | <script src="src/m3u8/m3u8-parser.js"></script> | ||
30 | <script src="src/manifest-controller.js"></script> | 30 | <script src="src/manifest-controller.js"></script> |
31 | <script src="src/segment-controller.js"></script> | ||
32 | <script src="src/hls-playback-controller.js"></script> | ||
31 | 33 | ||
32 | <!-- example MPEG2-TS segments --> | 34 | <!-- example MPEG2-TS segments --> |
33 | <!-- bipbop --> | 35 | <!-- bipbop --> |
... | @@ -48,51 +50,12 @@ | ... | @@ -48,51 +50,12 @@ |
48 | 50 | ||
49 | // initialize the player | 51 | // initialize the player |
50 | videojs.options.flash.swf = 'node_modules/videojs-media-sources/video-js-with-mse.swf'; | 52 | videojs.options.flash.swf = 'node_modules/videojs-media-sources/video-js-with-mse.swf'; |
51 | video = videojs('video'); | 53 | video = videojs('video',{},function(){ |
52 | 54 | this.playbackController = new window.videojs.hls.HLSPlaybackController(this); | |
53 | // create a media source | 55 | this.playbackController.loadManifest("http://localhost:7070/test/basic-playback/zencoder/gogo/manifest.m3u8",function(data){console.log(data)}); |
54 | mediaSource = new videojs.MediaSource(); | ||
55 | mediaSource.addEventListener('sourceopen', function(event){ | ||
56 | var | ||
57 | parser = new videojs.hls.SegmentParser(), | ||
58 | sourceBuffer = mediaSource.addSourceBuffer('video/flv; codecs="vp6,aac"'); | ||
59 | everything = []; | ||
60 | |||
61 | // feed parsed bytes into the player | ||
62 | everything.push(parser.getFlvHeader()); | ||
63 | sourceBuffer.appendBuffer(everything[everything.length - 1], video); | ||
64 | |||
65 | parser.parseSegmentBinaryData(window.bcSegment); | ||
66 | |||
67 | while (parser.tagsAvailable()) { | ||
68 | everything.push(parser.getNextTag().bytes); | ||
69 | sourceBuffer.appendBuffer(everything[everything.length - 1], video); | ||
70 | } | ||
71 | parser.flushTags(); | ||
72 | while (parser.tagsAvailable()) { | ||
73 | everything.push(parser.getNextTag().bytes); | ||
74 | sourceBuffer.appendBuffer(everything[everything.length - 1], video); | ||
75 | } | ||
76 | |||
77 | var iframe = document.createElement('iframe'); | ||
78 | iframe.src = 'data:video/x-flv;base64,' + window.btoa((Array.prototype.map.call(everything.reduce(function(result, next) { | ||
79 | var array = new Uint8Array(result.byteLength + next.byteLength); | ||
80 | array.set(result); | ||
81 | array.set(next, result.length); | ||
82 | return array; | ||
83 | }), function(byte) { | ||
84 | return String.fromCharCode(byte); | ||
85 | })).join('')); | ||
86 | //console.log(iframe); | ||
87 | // document.body.appendChild(iframe); | ||
88 | }, false); | ||
89 | |||
90 | url = videojs.URL.createObjectURL(mediaSource); | ||
91 | |||
92 | video.src({ | ||
93 | src: url, | ||
94 | type: "video/flv" | ||
95 | }); | 56 | }); |
96 | </script> | 57 | </script> |
58 | |||
59 | |||
97 | </body> | 60 | </body> |
98 | </html> | 61 | </html> | ... | ... |
src/hls-playback-controller.js
0 → 100644
1 | (function (window) { | ||
2 | window.videojs.hls.HLSPlaybackController = function (vjsPlayerReference) { | ||
3 | var ManifestController = window.videojs.hls.ManifestController; | ||
4 | var SegmentController = window.videojs.hls.SegmentController; | ||
5 | var MediaSource = window.videojs.MediaSource; | ||
6 | var SegmentParser = window.videojs.hls.SegmentParser; | ||
7 | var M3U8 = window.videojs.hls.M3U8; | ||
8 | |||
9 | var self = this; | ||
10 | |||
11 | self.player = vjsPlayerReference; | ||
12 | self.mediaSource = new MediaSource(); | ||
13 | self.parser = new SegmentParser(); | ||
14 | |||
15 | self.manifestController = null; | ||
16 | self.segmentController = null; | ||
17 | self.manifestLoaded = false; | ||
18 | self.currentSegment = 0; | ||
19 | self.currentManifest = null; | ||
20 | self.currentPlaylist = null; | ||
21 | self.currentRendition = null; | ||
22 | |||
23 | // Register Externall Callbacks | ||
24 | self.manifestLoadCompleteCallback; | ||
25 | |||
26 | self.player.on('timeupdate', function () { | ||
27 | console.log(self.player.currentTime()); | ||
28 | }); | ||
29 | |||
30 | self.player.on('onsrcchange', function () { | ||
31 | console.log('src change', self.player.currentSrc()); | ||
32 | //if src.url.m3u8 -- loadManifest.url | ||
33 | }); | ||
34 | |||
35 | self.rendition = function (rendition) { | ||
36 | self.currentRendition = rendition; | ||
37 | self.loadManifest(self.currentRendition.url, self.onM3U8LoadComplete, self.onM3U8LoadError, self.onM3U8Update); | ||
38 | }; | ||
39 | |||
40 | self.loadManifest = function (manifestUrl, onDataCallback, onErrorCallback, onUpdateCallback) { | ||
41 | self.mediaSource.addEventListener('sourceopen', function (event) { | ||
42 | console.log('source open here'); | ||
43 | // feed parsed bytes into the player | ||
44 | self.sourceBuffer = self.mediaSource.addSourceBuffer('video/flv; codecs="vp6,aac"'); | ||
45 | |||
46 | self.parser = new SegmentParser(); | ||
47 | |||
48 | self.sourceBuffer.appendBuffer(self.parser.getFlvHeader(), video); | ||
49 | |||
50 | if( onDataCallback ) | ||
51 | { | ||
52 | self.manifestLoadCompleteCallback = onDataCallback; | ||
53 | } | ||
54 | |||
55 | self.manifestController = new ManifestController(); | ||
56 | self.manifestController.loadManifest(manifestUrl, self.onM3U8LoadComplete, self.onM3U8LoadError, self.onM3U8Update); | ||
57 | |||
58 | }, false); | ||
59 | |||
60 | self.player.src({ | ||
61 | src: videojs.URL.createObjectURL(self.mediaSource), | ||
62 | type: "video/flv" | ||
63 | }); | ||
64 | }; | ||
65 | |||
66 | self.onM3U8LoadComplete = function (m3u8) { | ||
67 | if (m3u8.invalidReasons.length == 0) { | ||
68 | if(m3u8.isPlaylist) | ||
69 | { | ||
70 | self.currentPlaylist = m3u8; | ||
71 | self.rendition(self.currentPlaylist.playlistItems[0]); | ||
72 | } else { | ||
73 | self.currentManifest = m3u8; | ||
74 | self.manifestLoaded = true; | ||
75 | |||
76 | self.loadSegment(self.currentManifest.mediaItems[0]); | ||
77 | |||
78 | if(self.manifestLoadCompleteCallback) | ||
79 | { | ||
80 | self.manifestLoadCompleteCallback(m3u8); | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 | }; | ||
85 | |||
86 | self.onM3U8LoadError = function (error) { | ||
87 | |||
88 | }; | ||
89 | |||
90 | self.onM3U8Update = function (m3u8) { | ||
91 | |||
92 | }; | ||
93 | |||
94 | self.loadSegment = function(segment) { | ||
95 | self.segmentController = new SegmentController(); | ||
96 | self.segmentController.loadSegment(segment.url, self.onSegmentLoadComplete, self.onSegmentLoadError); | ||
97 | |||
98 | }; | ||
99 | |||
100 | self.onSegmentLoadComplete = function (segment) { | ||
101 | self.parser.parseSegmentBinaryData(segment.binaryData); | ||
102 | |||
103 | while (self.parser.tagsAvailable()) { | ||
104 | self.sourceBuffer.appendBuffer(self.parser.getNextTag().bytes, self.player); | ||
105 | }; | ||
106 | |||
107 | console.log('load another',self.currentSegment,self.currentManifest.mediaItems.length); | ||
108 | |||
109 | if(self.currentSegment < self.currentManifest.mediaItems.length-1) | ||
110 | { | ||
111 | console.log('load another'); | ||
112 | self.loadNextSegment(); | ||
113 | } | ||
114 | }; | ||
115 | |||
116 | self.loadNextSegment = function () { | ||
117 | self.currentSegment++; | ||
118 | self.loadSegment(self.currentManifest.mediaItems[self.currentSegment]); | ||
119 | } | ||
120 | |||
121 | self.onSegmentLoadError = function (error) { | ||
122 | |||
123 | }; | ||
124 | |||
125 | }; | ||
126 | })(this); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -4,6 +4,8 @@ | ... | @@ -4,6 +4,8 @@ |
4 | window.videojs.hls.M3U8Parser = function() { | 4 | window.videojs.hls.M3U8Parser = function() { |
5 | 5 | ||
6 | var self = this; | 6 | var self = this; |
7 | self.directory; | ||
8 | |||
7 | var tagTypes = window.videojs.hls.m3u8TagType; | 9 | var tagTypes = window.videojs.hls.m3u8TagType; |
8 | var lines = []; | 10 | var lines = []; |
9 | var data; | 11 | var data; |
... | @@ -31,6 +33,11 @@ | ... | @@ -31,6 +33,11 @@ |
31 | self.parse = function( rawDataString ) { | 33 | self.parse = function( rawDataString ) { |
32 | data = new M3U8(); | 34 | data = new M3U8(); |
33 | 35 | ||
36 | if(self.directory) | ||
37 | { | ||
38 | data.directory = self.directory; | ||
39 | } | ||
40 | |||
34 | if( rawDataString != undefined && rawDataString.toString().length > 0 ) | 41 | if( rawDataString != undefined && rawDataString.toString().length > 0 ) |
35 | { | 42 | { |
36 | lines = rawDataString.split('\n'); | 43 | lines = rawDataString.split('\n'); |
... | @@ -72,6 +79,15 @@ | ... | @@ -72,6 +79,15 @@ |
72 | segment.url = lines[index+1]; | 79 | segment.url = lines[index+1]; |
73 | } | 80 | } |
74 | 81 | ||
82 | if(segment.url.indexOf("http")===-1 && self.directory) | ||
83 | { | ||
84 | if(data.directory[data.directory.length-1] === segment.url[0] && segment.url[0] === "/") | ||
85 | { | ||
86 | segment.url = segment.url.substr(1); | ||
87 | } | ||
88 | segment.url = self.directory + segment.url; | ||
89 | } | ||
90 | |||
75 | data.mediaItems.push(segment); | 91 | data.mediaItems.push(segment); |
76 | 92 | ||
77 | break; | 93 | break; |
... | @@ -116,7 +132,7 @@ | ... | @@ -116,7 +132,7 @@ |
116 | break; | 132 | break; |
117 | 133 | ||
118 | case tagTypes.ZEN_TOTAL_DURATION: | 134 | case tagTypes.ZEN_TOTAL_DURATION: |
119 | data.totalDuration = self.getTagValue(value); | 135 | data.totalDuration = Number(self.getTagValue(value)); |
120 | break; | 136 | break; |
121 | 137 | ||
122 | case tagTypes.VERSION: | 138 | case tagTypes.VERSION: | ... | ... |
1 | (function(window) { | 1 | (function(window) { |
2 | window.videojs.hls.M3U8 = function() { | 2 | window.videojs.hls.M3U8 = function() { |
3 | this.directory = ""; | ||
3 | this.allowCache = "NO"; | 4 | this.allowCache = "NO"; |
4 | this.playlistItems = []; | 5 | this.playlistItems = []; |
5 | this.mediaItems = []; | 6 | this.mediaItems = []; | ... | ... |
1 | (function(window) { | 1 | (function (window) { |
2 | var M3U8 = window.videojs.hls.M3U8; | 2 | var M3U8 = window.videojs.hls.M3U8; |
3 | var M3U8Parser = window.videojs.hls.M3U8Parser; | 3 | var M3U8Parser = window.videojs.hls.M3U8Parser; |
4 | 4 | ||
5 | window.videojs.hls.ManifestController = function(){ | 5 | window.videojs.hls.ManifestController = function () { |
6 | |||
7 | var self = this; | 6 | var self = this; |
8 | var parser; | ||
9 | var data; | ||
10 | 7 | ||
11 | var onDataCallback; | 8 | self.parser; |
12 | var onErrorCallback; | 9 | self.data; |
13 | var onUpdateCallback; | 10 | self.url; |
11 | |||
12 | self.onDataCallback; | ||
13 | self.onErrorCallback; | ||
14 | self.onUpdateCallback; | ||
15 | |||
16 | self.loadManifest = function (manifestUrl, onDataCallback, onErrorCallback, onUpdateCallback) { | ||
17 | self.url = manifestUrl; | ||
14 | 18 | ||
15 | self.loadManifest = function ( manifestUrl, onDataCallback, onErrorCallback, onUpdateCallback ) { | 19 | if (onDataCallback) { |
16 | self.onDataCallback = onDataCallback; | 20 | self.onDataCallback = onDataCallback; |
21 | } | ||
22 | if (onErrorCallback) { | ||
17 | self.onErrorCallback = onErrorCallback; | 23 | self.onErrorCallback = onErrorCallback; |
24 | } | ||
25 | |||
26 | if (onUpdateCallback) { | ||
18 | self.onUpdateCallback = onUpdateCallback; | 27 | self.onUpdateCallback = onUpdateCallback; |
28 | } | ||
19 | 29 | ||
20 | vjs.get(manifestUrl, self.onManifestLoadComplete, self.onManifestLoadError); | 30 | vjs.get(manifestUrl, self.onManifestLoadComplete, self.onManifestLoadError); |
21 | }; | 31 | }; |
22 | 32 | ||
23 | self.parseManifest = function ( dataAsString ) { | 33 | self.parseManifest = function (dataAsString) { |
24 | self.parser = new M3U8Parser(); | 34 | self.parser = new M3U8Parser(); |
25 | self.data = self.parser.parse( dataAsString ); | 35 | self.parser.directory = /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/.exec(self.url).slice(1)[1]; |
36 | self.data = self.parser.parse(dataAsString); | ||
26 | 37 | ||
27 | return self.data; | 38 | return self.data; |
28 | }; | 39 | }; |
29 | 40 | ||
30 | self.onManifestLoadComplete = function(response) { | 41 | self.onManifestLoadComplete = function (response) { |
31 | var output = self.parseManifest(response); | 42 | var output = self.parseManifest(response); |
32 | 43 | ||
33 | if(self.onDataCallback != undefined) | 44 | if (self.onDataCallback != undefined) { |
34 | { | ||
35 | self.onDataCallback(output); | 45 | self.onDataCallback(output); |
36 | } | 46 | } |
37 | }; | 47 | }; |
38 | 48 | ||
39 | self.onManifestLoadError = function(err) { | 49 | self.onManifestLoadError = function (err) { |
40 | if(err) | 50 | if (self.onErrorCallback != undefined) { |
41 | { | 51 | self.onErrorCallback((err != undefined) ? err : null); |
42 | console.log(err.message); | ||
43 | } | ||
44 | |||
45 | if(self.onErrorCallback != undefined) | ||
46 | { | ||
47 | onErrorCallback((err != undefined) ? err : null); | ||
48 | } | 52 | } |
49 | }; | 53 | }; |
50 | } | 54 | } | ... | ... |
1 | (function(window) { | 1 | (function(window) { |
2 | 2 | ||
3 | var SegmentParser = window.videojs.hls.SegmentParser; | ||
4 | |||
5 | window.videojs.hls.SegmentController = function(){ | 3 | window.videojs.hls.SegmentController = function(){ |
6 | 4 | ||
7 | var self = this; | 5 | var self = this; |
8 | var url; | ||
9 | var parser; | ||
10 | var requestTimestamp; | ||
11 | var responseTimestamp; | ||
12 | var data; | ||
13 | 6 | ||
14 | var onDataCallback; | 7 | self.url; |
15 | var onErrorCallback; | 8 | |
16 | var onUpdateCallback; | 9 | self.requestTimestamp; |
10 | self.responseTimestamp; | ||
11 | self.data; | ||
12 | |||
13 | self.onDataCallback; | ||
14 | self.onErrorCallback; | ||
15 | self.onUpdateCallback; | ||
17 | 16 | ||
18 | self.loadSegment = function ( segmentUrl, onDataCallback, onErrorCallback, onUpdateCallback ) { | 17 | self.loadSegment = function ( segmentUrl, onDataCallback, onErrorCallback, onUpdateCallback ) { |
19 | self.url = segmentUrl; | 18 | self.url = segmentUrl; |
... | @@ -30,21 +29,23 @@ | ... | @@ -30,21 +29,23 @@ |
30 | }; | 29 | }; |
31 | 30 | ||
32 | req.send(null); | 31 | req.send(null); |
32 | |||
33 | //vjs.get(segmentUrl, self.onSegmentLoadComplete, self.onSegmentLoadError); | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | self.parseSegment = function ( incomingData ) { | 36 | self.parseSegment = function ( incomingData ) { |
36 | // Add David's code later // | 37 | // Add David's code later // |
38 | console.log('got segment data', incomingData.byteLength); | ||
37 | 39 | ||
38 | self.data = { | 40 | self.data = {}; |
39 | whatever: incomingData | 41 | self.data.binaryData = incomingData; |
40 | }; | ||
41 | self.data.url = self.url; | 42 | self.data.url = self.url; |
42 | self.data.isCached = false; | 43 | self.data.isCached = false; |
43 | self.data.requestTimestamp = self.requestTimestamp; | 44 | self.data.requestTimestamp = self.requestTimestamp; |
44 | self.data.responseTimestamp = self.responseTimestamp; | 45 | self.data.responseTimestamp = self.responseTimestamp; |
45 | self.data.byteLength = incomingData.byteLength; | 46 | self.data.byteLength = incomingData.byteLength; |
46 | self.data.isCached = ( parseInt(self.responseTimestamp - self.requestTimestamp) < 75 ); | 47 | self.data.isCached = ( parseInt(self.responseTimestamp - self.requestTimestamp) < 75 ); |
47 | self.data.throughput = self.calculateThroughput(self.data.byteLength, self.requestTimestamp ,self.responseTimestamp) | 48 | self.data.throughput = self.calculateThroughput(self.data.byteLength, self.requestTimestamp ,self.responseTimestamp); |
48 | 49 | ||
49 | return self.data; | 50 | return self.data; |
50 | }; | 51 | }; | ... | ... |
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/ |
... | @@ -38,18 +38,18 @@ | ... | @@ -38,18 +38,18 @@ |
38 | 38 | ||
39 | module('environment'); | 39 | module('environment'); |
40 | 40 | ||
41 | test('is sane', function() { | 41 | test('is sane', function () { |
42 | expect(1); | 42 | expect(1); |
43 | ok(true); | 43 | ok(true); |
44 | }); | 44 | }); |
45 | 45 | ||
46 | module('segment parser', { | 46 | module('segment parser', { |
47 | setup: function() { | 47 | setup: function () { |
48 | parser = new window.videojs.hls.SegmentParser(); | 48 | parser = new window.videojs.hls.SegmentParser(); |
49 | } | 49 | } |
50 | }); | 50 | }); |
51 | 51 | ||
52 | test('creates an flv header', function() { | 52 | test('creates an flv header', function () { |
53 | var header = Array.prototype.slice.call(parser.getFlvHeader()); | 53 | var header = Array.prototype.slice.call(parser.getFlvHeader()); |
54 | ok(header, 'the header is truthy'); | 54 | ok(header, 'the header is truthy'); |
55 | equal(9 + 4, header.length, 'the header length is correct'); | 55 | equal(9 + 4, header.length, 'the header length is correct'); |
... | @@ -60,7 +60,7 @@ | ... | @@ -60,7 +60,7 @@ |
60 | deepEqual(expectedHeader, header, 'the rest of the header is correct'); | 60 | deepEqual(expectedHeader, header, 'the rest of the header is correct'); |
61 | }); | 61 | }); |
62 | 62 | ||
63 | test('parses the first bipbop segment', function() { | 63 | test('parses the first bipbop segment', function () { |
64 | var tag, bytes, i; | 64 | var tag, bytes, i; |
65 | parser.parseSegmentBinaryData(window.bcSegment); | 65 | parser.parseSegmentBinaryData(window.bcSegment); |
66 | 66 | ||
... | @@ -70,7 +70,7 @@ | ... | @@ -70,7 +70,7 @@ |
70 | 'aac tags:', parser.stats.aacTags()); | 70 | 'aac tags:', parser.stats.aacTags()); |
71 | }); | 71 | }); |
72 | 72 | ||
73 | testAudioTag = function(tag) { | 73 | testAudioTag = function (tag) { |
74 | var | 74 | var |
75 | byte = tag.bytes[11], | 75 | byte = tag.bytes[11], |
76 | format = (byte & 0xF0) >>> 4, | 76 | format = (byte & 0xF0) >>> 4, |
... | @@ -87,7 +87,7 @@ | ... | @@ -87,7 +87,7 @@ |
87 | ok(aacPacketType === 0 || aacPacketType === 1, 'aac packets should have a valid type'); | 87 | ok(aacPacketType === 0 || aacPacketType === 1, 'aac packets should have a valid type'); |
88 | }; | 88 | }; |
89 | 89 | ||
90 | testVideoTag = function(tag) { | 90 | testVideoTag = function (tag) { |
91 | var | 91 | var |
92 | byte = tag.bytes[11], | 92 | byte = tag.bytes[11], |
93 | frameType = (byte & 0xF0) >>> 4, | 93 | frameType = (byte & 0xF0) >>> 4, |
... | @@ -120,7 +120,7 @@ | ... | @@ -120,7 +120,7 @@ |
120 | } | 120 | } |
121 | }; | 121 | }; |
122 | 122 | ||
123 | testNalUnit = function(bytes) { | 123 | testNalUnit = function (bytes) { |
124 | var | 124 | var |
125 | nalHeader = bytes[0], | 125 | nalHeader = bytes[0], |
126 | unitType = nalHeader & 0x1F; | 126 | unitType = nalHeader & 0x1F; |
... | @@ -132,7 +132,7 @@ | ... | @@ -132,7 +132,7 @@ |
132 | }; | 132 | }; |
133 | 133 | ||
134 | 134 | ||
135 | asciiFromBytes = function(bytes) { | 135 | asciiFromBytes = function (bytes) { |
136 | var | 136 | var |
137 | string = [], | 137 | string = [], |
138 | i = bytes.byteLength; | 138 | i = bytes.byteLength; |
... | @@ -143,7 +143,7 @@ | ... | @@ -143,7 +143,7 @@ |
143 | return string.join(''); | 143 | return string.join(''); |
144 | }; | 144 | }; |
145 | 145 | ||
146 | testScriptString = function(tag, offset, expected) { | 146 | testScriptString = function (tag, offset, expected) { |
147 | var type = tag.bytes[offset], | 147 | var type = tag.bytes[offset], |
148 | stringLength = tag.view.getUint16(offset + 1), | 148 | stringLength = tag.view.getUint16(offset + 1), |
149 | string, | 149 | string, |
... | @@ -156,7 +156,7 @@ | ... | @@ -156,7 +156,7 @@ |
156 | equal(expected, string, 'the string value is "' + expected + '"'); | 156 | equal(expected, string, 'the string value is "' + expected + '"'); |
157 | }; | 157 | }; |
158 | 158 | ||
159 | testScriptEcmaArray = function(tag, start) { | 159 | testScriptEcmaArray = function (tag, start) { |
160 | var | 160 | var |
161 | numItems = tag.view.getUint32(start), | 161 | numItems = tag.view.getUint32(start), |
162 | i = numItems, | 162 | i = numItems, |
... | @@ -190,7 +190,7 @@ | ... | @@ -190,7 +190,7 @@ |
190 | equal(tag.bytes[offset + 2], 9, 'the property array terminator is valid'); | 190 | equal(tag.bytes[offset + 2], 9, 'the property array terminator is valid'); |
191 | }; | 191 | }; |
192 | 192 | ||
193 | testScriptTag = function(tag) { | 193 | testScriptTag = function (tag) { |
194 | testScriptString(tag, 11, 'onMetaData'); | 194 | testScriptString(tag, 11, 'onMetaData'); |
195 | 195 | ||
196 | // the onMetaData object is stored as an 'ecma array', an array with non- | 196 | // the onMetaData object is stored as an 'ecma array', an array with non- |
... | @@ -199,7 +199,7 @@ | ... | @@ -199,7 +199,7 @@ |
199 | testScriptEcmaArray(tag, 25); | 199 | testScriptEcmaArray(tag, 25); |
200 | }; | 200 | }; |
201 | 201 | ||
202 | test('the flv tags are well-formed', function() { | 202 | test('the flv tags are well-formed', function () { |
203 | var | 203 | var |
204 | tag, | 204 | tag, |
205 | byte, | 205 | byte, |
... | @@ -241,27 +241,27 @@ | ... | @@ -241,27 +241,27 @@ |
241 | */ | 241 | */ |
242 | 242 | ||
243 | module('m3u8 parser', { | 243 | module('m3u8 parser', { |
244 | setup: function() { | 244 | setup: function () { |
245 | m3u8parser = new window.videojs.hls.M3U8Parser(); | 245 | m3u8parser = new window.videojs.hls.M3U8Parser(); |
246 | } | 246 | } |
247 | }); | 247 | }); |
248 | 248 | ||
249 | test('should create my parser', function() { | 249 | test('should create my parser', function () { |
250 | ok(m3u8parser != undefined); | 250 | ok(m3u8parser != undefined); |
251 | } | 251 | } |
252 | ); | 252 | ); |
253 | 253 | ||
254 | test('should successfully parse manifest data', function() { | 254 | test('should successfully parse manifest data', function () { |
255 | var parsedData = m3u8parser.parse(window.playlistData); | 255 | var parsedData = m3u8parser.parse(window.playlistData); |
256 | ok(parsedData); | 256 | ok(parsedData); |
257 | } | 257 | } |
258 | ); | 258 | ); |
259 | 259 | ||
260 | test('test for expected results', function() { | 260 | test('test for expected results', function () { |
261 | var data = m3u8parser.parse(window.playlistData); | 261 | var data = m3u8parser.parse(window.playlistData); |
262 | 262 | ||
263 | notEqual(data, null, 'data is not NULL'); | 263 | notEqual(data, null, 'data is not NULL'); |
264 | equal(data.invalidReasons.length, 0,'data has 0 invalid reasons'); | 264 | equal(data.invalidReasons.length, 0, 'data has 0 invalid reasons'); |
265 | equal(data.hasValidM3UTag, true, 'data has valid EXTM3U'); | 265 | equal(data.hasValidM3UTag, true, 'data has valid EXTM3U'); |
266 | equal(data.targetDuration, 10, 'data has correct TARGET DURATION'); | 266 | equal(data.targetDuration, 10, 'data has correct TARGET DURATION'); |
267 | equal(data.allowCache, "NO", 'acceptable ALLOW CACHE'); | 267 | equal(data.allowCache, "NO", 'acceptable ALLOW CACHE'); |
... | @@ -275,109 +275,109 @@ | ... | @@ -275,109 +275,109 @@ |
275 | ); | 275 | ); |
276 | 276 | ||
277 | module('brightcove playlist', { | 277 | module('brightcove playlist', { |
278 | setup: function() { | 278 | setup: function () { |
279 | m3u8parser = new window.videojs.hls.M3U8Parser(); | 279 | m3u8parser = new window.videojs.hls.M3U8Parser(); |
280 | } | 280 | } |
281 | }); | 281 | }); |
282 | 282 | ||
283 | test('should parse a brightcove manifest data', function() { | 283 | test('should parse a brightcove manifest data', function () { |
284 | var data = m3u8parser.parse(window.brightcove_playlist_data); | 284 | var data = m3u8parser.parse(window.brightcove_playlist_data); |
285 | 285 | ||
286 | ok(data); | 286 | ok(data); |
287 | equal(data.playlistItems.length, 4, 'Has correct rendition count'); | 287 | equal(data.playlistItems.length, 4, 'Has correct rendition count'); |
288 | equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct' ); | 288 | equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct'); |
289 | equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct' ); | 289 | equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct'); |
290 | equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct' ); | 290 | equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct'); |
291 | equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct' ); | 291 | equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct'); |
292 | 292 | ||
293 | } | 293 | } |
294 | ); | 294 | ); |
295 | 295 | ||
296 | module('manifest controller', { | 296 | module('manifest controller', { |
297 | setup: function() { | 297 | setup: function () { |
298 | manifestController = new window.videojs.hls.ManifestController(); | 298 | manifestController = new window.videojs.hls.ManifestController(); |
299 | this.vjsget = vjs.get; | 299 | this.vjsget = vjs.get; |
300 | vjs.get = function(url, success, error){ | 300 | vjs.get = function (url, success, error) { |
301 | console.log(url); | 301 | console.log(url); |
302 | success(window.brightcove_playlist_data); | 302 | success(window.brightcove_playlist_data); |
303 | }; | 303 | }; |
304 | }, | 304 | }, |
305 | teardown: function() { | 305 | teardown: function () { |
306 | vjs.get = this.vjsget; | 306 | vjs.get = this.vjsget; |
307 | } | 307 | } |
308 | }); | 308 | }); |
309 | 309 | ||
310 | test('should create', function() { | 310 | test('should create', function () { |
311 | ok(manifestController); | 311 | ok(manifestController); |
312 | }); | 312 | }); |
313 | 313 | ||
314 | test('should return a parsed object', function() { | 314 | test('should return a parsed object', function () { |
315 | var data = manifestController.parseManifest(window.brightcove_playlist_data); | 315 | var data = manifestController.parseManifest(window.brightcove_playlist_data); |
316 | 316 | ||
317 | ok(data); | 317 | ok(data); |
318 | 318 | ||
319 | equal(data.playlistItems.length, 4, 'Has correct rendition count'); | 319 | equal(data.playlistItems.length, 4, 'Has correct rendition count'); |
320 | equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct' ); | 320 | equal(data.playlistItems[0].bandwidth, 240000, 'First rendition index bandwidth is correct'); |
321 | equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct' ); | 321 | equal(data.playlistItems[0]["program-id"], 1, 'First rendition index program-id is correct'); |
322 | equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct' ); | 322 | equal(data.playlistItems[0].resolution.width, 396, 'First rendition index resolution width is correct'); |
323 | equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct' ); | 323 | equal(data.playlistItems[0].resolution.height, 224, 'First rendition index resolution height is correct'); |
324 | }) | 324 | }) |
325 | 325 | ||
326 | test('should get a manifest from hermes', function() { | 326 | test('should get a manifest from hermes', function () { |
327 | var hermesUrl = "http://localhost:7070/test/basic-playback/brightcove/16x9-master.m3u8"; | 327 | var hermesUrl = "http://localhost:7070/test/basic-playback/brightcove/16x9-master.m3u8"; |
328 | 328 | ||
329 | manifestController.loadManifest( | 329 | manifestController.loadManifest( |
330 | hermesUrl, | 330 | hermesUrl, |
331 | function(responseData){ | 331 | function (responseData) { |
332 | ok(true); | 332 | ok(true); |
333 | }, | 333 | }, |
334 | function(errorData){ | 334 | function (errorData) { |
335 | console.log('got error data'); | 335 | console.log('got error data'); |
336 | }, | 336 | }, |
337 | function(updateData){ | 337 | function (updateData) { |
338 | console.log('got update data'); | 338 | console.log('got update data'); |
339 | } | 339 | } |
340 | ) | 340 | ) |
341 | }); | 341 | }); |
342 | 342 | ||
343 | module('segment controller', { | 343 | module('segment controller', { |
344 | setup: function() { | 344 | setup: function () { |
345 | segmentController = new window.videojs.hls.SegmentController(); | 345 | segmentController = new window.videojs.hls.SegmentController(); |
346 | this.vjsget = vjs.get; | 346 | this.vjsget = vjs.get; |
347 | vjs.get = function(url, success, error){ | 347 | vjs.get = function (url, success, error) { |
348 | console.log('load segment url', url); | 348 | console.log('load segment url', url); |
349 | success(window.bcSegment); | 349 | success(window.bcSegment); |
350 | }; | 350 | }; |
351 | }, | 351 | }, |
352 | teardown: function() { | 352 | teardown: function () { |
353 | vjs.get = this.vjsget; | 353 | vjs.get = this.vjsget; |
354 | } | 354 | } |
355 | }); | 355 | }); |
356 | 356 | ||
357 | test('should get a segment data', function() { | 357 | test('should get a segment data', function () { |
358 | ok(true); | 358 | ok(true); |
359 | var hermesUrl = "http://localhost:7070/test/ts-files/brightcove/s-1.ts"; | 359 | var hermesUrl = "http://localhost:7070/test/ts-files/brightcove/s-1.ts"; |
360 | 360 | ||
361 | segmentController.loadSegment( | 361 | segmentController.loadSegment( |
362 | hermesUrl, | 362 | hermesUrl, |
363 | function(responseData){ | 363 | function (responseData) { |
364 | console.log('got response from segment controller'); | 364 | console.log('got response from segment controller'); |
365 | ok(true); | 365 | ok(true); |
366 | 366 | ||
367 | }, | 367 | }, |
368 | function(errorData){ | 368 | function (errorData) { |
369 | console.log('got error data'); | 369 | console.log('got error data'); |
370 | }, | 370 | }, |
371 | function(updateData){ | 371 | function (updateData) { |
372 | console.log('got update data'); | 372 | console.log('got update data'); |
373 | } | 373 | } |
374 | ) | 374 | ) |
375 | } | 375 | } |
376 | ) | 376 | ) |
377 | 377 | ||
378 | test('bandwidth calulation test', function() { | 378 | test('bandwidth calulation test', function () { |
379 | var multiSecondData = segmentController.calculateThroughput(10000,1000,2000); | 379 | var multiSecondData = segmentController.calculateThroughput(10000, 1000, 2000); |
380 | var subSecondData = segmentController.calculateThroughput(10000,1000,1500); | 380 | var subSecondData = segmentController.calculateThroughput(10000, 1000, 1500); |
381 | equal(multiSecondData, 80000, 'MULTI-Second bits per second calculation'); | 381 | equal(multiSecondData, 80000, 'MULTI-Second bits per second calculation'); |
382 | equal(subSecondData, 160000, 'SUB-Second bits per second calculation'); | 382 | equal(subSecondData, 160000, 'SUB-Second bits per second calculation'); |
383 | 383 | ... | ... |
-
Please register or sign in to post a comment