NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name Next DCDNet HTML5 Player
// @namespace http://tampermonkey.net/
// @version 0.1
// @description replaces flash audio player with a standard HTML5 audio player
// @author siomi
// @license MIT; https://spdx.org/licenses/MIT.html
// @match http://dcdnet.ru/albums/*
// @match http://www.dcdnet.ru/albums/*
// @require https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.0/howler.min.js
// @grant none
// ==/UserScript==
(function() {
'use strict';
/*Howl.prototype.changeSong = function(o) {
var self = this;
self.unload();
self._duration = 0; // init duration
self._sprite = {};// init sprite
self._src = typeof o.src !== 'string' ? o.src : [o.src];
self._format = typeof o.format !== 'string' ? o.format : [o.format];
self.load(); // => update duration, sprite(var timeout)
};*/
let GM_addStyle = function(css) {
const style = document.getElementById("GM_addStyleByDCD") || (function() {
const style = document.createElement('style');
style.type = 'text/css';
style.id = "GM_addStyleByDCD";
document.head.appendChild(style);
return style;
})();
const sheet = style.sheet;
sheet.insertRule(css, (sheet.rules || sheet.cssRules || []).length);
}
let getOffset = function(el) {
const rect = el.getBoundingClientRect();
return {
left: rect.left + window.scrollX,
top: rect.top + window.scrollY
};
}
let p = document.getElementById("tracks");
let d = document.createElement("div");
d.classList.add("player_main");
d.innerHTML = `<div class="player_main">
<div class="player">
<div class="buttons">
<a class="play_repeat" id="repeat_btn" href="#"><svg class="btn active" viewBox="0 0 32 32"><path d="M29 16 C29 22 24 29 16 29 8 29 3 22 3 16 3 10 8 3 16 3 21 3 25 6 27 9 M20 10 L27 9 28 2"></path></svg></a>
<a class="play_pause" id="play_btn" href="#"><svg class="btn" viewBox="0 0 32 32"><path d="M10 2 L10 30 24 16 Z"></path></svg></a>
<a class="play_pause hidden" id="pause_btn" href="#"><svg class="btn" viewBox="0 0 32 32"><path d="M23 2 L23 30 M9 2 L9 30"></path></svg></a>
</div>
<div class="info">
<div class="track_info">
<span id="info_title"></span>
<span id="info_duration"></span>
</div>
<div class="track_progress" id="info_progressbar">
<div class="track_progress-value" id="info_progress"></div>
</div>
</div>
<div class="volume">
<span class="play_volume"><svg class="btn" viewBox="0 0 32 32"><path d="M20 16 C20 8 15 2 15 2 L8 10 2 10 2 22 8 22 15 30 C15 30 20 24 20 16 Z M21 2 C21 2 25 6 25 16 25 26 21 30 21 30 M27 4 C27 4 30 8 30 16 30 24 27 28 27 28"></path></svg></span>
<div class="track_progress" id="info_volumebar">
<div class="track_progress-value" id="info_volume"><span></span></div>
</div>
</div>
</div>
<div class="playlist">
<div id="playlist_tracks">
</div>
</div>
</div>`;
GM_addStyle('.player_main a,.player_main div{box-sizing:border-box;}');
GM_addStyle('.player_main a,.player_main span{color:#fff;}');
GM_addStyle('.player_main a{text-decoration:none;}');
GM_addStyle('.player_main .hidden{display:none;}');
GM_addStyle('.player_main{display:inline-block;width:100%;max-width:40em;background-color:#76989d}');
GM_addStyle('.player_main .player,.player_main .playlist{display:flex;width:100%;max-width:40em}');
GM_addStyle('.player_main .player{justify-content: space-between;}');
GM_addStyle('.player_main .player .buttons,.player_main .playlist{display:flex}');
GM_addStyle('.player_main .player .info{display:flex;padding:.6em;width:100%;max-width:28em;flex-direction:column}');
GM_addStyle('.player_main .player .info .track_info{display:flex;justify-content:space-between;margin-bottom:.4em}');
GM_addStyle('.player_main #info_title{white-space:nowrap;overflow:hidden}');
GM_addStyle('.player_main .player .volume{display:flex;width:16em;align-items:center;padding:0 1em;flex:0 0 10em}');
GM_addStyle('.player_main .playlist #playlist_tracks{background-color:#e0eaeb;list-style:none;display:flex;width:100%;flex-direction:column;counter-reset:section}');
GM_addStyle('.player_main .playlist .track{display:flex;justify-content:space-around;width:100%;padding:.6em}');
GM_addStyle('.player_main .track_info{display:flex;max-width:40em;width:100%;justify-content:space-between;align-items:left}');
GM_addStyle('.player_main .track_info span.title{width:100%}');
GM_addStyle('.player_main .player_main .track_info span{color:white}');
GM_addStyle('.player_main .playlist .track_info span{color:black}');
GM_addStyle('.player_main .playlist .track.active,.player_main .track:hover{background:rgba(255,255,255,.3);cursor:pointer}');
GM_addStyle('.btn{display:inline-block;fill:none;margin:.6em .4em;font-size:1.2em;width:1.2em;stroke:currentColor;stroke-width:8%;overflow:visible}');
GM_addStyle('.player_main .play_repeat .btn{stroke:rgba(255,255,255,.3)}');
GM_addStyle('.player_main .play_repeat.active .btn{stroke:white}');
GM_addStyle('.player_main .track_progress{background:rgba(255,255,255,.3);justify-content:flex-start;align-items:center;position:relative;display:flex;height:4px;width:100%}');
GM_addStyle('.player_main .track_progress-value{background:#fff;height:4px;width:0%}');
p.append(d);
const tracks = document.querySelectorAll('#track_table tbody tr');
let volume = 1.0;
let repreat = true;
let playlist = [];
for(let i=0;i<tracks.length;i++){
let track = tracks[i];
let num = track.querySelector('td.track.number');
let title = track.querySelector('td:nth-child(3)').innerText;
let time = track.querySelector('td.time.number').innerText;
let link = track.querySelector('object param[name=movie]').value.split('&')[1];
playlist.push({
file: 'http://dcdnet.ru'+link.substring(4, link.length)
,title: title
,length: time
});
}
let tracks_el = document.getElementById("playlist_tracks");
let title_el = document.getElementById("info_title");
let duration_el = document.getElementById("info_duration");
let progressbar_el = document.getElementById("info_progressbar");
let progress_el = document.getElementById("info_progress");
let volumebar_el = document.getElementById("info_volumebar");
let volume_el = document.getElementById("info_volume");
let play_btn = document.getElementById("play_btn");
let pause_btn = document.getElementById("pause_btn");
let repeat_btn = document.getElementById("repeat_btn");
let Player = function (playlist) {
this.playlist = playlist;
this.index = 0;
this.volume = 1.0;
playlist.forEach(function(song) {
let div = document.createElement("div");
div.className = "track";
div.innerHTML = '<div class="track_info"><span class="title">'+song.title+'</span><span class="time">'+song.length+'</span></div>';
div.onclick = function () {
player.skipTo(playlist.indexOf(song));
let current = document.querySelector(".player_main .track.active")
if(current !== null){
current.classList.remove("active");
}
this.classList.add("active");
document.querySelector(".player_main .buttons a.hidden").classList.remove("hidden");
play_btn.classList.add("hidden");
};
tracks_el.appendChild(div);
});
};
Player.prototype = {
play: function (index) {
let self = this;
let sound;
index = typeof index === "number" ? index : self.index;
let data = self.playlist[index];
if (data.howl) {
sound = data.howl;
} else {
sound = data.howl = new Howl({
src: [data.file],
html5: true,
onplay: function () {
duration_el.innerHTML = self.formatTime(Math.round(sound.duration()));
requestAnimationFrame(self.step.bind(self));
},
onload: function () {
},
onend: function () {
self.skip("next");
},
onpause: function () {
},
onstop: function () {
},
onseek: function() {
requestAnimationFrame(self.step.bind(self));
}
});
}
sound.play();
title_el.innerHTML = data.title;
if (sound.state() === "loaded") {
} else {
}
self.index = index;
},
pause: function () {
var self = this;
var sound = self.playlist[self.index].howl;
sound.pause();
},
repeat_all: function(val) {
var self = this;
self.repeat = val;
},
skip: function (direction) {
var self = this;
var index = 0;
if (direction === "prev") {
index = self.index - 1;
if (index < 0) {
index = self.playlist.length - 1;
}
} else {
index = self.index + 1;
if (self.repeat && index >= self.playlist.length) {
index = 0;
}
if (!self.repeat && index >= self.playlist.length) {
self.stop;
} else {
self.skipTo(index);
}
}
},
skipTo: function (index) {
var self = this;
if (self.playlist[self.index].howl) {
self.playlist[self.index].howl.stop();
}
progress_el.style.width = "0%";
self.play(index);
},
vlm: function (val) {
var self = this;
Howler.volume(val);
volume_el.style.width = (val * 100) + "%";
},
seek: function (per) {
var self = this;
var sound = self.playlist[self.index].howl;
if (sound.playing()) {
sound.seek(sound.duration() * per);
}
},
step: function () {
var self = this;
var sound = self.playlist[self.index].howl;
var seek = sound.seek() || 0;
duration_el.innerHTML = self.formatTime(Math.round(seek));
progress_el.style.width = ((seek / sound.duration()) * 100 || 0) + "%";
if (sound.playing()) {
requestAnimationFrame(self.step.bind(self));
}
},
formatTime: function (secs) {
var minutes = Math.floor(secs / 60) || 0;
var seconds = secs - minutes * 60 || 0;
return minutes + ":" + (seconds < 10 ? "0" : "") + seconds;
},
};
let player = new Player(playlist);
player.vlm(volume);
player.skipTo(0);
play_btn.addEventListener("click", function (e) {
e.preventDefault();
player.play();
document.querySelectorAll(".player_main .buttons a.hidden").forEach(function(b){b.classList.remove("hidden")});
this.classList.add("hidden");
});
pause_btn.addEventListener("click", function (e) {
e.preventDefault();
player.pause();
document.querySelectorAll(".player_main .buttons a.hidden").forEach(function(b){b.classList.remove("hidden")});
this.classList.add("hidden");
});
repeat_btn.addEventListener("click", function (e) {
e.preventDefault();
this.classList.toggle("active");
player.repeat_all(this.classList.contains("active"));
});
let mousedown = false;
progressbar_el.addEventListener("click", function (event) {
player.seek((event.clientX - getOffset(this).left) / this.offsetWidth);
});
volumebar_el.addEventListener("mousemove", function (event) {
if (mousedown) {
player.vlm((event.clientX - getOffset(this).left) / this.offsetWidth);
}
});
volumebar_el.addEventListener("mousedown", function (event) {
mousedown = true;
});
volumebar_el.addEventListener("mouseup", function (event) {
mousedown = false;
});
volumebar_el.addEventListener("mouseleave", function (event) {
mousedown = false;
});
let tbl = p.querySelector("table");
tbl.parentNode.removeChild(tbl);
})();