// ==UserScript== // @name arte stream url/seperate mp4 // @namespace http://tampermonkey.net/ // @version 2.5.1 // @description get arte stream url with just one click (or none at all) or download seperate audio/video mp4 // @author mihau // @match https://www.arte.tv/de/videos/* // @match https://www.arte.tv/fr/videos/* // @match https://www.arte.tv/*/videos/* // @match https://www.arte.tv/*/live* // @license MIT // @supportURL https://greasyfork.org/en/scripts/533451-arte-stream-url-seperate-mp4 // @downloadURL none // ==/UserScript== // if you want to get the url in the very moment the page loads, change this from 0 to 1: var loadonload = 0; // please do not edit below this line window.addEventListener('load', function() { $ = function(_) {return document.getElementById(_)} $tn = function(_) {return document.getElementsByTagName(_)} $cn = function(_) {return document.getElementsByClassName(_)} $qa = function(_) {return document.querySelectorAll(_)} $qs = function(_) {return document.querySelector(_)} var loc = window.location.pathname.split("/"), lang = loc[1], id = loc[3], name = loc[4], url, filmid = "", cuescriptid = 0, liveid = "", archid = "", mode = "", kind = "", locdl = "download", locstream = "stream url", locvideo = "video", locaudio = "audio", locsubs = "subtitles", locnodl = "(download unvailable)"; if (/ARTE Concert/.test(document.title)) { kind = "concert"; } if (lang == "fr") { locsubs = "sous-titres"; locdl = "téléchargement"; locnodl = "(téléchargement indisponible)"; } if (lang == "de") { locdl = "Download"; locstream = "Stream URL"; locvideo = "Video"; locaudio = "Audio"; locsubs = "Untertitel"; locnodl = "(Download nicht verfügbar)"; } function showurl() { var test = prompt("stream url (click 'OK' for ffmpeg command)", url); if (test !== null) { prompt("ffmpeg command ('OK' for ffmpeg AUDIO-ONLY command)", 'ffmpeg -referer "' + location.href + '" -user_agent "' + window.navigator.userAgent + '" -i "' + url + '" -c copy -bsf:a aac_adtstoasc "' + filmtitle + '.mp4"'); if (test !== null) { prompt("ffmpeg AUDIO-ONLY command ('OK' for yt-dlp command)", 'ffmpeg -referer "' + location.href + '" -user_agent "' + window.navigator.userAgent + '" -i "' + url + '" -vn -c:a copy "' + filmtitle + '-audio.m4a"'); if (test !== null) { prompt("yt-dlp command", "yt-dlp '" + url + "'"); } } } } function parsescripts(nextfid) { var nix = self.__next_f[nextfid].toString(); if (mode == "live") { var mynewregex = new RegExp("m3u8.*", "gi"); url = nix.match("https://artesimulcast\.akamaized\.net.*m3u8")[0]; url = url.replace(mynewregex, "m3u8") if (lang == "de") { url = url.replace("artelive_fr", "artelive_de") } else { url = url.replace("artelive_de", "artelive_fr") } } else { var myregex = /Generate\/.*?\/\//; var match = nix.match(myregex); var mynewregex = new RegExp("\/.*", "gi") filmid = match[0].replace("Generate/", "").replace(mynewregex, ""); url = "https://manifest-arte.akamaized.net/api/manifest/v1/Generate/" + filmid + "/" + lang + "/XQ+KS+CHEV1/" + id + ".m3u8"; } return url; } function setlist() { var cue = ""; var txt = ""; var cuescript = self.__next_f[cuescriptid].toString().slice(2); var schemaObj = JSON.parse(cuescript); if (schemaObj.hasPart.length > 0) { var cuefilenamecomp = schemaObj.url.split("/"); var cuefilename = ""; // cuefilenamecomp[cuefilenamecomp.length-2]; if (/ - /.test(schemaObj.name)) { var artistcreds = schemaObj.name.split(" - "); cuefilename = artistcreds[0] + "-" + artistcreds[1]; } else { var artistcreds = new Array(); artistcreds[0] = schemaObj.name; artistcreds[1] = schemaObj.name; cuefilename = artistcreds[0] + "-" + artistcreds[1]; } cuefilename = cuefilename.replace(/[^a-z0-9-.]/gi, '_').toLowerCase(); cue += 'PERFORMER "'+artistcreds[0]+'"' + "\n"; cue += 'TITLE "'+artistcreds[1]+'"' + "\n"; cue += 'FILE "'+cuefilename+'.m4a" M4A' + "\n\n TRACK 01 AUDIO\n"; var cueperf = ' PERFORMER "'+artistcreds[0]+'"' + "\n"; cue += cueperf; cue += ' TITLE "Intro/Prologue"' + "\n"; cue += " INDEX 01 00:00:00\n"; txt += "00:00 Intro/Prologue\n"; for (var j = 0, k = schemaObj.hasPart.length; j < k; ++j) { var padm = ""; if (schemaObj.hasPart[j].startOffset < 600) { padm = "0"; } var cuetrackid = j+2; var ctidpad = ""; if (cuetrackid < 10) { ctidpad = "0"; } cue += "\n TRACK " + ctidpad + cuetrackid + " AUDIO \n"; cue += cueperf; cue += " TITLE " + '"' + schemaObj.hasPart[j].name + '"'; cue += "\n INDEX 01 " + padm + fmtMSS(schemaObj.hasPart[j].startOffset) + ":00\n"; txt += padm + fmtMSS(schemaObj.hasPart[j].startOffset) + " " + schemaObj.hasPart[j].name + "\n"; } cue += "\n\n"; window.cue = cue; txt += "\n\n"; window.txt = txt; } window.cuefilename = cuefilename; } // https://stackoverflow.com/questions/3733227/javascript-seconds-to-minutes-and-seconds function fmtMSS(s){ return (s - (s %= 60)) / 60 + (9 < s ? ':' : ':0') + s; } // ... for (var i = 0, l = self.__next_f.length; i < l; ++i) { var it = self.__next_f[i].toString(); if (kind == "concert" ) { if (/startOffset/.test(it)) { cuescriptid = i; } } if (/m3u8/.test(it)) { if (/artelive/.test(it)) { liveid = i; mode = "live"; parsescripts(i); } else if (/Generate/.test(it)) { archid = i; mode = "archive"; var thestring = self.__next_f[archid].toString().slice(0, -1).slice(22, -1); if (/Generate\//.test(thestring)) { var schemaObj = JSON.parse(thestring); filmid = "notnull"; url = schemaObj.apiPlayerConfig.attributes.streams[0].url; } else { parsescripts(i); } } } } // for XHR later on var download_url = ""; if ((url != "") && (url != null) && (url != "null")) { download_url = url; } else { download_url = "https://api.arte.tv/api/player/v2/config/" + lang + "/" + id; } var xhr = new XMLHttpRequest(); if (loadonload != 0) { if ((filmid != null) && (filmid != "null") && (filmid != "") && (filmid != "undefined") && (filmid != undefined) && (filmid != NaN)) { showurl(); } } var filmtitle = $qs('meta[property="og:title"]').content; [" | ARTE Concert", " | ARTE", "- Regarder le documentaire complet", " - Die ganze Doku", " - Komplette Sendung", " - Programm in voller Länge", " - Film in voller Länge", " - Regarder le film complet", " - Regarder l’émission complète"].forEach((item) => { filmtitle = filmtitle.replace(item, "") }); filmtitle = filmtitle.replace(/ /g, "_").replace(/[^a-z0-9 \.,_-]/gim, "").replace("_-_", "-"); $tn("body")[0].onclick = function() { setTimeout('document.getElementsByTagName("body")[0].click()', 1000); var para = document.createElement("a"); para.setAttribute('id', 'arteuserjs'); para.setAttribute('style', 'color: red; font-weight: 800; padding-left: 5px'); para.setAttribute('class', 'ds-1nr7pfe'); //ds-64fl0u var node = document.createElement("span"); node.setAttribute('id', 'streamurl'); node.setAttribute('class', 'ds-1u5tqvm'); // ds-11ckmbs node.setAttribute('style', 'padding-left: 10px; color: #FA481C'); node.innerText = locstream; para.appendChild(node); if (!($("arteuserjs"))) { if ($cn('ds-1r0jukn')[0]) { $cn('ds-1r0jukn')[0].insertBefore(para, null); } else if ($cn('ds-1rm5mah')[0]) { $cn('ds-1rm5mah')[0].insertBefore(para, null); } } if (mode == "archive") { var anothernode = document.createElement("span"); anothernode.setAttribute('id', 'placeholder'); anothernode.setAttribute('class', 'ds-11ckmbs'); anothernode.setAttribute('style', 'padding-left: 10px'); anothernode.innerText = ""; para.appendChild(anothernode); var getJSON = function(url, callback) { xhr.open('GET', url, true); xhr.responseType = 'json'; xhr.onload = function() { var status = xhr.status; if (status == 200) { callback(null, xhr.response); } else { callback(status); } }; xhr.send(); }; var getM3U = function(url, callback) { xhr.open('GET', url, true); xhr.responseType = 'text'; xhr.onload = function() { var status = xhr.status; if (status == 200) { callback(null, xhr.response); } else { callback(status); } }; xhr.send(); }; if ((filmid != null) && (filmid != "null") && (filmid != "") && (filmid != "undefined") && (filmid != undefined) && (filmid != NaN)) { $("streamurl").onclick = function() { showurl(); } } else { getJSON(download_url, function(err, data) { if (err != null) { console.error(err); } else { url = data.data.attributes.streams[0].url; } }); } getM3U(url, function(err, data) { if (err != null) { console.error(err); } else { getM3U = function() {}; var mp4avail = 1, videosarr = new Array(), audiosarr = new Array(), subtisarr = new Array(), vid = 0, aud = 0, sub = 0, result, videolinks, audiolinks, subtilinks = "", vregex = new RegExp(".*_v", "gi"), videoformats = /-([A-Z])_v/, uregex = /URI=(["'])(.*?)\1/, nregex = /NAME=(["'])(.*?)\1/; var lines = data.split(/[\r\n]/); for (var i in lines) { var line = lines[i]; if ((!(/h265/.test(line))) && (!(/iframe/.test(line)))) { if (videoformats.test(line)) { if (/aka_me_session/.test(line)) { mp4avail = 0; } videosarr[vid] = line; vid++; } if (/TYPE=AUDIO/.test(line)) { var audiofile = line.match(uregex)[2]; var audiolabel = line.match(nregex)[2]; audiosarr[aud] = audiolabel + "#" + audiofile; aud++; } if (/TYPE=SUBTITLES/.test(line)) { var subfile = line.match(uregex)[2]; var sublabel = line.match(nregex)[2]; subtisarr[sub] = sublabel + "#" + subfile.replace("m3u8", "vtt"); sub++; } } } videosarr = videosarr.sort(); videosarr.push(videosarr.shift()); videosarr = videosarr.reverse(); audiosarr = audiosarr.sort(); subtisarr = subtisarr.sort(); for (var i = 0, l = subtisarr.length; i < l; ++i) { var subcom = subtisarr[i].split("#"); subtilinks += ''; } for (var i = 0, l = audiosarr.length; i < l; ++i) { var audcom = audiosarr[i].split("#"); audiolinks += ''; } for (var i = 0, l = videosarr.length; i < l; ++i) { videolinks += ''; } // hardcoded, should do for now if ((/h265/.test(lines)) && (/1080p/.test(videolinks))) { videolinks += ''; videolinks += ''; videolinks += ''; } if (mp4avail == 1) { result = '
'; result = result.replaceAll(".m3u8", ".mp4").replaceAll("undefined", ""); } else { result = locnodl; } $("placeholder").innerHTML = result; } }); var script = document.createElement("script"); script.innerHTML = ` function opennewtab() { var optionvalue = document.jump.dlmenu.options[document.jump.dlmenu.selectedIndex].value; if ((optionvalue == "cue") || (optionvalue == "txt")) { var hiddenElement = document.createElement('a'); if (optionvalue == "cue") { hiddenElement.href = 'data:attachment/text,' + encodeURIComponent(window.cue); hiddenElement.download = window.cuefilename + '.cue'; } if (optionvalue == "txt") { hiddenElement.href = 'data:attachment/text,' + encodeURIComponent(window.txt); hiddenElement.download = window.cuefilename + '.txt'; } hiddenElement.target = '_blank'; hiddenElement.click(); } else if ((document.jump.dlmenu.selectedIndex > 0) && (optionvalue != "") && (optionvalue != "#")) { window.open(optionvalue, "artedltab"); } } `; document.body.appendChild(script); } $("streamurl").onclick = function() { showurl() } $tn("body")[0].onclick = function() {} if ((kind == "concert") && (cuescriptid > 0)) { setlist(); } }; setTimeout('document.getElementsByTagName("body")[0].click()', 2500); });