Compare commits
4 Commits
19c568d27a
...
3979d358d0
Author | SHA1 | Date | |
---|---|---|---|
3979d358d0 | |||
422446c914 | |||
bbb3d86e16 | |||
996dfb4029 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,3 +1,5 @@
|
|||||||
dist/js/*.js
|
dist/js/*.js
|
||||||
dist/css/*.css
|
dist/css/*.css
|
||||||
dist/css/*.svg
|
dist/css/*.svg
|
||||||
|
package-lock.json
|
||||||
|
node_modules
|
||||||
|
8
.minify.json
Normal file
8
.minify.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"js": {
|
||||||
|
"type": "terser",
|
||||||
|
"terser": {
|
||||||
|
"mangle": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
package.json
Normal file
18
package.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "myplayer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "A Web-MP3-Player with Playlist Support",
|
||||||
|
"main": "src/player.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://tk-sls.de/git/tk-sls.de/myplayer.git"
|
||||||
|
},
|
||||||
|
"author": "tilt <tilt@linuxfoo.de>",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"minify": "^11.4.1"
|
||||||
|
}
|
||||||
|
}
|
@ -12,8 +12,8 @@ if ! cd "$dir" ; then
|
|||||||
elif ! mkdir -p "$jsdir" ; then
|
elif ! mkdir -p "$jsdir" ; then
|
||||||
echo "ERROR: Could not create directory $jsdir; aborted." >&2 ;
|
echo "ERROR: Could not create directory $jsdir; aborted." >&2 ;
|
||||||
exit 1 ;
|
exit 1 ;
|
||||||
elif ! type yui-compressor > /dev/null ; then
|
elif ! type minify > /dev/null ; then
|
||||||
echo "ERROR: Executable \"yui-compressor\" not found in PATH; aborted." >&2 ;
|
echo "ERROR: Executable \"minify\" not found in PATH; aborted." >&2 ;
|
||||||
exit 1 ;
|
exit 1 ;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ do
|
|||||||
done
|
done
|
||||||
|
|
||||||
echo "INFO: Compressing player.js ..." >&2
|
echo "INFO: Compressing player.js ..." >&2
|
||||||
yui-compressor player.js >> "$jsdir"/myplayer.min.js
|
minify player.js >> "$jsdir"/myplayer.min.js
|
||||||
|
|
||||||
chmod 644 "$jsdir"/myplayer.min.js
|
chmod 644 "$jsdir"/myplayer.min.js
|
||||||
|
|
||||||
|
224
src/player.js
224
src/player.js
@ -21,26 +21,29 @@
|
|||||||
* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE */
|
* THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE */
|
||||||
|
|
||||||
var MyPlayer = function(_args) {
|
var MyPlayer = function(_args) {
|
||||||
var failed = false;
|
var failed = false,
|
||||||
var detached = false;
|
detached = false,
|
||||||
var player = null;
|
player = null,
|
||||||
|
args_default = {
|
||||||
var defaultArgs = {
|
|
||||||
detachable: true,
|
|
||||||
element: 'body',
|
|
||||||
id3: false,
|
|
||||||
mode: 'mp3url',
|
|
||||||
waveform: false,
|
|
||||||
autoplay: false,
|
autoplay: false,
|
||||||
|
css: { "height": "500px" },
|
||||||
|
detachable: true,
|
||||||
|
element: "body",
|
||||||
|
id3: false,
|
||||||
|
list: [],
|
||||||
loop: true,
|
loop: true,
|
||||||
|
mode: "mp3url",
|
||||||
shuffle: false,
|
shuffle: false,
|
||||||
list: []
|
waveform: false
|
||||||
};
|
},
|
||||||
|
args = (_args===undefined) ? args_default : $.extend({}, args_default, _args),
|
||||||
|
mimeTypeFromSrc = function(src) {
|
||||||
|
var extension = src.split(".").pop().toLowerCase();
|
||||||
|
|
||||||
var mimeTypeFromSrc = function(src) {
|
var types = {
|
||||||
var extension = src.split('.').pop().toLowerCase();
|
"3g2": "video/3gpp2",
|
||||||
|
"3gp": "video/3gpp",
|
||||||
return {
|
"7z": "application/x-7z-compressed",
|
||||||
"aac": "audio/aac",
|
"aac": "audio/aac",
|
||||||
"abw": "application/x-abiword",
|
"abw": "application/x-abiword",
|
||||||
"arc": "application/x-freearc",
|
"arc": "application/x-freearc",
|
||||||
@ -55,11 +58,10 @@ var MyPlayer = function(_args) {
|
|||||||
"css": "text/css",
|
"css": "text/css",
|
||||||
"csv": "text/csv",
|
"csv": "text/csv",
|
||||||
"doc": "application/msword",
|
"doc": "application/msword",
|
||||||
"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
||||||
"eot": "application/vnd.ms-fontobject",
|
"eot": "application/vnd.ms-fontobject",
|
||||||
"epub": "application/epub+zip",
|
"epub": "application/epub+zip",
|
||||||
"gz": "application/gzip",
|
|
||||||
"gif": "image/gif",
|
"gif": "image/gif",
|
||||||
|
"gz": "application/gzip",
|
||||||
"htm": "text/html",
|
"htm": "text/html",
|
||||||
"html": "text/html",
|
"html": "text/html",
|
||||||
"ico": "image/vnd.microsoft.icon",
|
"ico": "image/vnd.microsoft.icon",
|
||||||
@ -85,11 +87,10 @@ var MyPlayer = function(_args) {
|
|||||||
"ogx": "application/ogg",
|
"ogx": "application/ogg",
|
||||||
"opus": "audio/opus",
|
"opus": "audio/opus",
|
||||||
"otf": "font/otf",
|
"otf": "font/otf",
|
||||||
"png": "image/png",
|
|
||||||
"pdf": "application/pdf",
|
"pdf": "application/pdf",
|
||||||
"php": "application/x-httpd-php",
|
"php": "application/x-httpd-php",
|
||||||
|
"png": "image/png",
|
||||||
"ppt": "application/vnd.ms-powerpoint",
|
"ppt": "application/vnd.ms-powerpoint",
|
||||||
"pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
||||||
"rar": "application/vnd.rar",
|
"rar": "application/vnd.rar",
|
||||||
"rtf": "application/rtf",
|
"rtf": "application/rtf",
|
||||||
"sh": "application/x-sh",
|
"sh": "application/x-sh",
|
||||||
@ -110,40 +111,30 @@ var MyPlayer = function(_args) {
|
|||||||
"woff2": "font/woff2",
|
"woff2": "font/woff2",
|
||||||
"xhtml": "application/xhtml+xml",
|
"xhtml": "application/xhtml+xml",
|
||||||
"xls": "application/vnd.ms-excel",
|
"xls": "application/vnd.ms-excel",
|
||||||
"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
||||||
"xml": "application/xml",
|
"xml": "application/xml",
|
||||||
"xul": "application/vnd.mozilla.xul+xml",
|
"xul": "application/vnd.mozilla.xul+xml",
|
||||||
"zip": "application/zip",
|
"zip": "application/zip"
|
||||||
"3gp": "video/3gpp",
|
|
||||||
"3g2": "video/3gpp2",
|
|
||||||
"7z": "application/x-7z-compressed"
|
|
||||||
}[extension] || "application/octet-stream";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var args = (typeof(_args)==='undefined')
|
return types[extension] || "application/octet-stream";
|
||||||
? defaultArgs
|
},
|
||||||
: $.extend({}, defaultArgs, _args);
|
createAudio = function() {
|
||||||
|
|
||||||
var createAudio = function() {
|
|
||||||
var autoplay = args.autoplay ? 'autoplay="true"' : '';
|
var autoplay = args.autoplay ? 'autoplay="true"' : '';
|
||||||
|
var styles = [];
|
||||||
|
var style;
|
||||||
|
var key;
|
||||||
|
|
||||||
$(args.element).append(
|
for (key in args.css) {
|
||||||
'<audio id="myplayer" controls="controls" ' + autoplay + '>'+
|
var value = args.css[key];
|
||||||
'<p>'+
|
styles.push(`${key}: ${value}`);
|
||||||
'Your browser does not understand '+
|
}
|
||||||
'the <audio> tag. '+
|
|
||||||
'</p>'+
|
|
||||||
'</audio>'
|
|
||||||
);
|
|
||||||
|
|
||||||
args.audio = args.element + ' audio';
|
style = styles.join(" ");
|
||||||
|
args.audio = $(`<audio id="myplayer" controls="controls" style="${style}" ${autoplay}></audio>`);
|
||||||
$(args.audio).css({
|
console.log("DEBUG: appending audio=", args.audio, " to element=", args.element, " ...");
|
||||||
'height': '500px',
|
$(args.element).append(args.audio);
|
||||||
});
|
},
|
||||||
};
|
readId3 = function() {
|
||||||
|
|
||||||
var readId3 = function() {
|
|
||||||
$(args.element).find('ul.mejs li').each(function(i, track){
|
$(args.element).find('ul.mejs li').each(function(i, track){
|
||||||
var url = $(track).attr('data-url');
|
var url = $(track).attr('data-url');
|
||||||
|
|
||||||
@ -154,35 +145,57 @@ var MyPlayer = function(_args) {
|
|||||||
var tags = tag.tags;
|
var tags = tag.tags;
|
||||||
var track_title;
|
var track_title;
|
||||||
|
|
||||||
if(typeof(tags.title)!='undefined')
|
if(typeof(tags.title)!='undefined') {
|
||||||
track_title = tags.title;
|
track_title = tags.title;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
track_title = url;
|
track_title = url;
|
||||||
|
}
|
||||||
|
|
||||||
if(typeof(tags.artist)!='undefined')
|
if(typeof(tags.artist)!='undefined') {
|
||||||
track_title = tags.artist + ' - ' + track_title;
|
track_title = tags.artist + ' - ' + track_title;
|
||||||
|
}
|
||||||
|
|
||||||
$(args.element).find('ul.mejs li').each(function(j, _track){
|
$(args.element).find('ul.mejs li').each(function(j, _track){
|
||||||
if(i==j)
|
if(i==j) {
|
||||||
$(_track).html(track_title);
|
$(_track).html(track_title);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
},
|
||||||
|
playerCreated = function(mediaElement, originalNode, instance) {
|
||||||
var playerCreated = function() {
|
|
||||||
restoreParams();
|
restoreParams();
|
||||||
|
|
||||||
if(args.id3)
|
if(args.shuffle) {
|
||||||
readId3();
|
instance.shuffleCallback();
|
||||||
};
|
}
|
||||||
|
|
||||||
var createPlayer = function() {
|
if(args.loop) {
|
||||||
|
instance.loopCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(args.id3) {
|
||||||
|
readId3();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createPlayer = function() {
|
||||||
player = new MediaElementPlayer(
|
player = new MediaElementPlayer(
|
||||||
"myplayer", {
|
"myplayer", {
|
||||||
success: playerCreated,
|
success: playerCreated,
|
||||||
features: ['playpause', 'current', 'progress', 'duration', 'volume', 'playlist', 'prevtrack', 'nexttrack', 'shuffle', 'loop']
|
features: [
|
||||||
|
'playpause',
|
||||||
|
'current',
|
||||||
|
'progress',
|
||||||
|
'duration',
|
||||||
|
'volume',
|
||||||
|
'playlist',
|
||||||
|
'prevtrack',
|
||||||
|
'nexttrack',
|
||||||
|
'shuffle',
|
||||||
|
'loop'
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
$(args.element).append(
|
$(args.element).append(
|
||||||
@ -190,25 +203,25 @@ var MyPlayer = function(_args) {
|
|||||||
'The player is currently detached.'+
|
'The player is currently detached.'+
|
||||||
'</p>'
|
'</p>'
|
||||||
);
|
);
|
||||||
};
|
},
|
||||||
|
param = function(name) {
|
||||||
var param = function(name) {
|
|
||||||
var query = window.location.search.substring(1);
|
var query = window.location.search.substring(1);
|
||||||
var vars = query.split("&");
|
var vars = query.split("&");
|
||||||
|
|
||||||
for(var i=0; i<vars.length; i++) {
|
for(i=0; i<vars.length; i++) {
|
||||||
var pair = vars[i].split("=");
|
var pair = vars[i].split("=");
|
||||||
|
|
||||||
if(pair[0] == name)
|
if(pair[0] == name) {
|
||||||
return pair[1];
|
return pair[1];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
};
|
},
|
||||||
|
setupDetach = function() {
|
||||||
var setupDetach = function() {
|
if(!args.detachable) {
|
||||||
if(!args.detachable)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var popup = function(url) {
|
var popup = function(url) {
|
||||||
player.pause();
|
player.pause();
|
||||||
@ -222,8 +235,9 @@ var MyPlayer = function(_args) {
|
|||||||
'resizable=false'
|
'resizable=false'
|
||||||
);
|
);
|
||||||
|
|
||||||
if(window.focus)
|
if(window.focus) {
|
||||||
playerWindow.focus();
|
playerWindow.focus();
|
||||||
|
}
|
||||||
|
|
||||||
$("iframe",top.document).height(20);
|
$("iframe",top.document).height(20);
|
||||||
|
|
||||||
@ -248,8 +262,9 @@ var MyPlayer = function(_args) {
|
|||||||
var trackNo = 0;
|
var trackNo = 0;
|
||||||
|
|
||||||
$(args.element).find('ul.mejs li').each(function(i){
|
$(args.element).find('ul.mejs li').each(function(i){
|
||||||
if($(this).hasClass('current'))
|
if($(this).hasClass('current')) {
|
||||||
trackNo = i;
|
trackNo = i;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
popup(
|
popup(
|
||||||
@ -271,11 +286,11 @@ var MyPlayer = function(_args) {
|
|||||||
$('.playerDetached', opener.document).hide();
|
$('.playerDetached', opener.document).hide();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
restoreParams = function() {
|
||||||
var restoreParams = function() {
|
if(!detached) {
|
||||||
if(!detached)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var paused = (param('paused') && param('paused')=='true');
|
var paused = (param('paused') && param('paused')=='true');
|
||||||
var currentTime = param('currentTime') ? parseFloat(param('currentTime')) : 0.0;
|
var currentTime = param('currentTime') ? parseFloat(param('currentTime')) : 0.0;
|
||||||
@ -291,8 +306,9 @@ var MyPlayer = function(_args) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(paused)
|
if(paused) {
|
||||||
player.pause();
|
player.pause();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if(param('popup')!==false) {
|
if(param('popup')!==false) {
|
||||||
@ -311,6 +327,7 @@ var MyPlayer = function(_args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(args.mode=='mp3url') {
|
if(args.mode=='mp3url') {
|
||||||
|
console.log("args.mode=", args.mode);
|
||||||
var mp3url = (typeof args.mp3url === "undefined")
|
var mp3url = (typeof args.mp3url === "undefined")
|
||||||
? $(location).attr('href').replace(/\?.*/, '').replace(/\/[^\/]+\/?$/, '')
|
? $(location).attr('href').replace(/\?.*/, '').replace(/\/[^\/]+\/?$/, '')
|
||||||
: args.mp3url;
|
: args.mp3url;
|
||||||
@ -319,12 +336,15 @@ var MyPlayer = function(_args) {
|
|||||||
url: mp3url,
|
url: mp3url,
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
success: function(res) {
|
success: function(res) {
|
||||||
createAudio();
|
var doc;
|
||||||
|
var head;
|
||||||
|
|
||||||
var doc = document.createElement('html');
|
doc = document.createElement('html');
|
||||||
|
|
||||||
|
createAudio();
|
||||||
doc.innerHTML = res;
|
doc.innerHTML = res;
|
||||||
|
|
||||||
var head = $(doc).find('a').each(function(idx,item) {
|
head = $(doc).find('a').each(function(idx,item) {
|
||||||
var src = $(item).attr('href');
|
var src = $(item).attr('href');
|
||||||
|
|
||||||
if(src.match(/\.mp3$/)) {
|
if(src.match(/\.mp3$/)) {
|
||||||
@ -332,7 +352,7 @@ var MyPlayer = function(_args) {
|
|||||||
var title = item.innerHTML;
|
var title = item.innerHTML;
|
||||||
var type = "audio/mpeg";
|
var type = "audio/mpeg";
|
||||||
|
|
||||||
$(args.audio).append('<source src="'+url+'" type="' + type + '" title="'+title+'"/>');
|
args.audio.append(`<source src="${url}" type="${type}" title="${title}"/>`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -350,71 +370,77 @@ var MyPlayer = function(_args) {
|
|||||||
|
|
||||||
$.get(m3u, function(txt){
|
$.get(m3u, function(txt){
|
||||||
var lines = txt.split("\n");
|
var lines = txt.split("\n");
|
||||||
|
var len = lines.length;
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
for(var i = 0, len = lines.length; i < len; i++)
|
while(i < len) {
|
||||||
if(!lines[i].match(/^[ \t]*#/) && lines[i].match(/\.mp3$/)) {
|
if(!lines[i].match(/^[ \t]*#/) && lines[i].match(/\.mp3$/)) {
|
||||||
var mp3 = lines[i];
|
var mp3 = lines[i];
|
||||||
var title = unescape(mp3.split('/').pop());
|
var title = unescape(mp3.split('/').pop());
|
||||||
var type = "audio/mpeg";
|
var type = "audio/mpeg";
|
||||||
|
|
||||||
$(args.audio).append('<source src="'+mp3+'" type="' + type + '" title="'+title+'"/>');
|
args.audio.append(`<source src="${mp3}" type="${type}" title="${title}"/>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("DEBUG: mode==m3u audio=",$(args.audio));
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
createPlayer();
|
createPlayer();
|
||||||
setupDetach();
|
setupDetach();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if(args.mode=='list') {
|
else if(args.mode=='list') {
|
||||||
|
var len = args.list.length;
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
createAudio();
|
createAudio();
|
||||||
|
|
||||||
for(var i = 0, len = args.list.length; i < len; i++) {
|
while(i < len) {
|
||||||
var item = args.list[i];
|
var item = args.list[i];
|
||||||
var type = typeof item;
|
var type = typeof item;
|
||||||
var src = '';
|
var src = '';
|
||||||
var title = '';
|
var title = '';
|
||||||
|
var type;
|
||||||
|
|
||||||
if(item !== null && type === 'object') {
|
if(item !== null && type === 'object') {
|
||||||
if(item.url)
|
if(item.url) {
|
||||||
src = item.url;
|
src = item.url;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
alert(
|
alert(`MyPlayer: item[${i}]: property "url" is missing.`);
|
||||||
'MyPlayer: item[' + i + ']: '+
|
i++;
|
||||||
'property "url" is missing.'
|
|
||||||
);
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(item.title)
|
if(item.title) {
|
||||||
title = item.title;
|
title = item.title;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
title = url.replace(/(.*\/)?([^\/]+)/, '$2');
|
title = url.replace(/(.*\/)?([^\/]+)/, '$2');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if(type === 'string') {
|
else if(type === 'string') {
|
||||||
src = item;
|
src = item;
|
||||||
title = src;
|
title = src;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
alert(
|
alert(`MyPlayer: item[${i}]: unsupported type=${type}.`);
|
||||||
'MyPlayer: item [' + i + ']: '+
|
i++;
|
||||||
'unsupported type "' + type + '"'
|
|
||||||
);
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var type = mimeTypeFromSrc(src);
|
type = mimeTypeFromSrc(src);
|
||||||
|
|
||||||
$(args.audio).append('<source src="'+src+'" type="' + type + '" title="'+title+'"/>');
|
args.audio.append(`<source src="${src}" type="${type}" title="${type}"/>`);
|
||||||
|
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
createPlayer();
|
createPlayer();
|
||||||
setupDetach();
|
setupDetach();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$(args.element).append('<p>Unsupported mode "'+args.mode+'"</p>');
|
$(args.element).append(`<p>Unsupported mode ${args.mode}"</p>`);
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user