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); })();