Compare commits

...

4 Commits

Author SHA1 Message Date
3979d358d0 ignore npm tempfiles 2024-11-11 02:37:07 +01:00
422446c914 add minify configfile 2024-11-11 02:36:39 +01:00
bbb3d86e16 use minify 2024-11-11 02:36:26 +01:00
996dfb4029 various linter-related changes to formatting 2024-11-11 02:36:06 +01:00
5 changed files with 424 additions and 370 deletions

2
.gitignore vendored
View File

@ -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
View File

@ -0,0 +1,8 @@
{
"js": {
"type": "terser",
"terser": {
"mangle": false
}
}
}

18
package.json Normal file
View 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"
}
}

View File

@ -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

View File

@ -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 &lt;audio&gt; 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;
} }
}; };