NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Listen to Youtube // @id Volkan-K.Userscript.Listen-To-Youtube // @namespace volkan-k // @description Removes video and plays mp3 on youtube. // @author Volkan K. // @license MIT // @copyright 2018+ Volkan K. // @version 3.0.2 // @domain youtube.com // @domain www.youtube.com // @include http://youtube.com/* // @include http://www.youtube.com/* // @include https://youtube.com/* // @include https://www.youtube.com/* // @grant GM_xmlhttpRequest // @grant GM_setValue // @grant GM_getValue // @grant unsafeWindow // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.9/mediaelement-and-player.min.js // @run-at document-end // @connect youtubemp3api.com // @connect youtube.com // ==/UserScript== var debug_internal = 1; // 1=enable debug , 0 =disable debug var use_youtube_player = 1; // 1=enable ytplayer, 0= disable ytplayer var use_youtube_source = 1; // 1=use youtube source, 0=use external source. var use_yt_config = 1; //var DECODE_RULE=[21,-3,41,0,-1,21,-1]; // positive = swap , zero = reverse, negative=slice var DECODE_RULE=[]; var audio_selector= "mime=audio"; var audio_quality="highest"; // highest or lowest, you either save bandwidth or not. var STORAGE_URL='download-youtube-script-url'; var STORAGE_CODE='download-youtube-signature-code'; var isDecodeRuleUpdated=false; var scriptURL=null; this.$ = this.jQuery = jQuery.noConflict(true); //console.log(unsafeWindow.ytplayer.config.args.adaptive_fmts); // for debug var videoElements = $('video'); var videoElement = videoElements[0]; if ($("div[id='player-api']:not('.off-screen-target')").length > 0) { var target_node = "div[id='player-api']:not('.off-screen-target')"; } else { var target_node = "#player-container"; } var VIDEO_ID = get_video_id_from_yturl(window.location.href); window.VIDEO_ID = VIDEO_ID; //console.log(VIDEO_ID); //return ; // for debug if ($('meta[name="GM_VIDEO_ID"]').length == 0) { $("head").append('<meta name="GM_VIDEO_ID" content="' + VIDEO_ID + '"/>'); } function debugLog(message) { if (debug_internal == 1) { console.log("USER-SCRIPT LISTEN-TO-YT | " + message); } } function isString(s) { return (typeof s === 'string' || s instanceof String); } function isInteger(n) { return (typeof n === 'number' && n % 1 == 0); } String.prototype.replaceAt = function(index, char) { var a = this.split(""); a[index] = char; return a.join(""); } function decryptSignature(sig) { function remove(sig, arr) { if (!arr || arr.length === 0) { arr = [6, 5, 4, -2, 1]; } str = sig.split(''); for (var i = 0; i < arr.length; i++) { str.splice(arr[i], 1); } str = str.join(''); return str; } function swap(a, b) { var c = a[0]; a[0] = a[b % a.length]; a[b] = c; return a } function swap_new(string, position) { string = string.split(''); var last = string[string.length - 1]; string[position] = last; string = string.join(''); return string; } function decode(sig, arr) { // encoded decryption if (!isString(sig)) return null; var sigA = sig.split(''); for (var i = 0; i < arr.length; i++) { var act = arr[i]; if (!isInteger(act)) return null; sigA = (act > 0) ? swap(sigA, act) : ((act == 0) ? sigA.reverse() : sigA.slice(-act)); } var result = sigA.join(''); return result; } if (sig == null) return ''; var arr = DECODE_RULE; if (arr) { var sig2 = decode(sig, arr); //debugLog("DEBUG: encrypted signature = "+sig+", decrypted signature = "+sig2); if (sig2) return sig2; } else { /*setPref(STORAGE_URL, ''); setPref(STORAGE_CODE, '');*/ } return sig; } function remove_all_video_players() { if ($("video,iframe,div.html5-video-player").length < 1) { return; } $("div.html5-video-player").each(function() { //$(this).remove(); $(this)[0].destroy(); $(this).hide(); }); $('video').each(function() { $(this)[0].pause(); $(this)[0].currentTime = 0; $(this).attr('src', ''); $(this)[0].load(); $(this)[0].innerHTML = ''; $(this)[0].load(); $(this).removeAttr('src'); $(this)[0].load(); //$(this).remove(); $(this).hide(); }); $("iframe").each(function() { $(this).attr('src', 'https://www.youtube.com/html5'); //$(this).remove(); $(this).hide(); }); window.yt = null; window.ytplayer = null; } function pause_all_video_players() { $('video').not("[src*='googlevideo']").not("[src*='youtubemp3api']").each(function() { $(this)[0].pause(); $(this)[0].currentTime = 0; /*if ($(this).attr('src').startsWith("blob:")){ // causes problem with "autoplay next video" feature. $(this).attr('src', 'https://github.com/anars/blank-audio/raw/master/750-milliseconds-of-silence.mp3'); }*/ /*$(this).attr('src', ''); $(this)[0].load(); $(this)[0].innerHTML=''; $(this)[0].load(); $(this).removeAttr('src'); $(this)[0].load();*/ $(this).parents("div.html5-video-player").each(function() { $(this)[0].stopVideo(); }); }); } /*var script = document.createElement("script"); script.type = "text/javascript"; script.textContent = 'document.createElement("video").constructor.prototype.canPlayType = function(type){return ""}'; document.documentElement.appendChild(script); */ function addStyle_external(css_link) { var head, style; head = document.getElementsByTagName('head')[0]; if (!head) { return; } style = document.createElement('link'); style.setAttribute("rel", "stylesheet"); style.setAttribute("type", "text/css"); style.setAttribute("href", css_link); head.appendChild(style); } addStyle_external("https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.9/mediaelementplayer.min.css"); function choose_adaptive_fmt_by_url(adaptive_fmts, url_part, decrypt) { if (typeof adaptive_fmts ==="undefined" || adaptive_fmts === "" || adaptive_fmts === null) { debugLog("DEBUG: adaptive_fmts empty at choose_adaptive_fmt_by_url()"); return; } adaptive_fmts_arr = adaptive_fmts.split(","); var return_value=null; var current_bitrate=0; var available_bitrates=[]; for (i = 0; i < adaptive_fmts_arr.length; i++) { if (loadStringVar_new(adaptive_fmts_arr[i], "url").includes(url_part)) { i_bitrate=parseInt(loadStringVar_new(adaptive_fmts_arr[i], "bitrate")); available_bitrates.push(i_bitrate); if ((audio_quality==="lowest" && i_bitrate>current_bitrate && current_bitrate!==0) || (audio_quality!=="lowest") && i_bitrate<current_bitrate){ // this bitrate is not desired continue; } current_bitrate=i_bitrate; var selected_url = loadStringVar_new(adaptive_fmts_arr[i], "url"); if (selected_url.includes("&signature=") || loadStringVar_new(adaptive_fmts_arr[i], "s") == "") { decrypt = 0; // TEST: dont decrypt signature if it is already in URL if (decrypt == 1 || decrypt == true) { var parsed_signature = loadStringVar_new(selected_url, "signature"); if (parsed_signature!==false) { var decoded_url=selected_url.replace(/\&signature=[\w\.]+/, '&signature='+decryptSignature(parsed_signature)); return_value= decoded_url; } else { debugLog("DEBUG: failed to decrypt url"); return_value=null; } } else { return selected_url; } } else { if (decrypt == 1 || decrypt == true) { return_value=selected_url + "&signature=" + decryptSignature(loadStringVar_new(adaptive_fmts_arr[i], "s")); } else { return_value=selected_url + "&signature=" + loadStringVar_new(adaptive_fmts_arr[i], "s"); } } } } debugLog("available bitrates = "+available_bitrates.sort(function(a, b){return a - b})+" ; selected bitrate = "+current_bitrate); return return_value; } function loadStringVar_new(string, sParam) { var sURLVariables = string.split('&'), sParameterName, i; for (i = 0; i < sURLVariables.length; i++) { sParameterName = sURLVariables[i].split('='); if (decodeURIComponent(sParameterName[0]) === sParam) { return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]); } } return false; } function loadStringVar(sVar, mystring) { if (!(/^[&?]/.test(mystring))) { mystring = "?" + mystring; } return unescape(mystring.replace(new RegExp("^(?:.*[&\\?]" + escape(sVar).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1")); } function loadPageVar(sVar) { return unescape(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + escape(sVar).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1")); } function findMatch(text, regexp) { var matches=text.match(regexp); return (matches)?matches[1]:null; } function get_video_id_from_yturl(yturl) { /*var parser = document.createElement('a'); parser.href = yturl;*/ if (yturl.includes("embed/")){ return findMatch(yturl, /embed\/([a-zA-Z0-9_-]{11})/i); } if (yturl) { var parser = yturl.split("?")[1]; } else if (window.location.href) { var parser = window.location.href.split("?")[1]; } else { return window.ytplayer.config.args.video_id; } return loadStringVar("v", parser); } function absoluteURL(url) { var link = document.createElement('a'); link.href = url; return link.href; } function getPref(name) { // cross-browser GM_getValue var a = '', b = ''; try { a = typeof GM_getValue.toString; b = GM_getValue.toString() } catch (e) {} if (typeof GM_getValue === 'function' && (a === 'undefined' || b.indexOf('not supported') === -1)) { return GM_getValue(name, null); // Greasemonkey, Tampermonkey, Firefox extension } else { var ls = null; try { ls = window.localStorage || null } catch (e) {} if (ls) { return ls.getItem(name); // Chrome script, Opera extensions } } return; } function setPref(name, value) { // cross-browser GM_setValue var a = '', b = ''; try { a = typeof GM_setValue.toString; b = GM_setValue.toString() } catch (e) {} if (typeof GM_setValue === 'function' && (a === 'undefined' || b.indexOf('not supported') === -1)) { GM_setValue(name, value); // Greasemonkey, Tampermonkey, Firefox extension } else { var ls = null; try { ls = window.localStorage || null } catch (e) {} if (ls) { return ls.setItem(name, value); // Chrome script, Opera extensions } } } function crossXmlHttpRequest(details) { // cross-browser GM_xmlhttpRequest if (typeof GM_xmlhttpRequest === 'function') { // Greasemonkey, Tampermonkey, Firefox extension, Chrome script GM_xmlhttpRequest(details); } else if (typeof window.opera !== 'undefined' && window.opera && typeof opera.extension !== 'undefined' && typeof opera.extension.postMessage !== 'undefined') { // Opera 12 extension var index = operaTable.length; opera.extension.postMessage({ 'action': 'xhr-' + index, 'url': details.url, 'method': details.method }); operaTable[index] = details; } else if (typeof window.opera === 'undefined' && typeof XMLHttpRequest === 'function') { // Opera 15+ extension var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { if (details['onload']) { details['onload'](xhr); } } } xhr.open(details.method, details.url, true); xhr.send(); } } function isValidSignatureCode(arr) { // valid values: '5,-3,0,2,5', 'error' if (!arr) return false; if (arr == 'error') return true; arr = arr.split(','); for (var i = 0; i < arr.length; i++) { if (!isInteger(parseInt(arr[i], 10))) return false; } return true; } function fetchSignatureScript(scriptURL) { var storageURL = getPref(STORAGE_URL); var storageCode = getPref(STORAGE_CODE); if (!(/,0,|^0,|,0$|\-/.test(storageCode))) storageCode = null; // hack for only positive items if (storageCode && isValidSignatureCode(storageCode) && storageURL && scriptURL == absoluteURL(storageURL)) return; try { debugLog('fetch ' + scriptURL); isSignatureUpdatingStarted = true; crossXmlHttpRequest({ method: 'GET', url: scriptURL, onload: function(response) { debugLog('fetch status ' + response.status); if (response.readyState === 4 && response.status === 200 && response.responseText) { findSignatureCode(response.responseText); } } }); } catch (e) {} } function findSignatureCode(sourceCode) { debugLog('Info: signature start ' + getPref(STORAGE_CODE)); var signatureFunctionName = findMatch(sourceCode, /\.set\s*\("signature"\s*,\s*([a-zA-Z0-9_$][\w$]*)\(/) || findMatch(sourceCode, /\.sig\s*\|\|\s*([a-zA-Z0-9_$][\w$]*)\(/) || findMatch(sourceCode, /\.signature\s*=\s*([a-zA-Z_$][\w$]*)\([a-zA-Z_$][\w$]*\)/) //old || findMatch(sourceCode, /\|\|\s*"signature"\s*,\s*([a-zA-Z0-9_$][\w$]*)\(/); //new if (signatureFunctionName == null) return setPref(STORAGE_CODE, 'error'); signatureFunctionName = signatureFunctionName.replace('$', '\\$'); var regCode = new RegExp(signatureFunctionName + '\\s*=\\s*function' + '\\s*\\([\\w$]*\\)\\s*{[\\w$]*=[\\w$]*\\.split\\(""\\);\n*(.+);return [\\w$]*\\.join'); var regCode2 = new RegExp('function \\s*' + signatureFunctionName + '\\s*\\([\\w$]*\\)\\s*{[\\w$]*=[\\w$]*\\.split\\(""\\);\n*(.+);return [\\w$]*\\.join'); var functionCode = findMatch(sourceCode, regCode) || findMatch(sourceCode, regCode2); debugLog('Info: signaturefunction ' + signatureFunctionName + ' -- ' + functionCode); if (functionCode == null) return setPref(STORAGE_CODE, 'error'); var reverseFunctionName = findMatch(sourceCode, /([\w$]*)\s*:\s*function\s*\(\s*[\w$]*\s*\)\s*{\s*(?:return\s*)?[\w$]*\.reverse\s*\(\s*\)\s*}/); debugLog('Info: reversefunction ' + reverseFunctionName); if (reverseFunctionName) reverseFunctionName = reverseFunctionName.replace('$', '\\$'); var sliceFunctionName = findMatch(sourceCode, /([\w$]*)\s*:\s*function\s*\(\s*[\w$]*\s*,\s*[\w$]*\s*\)\s*{\s*(?:return\s*)?[\w$]*\.(?:slice|splice)\(.+\)\s*}/); debugLog('Info: slicefunction ' + sliceFunctionName); if (sliceFunctionName) sliceFunctionName = sliceFunctionName.replace('$', '\\$'); var regSlice = new RegExp('\\.(?:' + 'slice' + (sliceFunctionName ? '|' + sliceFunctionName : '') + ')\\s*\\(\\s*(?:[a-zA-Z_$][\\w$]*\\s*,)?\\s*([0-9]+)\\s*\\)'); // .slice(5) sau .Hf(a,5) var regReverse = new RegExp('\\.(?:' + 'reverse' + (reverseFunctionName ? '|' + reverseFunctionName : '') + ')\\s*\\([^\\)]*\\)'); // .reverse() sau .Gf(a,45) var regSwap = new RegExp('[\\w$]+\\s*\\(\\s*[\\w$]+\\s*,\\s*([0-9]+)\\s*\\)'); var regInline = new RegExp('[\\w$]+\\[0\\]\\s*=\\s*[\\w$]+\\[([0-9]+)\\s*%\\s*[\\w$]+\\.length\\]'); var functionCodePieces = functionCode.split(';'); var decodeArray = []; for (var i = 0; i < functionCodePieces.length; i++) { functionCodePieces[i] = functionCodePieces[i].trim(); var codeLine = functionCodePieces[i]; if (codeLine.length > 0) { var arrSlice = codeLine.match(regSlice); var arrReverse = codeLine.match(regReverse); debugLog(i + ': ' + codeLine + ' --' + (arrSlice ? ' slice length ' + arrSlice.length : '') + ' ' + (arrReverse ? 'reverse' : '')); if (arrSlice && arrSlice.length >= 2) { // slice var slice = parseInt(arrSlice[1], 10); if (isInteger(slice)) { decodeArray.push(-slice); } else return setPref(STORAGE_CODE, 'error'); } else if (arrReverse && arrReverse.length >= 1) { // reverse decodeArray.push(0); } else if (codeLine.indexOf('[0]') >= 0) { // inline swap if (i + 2 < functionCodePieces.length && functionCodePieces[i + 1].indexOf('.length') >= 0 && functionCodePieces[i + 1].indexOf('[0]') >= 0) { var inline = findMatch(functionCodePieces[i + 1], regInline); inline = parseInt(inline, 10); decodeArray.push(inline); i += 2; } else return setPref(STORAGE_CODE, 'error'); } else if (codeLine.indexOf(',') >= 0) { // swap var swap = findMatch(codeLine, regSwap); swap = parseInt(swap, 10); if (isInteger(swap) && swap > 0) { decodeArray.push(swap); } else return setPref(STORAGE_CODE, 'error'); } else return setPref(STORAGE_CODE, 'error'); } } if (decodeArray) { setPref(STORAGE_URL, scriptURL); setPref(STORAGE_CODE, decodeArray.toString()); DECODE_RULE = decodeArray; debugLog('Info: signature ' + decodeArray.toString() + ' ' + scriptURL); // update download links and add file sizes var elem = document.querySelector("div.html5-video-container > video"); var url = elem.src; var sig = loadStringVar_new(url,"signature"); if (elem && url && sig) { url = url.replace(/\&signature=[\w\.]+/, '&signature=' + decryptSignature(sig)); elem.setAttribute('src', url); elem.play(); } } } function getDecodeRules(rules) { var storageCode = getPref(STORAGE_CODE); if (storageCode && storageCode != 'error' && isValidSignatureCode(storageCode)) { var arr = storageCode.split(','); for (var i = 0; i < arr.length; i++) { arr[i] = parseInt(arr[i], 10); } rules = arr; debugLog('Info: signature ' + arr.toString() + ' ' + scriptURL); } return rules; } function show_poster_image() { if ($("img#poster_image").length > 0) { debugLog("DEBUG: show_poster_image() exits because img tag exists"); return; } if ($(target_node).filter("[style*='img.youtube.com']").length > 0) { debugLog("DEBUG: show_poster_image() exits because background-image css exists"); return; } if ($('meta[name="GM_VIDEO_ID"]').length > 0) { VIDEO_ID = $('meta[name="GM_VIDEO_ID"]').attr("content"); } else { VIDEO_ID = get_video_id_from_yturl(window.location.href); } if (!(VIDEO_ID)) { debugLog("DEBUG : show_poster_image() cant find VIDEO_ID"); return; } var bgUrl = 'https://img.youtube.com/vi/' + VIDEO_ID + '/0.jpg'; if ($("video").eq(0).filter("[style*='img.youtube.com']").length > 0) { debugLog("DEBUG: show_poster_image() exits because img.youtube.com exists in style"); return; } if (use_youtube_player === 0) { //$(target_node).append('<div><img id="poster_image" src="https://img.youtube.com/vi/'+VIDEO_ID+'/hqdefault.jpg" style="display:block; margin:auto;"/></div>'); $(target_node).css({ "background-image": "url(https://img.youtube.com/vi/" + VIDEO_ID + "/hqdefault.jpg)", "background-repeat": "no-repeat", /* "background-attachment": "fixed", */ "background-position": "center" }); } else { $("video").eq(0).css("background", 'transparent url(' + bgUrl + ') no-repeat center'); $("video").eq(0).css("backgroundSize", '80%'); } } function prepare_audio_player() { if ($("audio").length > 0) { debugLog("DEBUG : prepare_audio_player() exits because there is audio in page."); return; } if ($('meta[name="GM_RUNNING"]').length > 0) { if ($('meta[name="GM_MP3_URL"]').length > 0) { show_audio_player($('meta[name="GM_MP3_URL"]').attr("content")); debugLog("DEBUG : prepare_audio_player() runs show_audio_player with last mp3 url."); return; } else { debugLog("DEBUG : prepare_audio_player() exits because it already completed a request."); return; } } if ($('meta[name="GM_RAN"]').attr("content") > 3) { debugLog("DEBUG : prepare_audio_player() exits because it has ran 3 times without success."); return; } if ($('meta[name="GM_VIDEO_ID"]').length > 0) { VIDEO_ID = $('meta[name="GM_VIDEO_ID"]').attr("content"); } else { VIDEO_ID = get_video_id_from_yturl(window.location.href); } if (!(VIDEO_ID)) { debugLog("DEBUG : prepare_audio_player() cant find VIDEO_ID"); return; } debugLog("DEBUG : prepare_audio_player() running with VIDEO_ID = " + VIDEO_ID); function xhr_onload(response) { if (response.status == 200) { // we can parse now //console.log(response.responseText); if (use_youtube_source == 1) { // youtube GVI parsing adaptive_fmts = loadStringVar_new(response.responseText, "adaptive_fmts"); console.log(response.responseText); if (adaptive_fmts===false){ debugLog("DEBUG: couldn't find adaptive_fmts in response.responseText. Exiting!"); return; } var download_link = choose_adaptive_fmt_by_url(adaptive_fmts, audio_selector, 1); debugLog("DEBUG: adaptive_fmts = "+adaptive_fmts); debugLog("DEBUG: download_link = "+download_link); } else { var response_parsed = $.parseHTML(response.responseText); //var download_link = $('a[href*="youtubemp3api.com/@download/"]', response_parsed); var download_link = $(response_parsed).filter('a[href*="youtubemp3api.com/@download/"]').eq(0).attr("href"); } process_download_link(download_link); if ($('meta[name="GM_RUNNING"]').length == 0) { $("head").append('<meta name="GM_RUNNING" content="YES"/>'); } } else { debugLog("response.status = " + response.status +",use_youtube_source="+use_youtube_source); } } function process_download_link(download_link){ show_audio_player(download_link); if ($('meta[name="GM_MP3_URL"]').length == 0) { $("head").append('<meta name="GM_MP3_URL" content="' + download_link + '"/>'); } } if (use_youtube_source == 1) { var args = null; var usw = (typeof unsafeWindow !== 'undefined') ? unsafeWindow : window; // Firefox, Opera<15 //console.log(unsafeWindow.ytplayer.config.args.adaptive_fmts); // for debug if (usw.ytplayer && usw.ytplayer.config && usw.ytplayer.config.args) { args = usw.ytplayer.config.args; } if (usw.ytplayer && usw.ytplayer.config && usw.ytplayer.config.assets) { scriptURL=usw.ytplayer.config.assets.js; } if (!isDecodeRuleUpdated) { DECODE_RULE = getDecodeRules(DECODE_RULE); isDecodeRuleUpdated = true; } if (scriptURL) { scriptURL = absoluteURL(scriptURL); debugLog('Info: Full script URL: '+scriptURL); fetchSignatureScript(scriptURL); } //console.log(window.ytplayer.config.args); // for debug if (args && args['adaptive_fmts'] && use_yt_config === 1) { debugLog("DEBUG: using youtube configuration"); adaptive_fmts = args['adaptive_fmts']; var download_link = choose_adaptive_fmt_by_url(adaptive_fmts, audio_selector, 1); process_download_link(download_link); } else { // GVI call debugLog("DEBUG: using Get_Video_Info configuration"); xhr_ret_val = GM_xmlhttpRequest({ synchronous: false, method: "GET", headers: { 'Referer': "https://www.youtube.com/watch?v=" + VIDEO_ID }, url: "https://www.youtube.com/get_video_info?el=detailpage&video_id=" + VIDEO_ID, onerror: function(oEvent) { debugLog("Error " + oEvent.target.status + " occurred while receiving the document."); }, onload: function(response) { xhr_onload(response); } }); } } else { xhr_ret_val = GM_xmlhttpRequest({ synchronous: false, method: "GET", headers: { 'Referer': "https://youtubemp3api.com/@api/button/mp3/" + VIDEO_ID }, //url: "https://youtubemp3api.com/@api/button/audiostreams/"+VIDEO_ID, url: "https://youtubemp3api.com/@grab?vidID=" + VIDEO_ID + "&format=mp3&streams=audiostreams&api=button", onerror: function(oEvent) { debugLog("Error " + oEvent.target.status + " occurred while receiving the document."); }, onload: function(response) { xhr_onload(response); } }); } //xhr_onload(xhr_ret_val); if ($('meta[name="GM_RAN"]').length == 0) { $("head").append('<meta name="GM_RAN" content="1"/>'); } else { $('meta[name="GM_RAN"]').attr("content", function(i, val) { return parseInt(val) + 1; }); } } function is_it_already_processed() { if ($("audio").length > 0) { return true; } if ($("video").eq(0).filter("[src*='youtubemp3api']").length > 0) { return true; } //console.log($("video").eq(0).attr("src")); if ($("video").eq(0).filter("[src*='googlevideo']").length > 0) { return true; } return false; } function show_audio_player(audio_url) { if (is_it_already_processed() === true) { return; } if (typeof audio_url==="undefined" || audio_url === "" || audio_url === null || audio_url === undefined) { if ($('meta[name="GM_MP3_URL"]').length > 0 && $('meta[name="GM_MP3_URL"]').attr("content")!="undefined") { audio_url = $('meta[name="GM_MP3_URL"]').attr("content"); debugLog("DEBUG : show_audio_player() runs with last mp3 url because of empty parameter."); } else { debugLog("NOTICE: show_audio_player() fails to run because of empty parameter and undefined last mp3 url"); return; } } /*$('audio').each(function() { $(this)[0].pause(); $(this)[0].currentTime = 0; });*/ if (use_youtube_player === 0) { if (!(document.getElementById("player_mp3"))) { $(target_node).prepend('<audio class="mejs__player" id="player_mp3" preload="auto" autoplay="autoplay" controls="controls" style="max-width: 100%">' + '<source src="' + audio_url + '" type="audio/mp3">' + '</audio>'); } $('audio').mediaelementplayer({ enablePluginDebug: true, alwaysShowControls: true, // Do not forget to put a final slash (/) pluginPath: 'https://cdnjs.com/libraries/mediaelement/', // this will allow the CDN to use Flash without restrictions // (by default, this is set as `sameDomain`) shimScriptAccess: 'always', // more configuration success: function(mediaElement, domObject) { debugLog("DEBUG: media was successfully loaded"); mediaElement.play(); // add event listener mediaElement.addEventListener('canplay', function(e) { // Player is ready mediaElement.play(); }, false); mediaElement.addEventListener('ended', function(e) { //Do Stuff here //alert("sometext"); if ((document.getElementById("autoplay-checkbox") && document.getElementById("autoplay-checkbox").checked) || (document.getElementById("toggle") && document.getElementById("toggle").checked)) { if ($("ytd-compact-autoplay-renderer a#thumbnail").length > 0) { $("ytd-compact-autoplay-renderer a#thumbnail")[0].click(); } else if ($("div.watch-sidebar-body div.content-wrapper a.content-link").length > 0) { $("div.watch-sidebar-body div.content-wrapper a.content-link")[0].click(); } } }, false); /*var events = ['loadstart', 'play','pause', 'ended']; for (var i=0, il=events.length; i<il; i++) { var eventName = events[i]; mediaElement.addEventListener(events[i], function(e) { debugLog(e.type); }); }*/ }, error: function(mediaElement, domObject) { debugLog("DEBUG: media had an error loading"); setTimeout(function() { mediaElement.play(); }, 1000); }, }); } else { /*if ( $('meta[name="GM_PROCESSED"]').length >0 ) { return ; } else { $("head").append('<meta name="GM_PROCESSED" content="YES"/>'); }*/ //console.log(is_it_already_processed()); if (is_it_already_processed() === false && $("video").attr("src") != audio_url && typeof audio_url !=="undefined") { $("video")[0].pause(); $("video").eq(0).attr('src', audio_url); debugLog("DEBUG: set src to " + audio_url); $("video")[0].currentTime = 0; $("video")[0].play(); } else { debugLog("DEBUG: won't set source! is_it_already_processed() = "+is_it_already_processed()+", typeof audio_url = "+typeof audio_url); } } } function my_ready_function() { /*if (is_it_already_processed()===true) { //clearInterval(window.my_ival); return; }*/ if ($("audio").length > 0) { if (use_youtube_player === 0) { setInterval(remove_all_video_players, 1000); // } else { // setInterval(pause_all_video_players,1000); } return; } if (use_youtube_player === 0) { remove_all_video_players(); } else { pause_all_video_players(); } show_poster_image(); show_audio_player(); } $(document).ready(function() { my_ready_function(); prepare_audio_player(); }); window.my_ival = setInterval(my_ready_function, 1000);