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