eda08662 by Tom Johnson Committed by David LaPalomento

toms working example base

1 parent 3b271282
1 <!DOCTYPE html> 1 <!DOCTYPE html>
2 <html> 2 <html>
3 <head> 3 <head>
4 <meta charset="utf-8"> 4 <meta charset="utf-8">
5 <title>video.js HLS Plugin Example</title> 5 <title>video.js HLS Plugin Example</title>
6 6
7 <link href="node_modules/video.js/video-js.css" rel="stylesheet"> 7 <link href="node_modules/video.js/video-js.css" rel="stylesheet">
8 8
...@@ -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>
......
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;
17 self.onErrorCallback = onErrorCallback; 21 }
18 self.onUpdateCallback = onUpdateCallback; 22 if (onErrorCallback) {
23 self.onErrorCallback = onErrorCallback;
24 }
25
26 if (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;
...@@ -22,29 +21,31 @@ ...@@ -22,29 +21,31 @@
22 self.onUpdateCallback = onUpdateCallback; 21 self.onUpdateCallback = onUpdateCallback;
23 self.requestTimestamp = new Date().getTime(); 22 self.requestTimestamp = new Date().getTime();
24 23
25 var req = new XMLHttpRequest(); 24 var req = new XMLHttpRequest();
26 req.open('GET', segmentUrl, true); 25 req.open('GET', segmentUrl, true);
27 req.responseType = 'arraybuffer'; 26 req.responseType = 'arraybuffer';
28 req.onload = function(response) { 27 req.onload = function(response) {
29 self.onSegmentLoadComplete(new Uint8Array(req.response)); 28 self.onSegmentLoadComplete(new Uint8Array(req.response));
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 };
......