forked from opi/m3uStreamPlayer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathm3uStreamPlayer.js
143 lines (121 loc) · 4.49 KB
/
m3uStreamPlayer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
;(function(root, name, output){
if(typeof define == "function" && define.amd) return define([], output)
if(typeof module == "object" && module.exports) module.exports = output()
else root[name] = output()
})(this.window, "m3uStreamPlayer", function(){
'use strict';
// Defaults
var exports = {
selector: '[data-playlist]',
debug: false
};
// Load playlist, and get sources.
var _getPlaylistSources = function(elem) {
// XHR Request to playlist file
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = process;
xhr.open("GET", elem.getAttribute('data-playlist'), true);
xhr.send();
function process() {
if (xhr.readyState == 4) {
// m3uToUrl From https://github.com/aitorciki/jquery-playlist/blob/master/jquery.playlist.js
elem.sources = xhr.responseText.match(/^(?!#)(?!\s).*$/mg).filter(function(element){return (element);});
if (exports.debug) console.log("Sources: "+elem.sources);
// Load first source
elem.src = elem.sources[0];
// Play first source
if (elem.getAttribute('autoplay')) elem.play();
}
}
}
// Get current source index
var _getSourceIdx = function(elem) {
for(var i = 0; i < elem.sources.length; i++){
if (elem.currentSrc == elem.sources[i]) return i;
}
return 0;
}
// Jump to next source.
var _nextSource = function(elem) {
var sourceIdx = _getSourceIdx(elem);
var nextSourceIdx = (sourceIdx == elem.sources.length -1 ) ? 0 : sourceIdx + 1;
elem.src = elem.sources[nextSourceIdx];
if (exports.debug) console.log("Source updated: "+elem.src);
elem.play();
}
// Randomize source.
var _randomizeSource = function(elem) {
elem.src = elem.sources[Math.floor(Math.random()*elem.sources.length)];
// this.currentTime = 0;
if (exports.debug) console.log("Source randomized: "+elem.src);
elem.play();
}
// Display human readable message in console.
var _errorMessage = function(event) {
switch (event.target.error.code) {
case event.target.error.MEDIA_ERR_ABORTED:
return "The fetching process for the media resource was aborted by the user agent at the user's request.";
case event.target.error.MEDIA_ERR_NETWORK:
return "A network error of some description caused the user agent to stop fetching the media resource, after the resource was established to be usable.";
case event.target.error.MEDIA_ERR_DECODE:
return "An error of some description occurred while decoding the media resource, after the resource was established to be usable.";
case event.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
return "The media resource indicated by the src attribute was not suitable.";
default:
return "An unknown error occurred.";
}
}
// Process element, attach listeners
var _process = function(elem) {
elem.sources = [];
_getPlaylistSources(elem);
// On error, update source, and play again.
elem.addEventListener('error', function(e) {
if (exports.debug) console.log("Error: " + _errorMessage(e));
_nextSource(this);
});
// On end, update source, and play again.
elem.addEventListener('ended', function() {
if (exports.debug) console.log("Ended");
_nextSource(this);
});
// Show current source, debug only.
elem.addEventListener('play', function(e) {
if (exports.debug) console.log("Play: "+this.currentSrc);
});
// Pause event, debug only.
elem.addEventListener('pause', function() {
if (exports.debug) console.log("Pause");
});
}
// Expose nextSource function
exports.nextSource = function(elem) {
_nextSource(elem);
}
// Expose randomizeSource function
exports.randomizeSource = function(elem) {
_randomizeSource(elem);
}
exports.init = function (obj) {
// Allow string to be passed as argument.
if (typeof obj === "string") obj = {selector: obj}
// Mix options with defaults.
for (var key in obj) {
exports[key] = obj[key];
}
// Prevent IE8 from bugging when a calling console.log
if (exports.debug) {
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };
}
// Get nodes, and process them.
var nodes = document.querySelectorAll(exports.selector);
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (node.nodeName === "VIDEO" || node.nodeName === "AUDIO") {
_process(node);
}
}
};
return exports;
});