arte stream and download

get arte stream url with just one click (or none at all) or download seperate audio/video mp4

安装此脚本
作者推荐脚本

您可能也喜欢arte stop nagging me

安装此脚本
// ==UserScript==
// @name         arte stream and download
// @namespace    http://tampermonkey.net/
// @version      2.8.2
// @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://gf.qytechs.cn/en/scripts/533451-arte-stream-and-download
// ==/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 pathpart = window.location.pathname.split("/"),
        lang = pathpart[1],
        id = pathpart[3],
        name = pathpart[4],
		jsoncontainer,
		nix = "",
        url = "",
        filmid = "",
        cuescriptid = 0,
        liveid = "",
        archid = "",
        mode = "",
        kind = "",
        livelabel = "",
        chapterformat = "",
        loc_stream = "stream url",
        loc_video = "video",
        loc_audio = "audio",
        loc_subs = "subtitles",
        loc_set = "setlist",
        loc_cue = "cue file",
        loc_txt = "plain text",
        loc_dl = "download",
        loc_nodl = "(download unvailable)";

    if (/ARTE Concert/.test(document.title)) {
      kind = "concert";
    }

    if (lang == "fr") {
      loc_subs = "sous-titres";
      loc_dl = "téléchargement";
      loc_nodl = "(téléchargement indisponible)";
    }
    if (lang == "de") {
      loc_stream = "Stream URL";
      loc_video = "Video";
      loc_audio = "Audio";
      loc_subs = "Untertitel";
      loc_set = "Setliste";
      loc_cue = "cue-Datei";
      loc_txt = "Textdatei";
      loc_dl = "Download";
      loc_nodl = "(Download nicht verfügbar)";
    }

    function streamurl() {
      if (mode == "live") {
      var test = prompt(livelabel + loc_stream, url);
      } else {
        var test = prompt(loc_stream+" (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) {
		
      if (nextfid != -1) {
		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 = "",
          txt = "",
          cuefilename = "",
          cuescript = "",
          schemaObj = "";

      if (chapterformat == "chapter") {
        cuescript = self.__next_f[cuescriptid].toString().slice(22).slice(0, -2);
        schemaObj = JSON.parse(cuescript);
        var artistcreds = new Array();
        artistcreds[0] = schemaObj.apiPlayerConfig.attributes.metadata.title;
        artistcreds[1] = schemaObj.apiPlayerConfig.attributes.metadata.subtitle;
      } else {
        cuescript = self.__next_f[cuescriptid].toString().slice(2);
        schemaObj = JSON.parse(cuescript);
        if (/ - /.test(schemaObj.name)) {
          var artistcreds = schemaObj.name.split(" - ");
        } 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";
      var setlistlength = 0;

      if (chapterformat == "chapter") {
        setlistlength = schemaObj.apiPlayerConfig.attributes.chapters.elements.length;
      } else {
        setlistlength = schemaObj.hasPart.length;
      }

      for (var j = 0, k = setlistlength; j < k; ++j) {

        var songtitle = "";
        var timestamp = "";
        if (chapterformat == "chapter") {
          songtitle = schemaObj.apiPlayerConfig.attributes.chapters.elements[j].title;
          timestamp = schemaObj.apiPlayerConfig.attributes.chapters.elements[j].startTime;
        } else {
          songtitle = schemaObj.hasPart[j].name;
          timestamp = schemaObj.hasPart[j].startOffset;
        }

        var padm = "";
        if (timestamp < 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 " + '"' + songtitle + '"';
        cue += "\n    INDEX 01 " + padm + fmtMSS(timestamp) + ":00\n";

        txt += padm + fmtMSS(timestamp) + " " + songtitle + "\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;
    }

    if (self.__next_f) {
      
      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;
            chapterformat = "offset";
          }
          if (/chapterId/.test(it)) {
            cuescriptid = i;
            chapterformat = "chapter";

          }
        }

        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(22, -1).slice(0, -1);
            if (/Generate\//.test(thestring)) {
              var schemaObj = JSON.parse(thestring);
              filmid = "notnull";
              url = schemaObj.apiPlayerConfig.attributes.streams[0].url;

            } else {

              parsescripts(i);

            }

          }

        }

      }
      
    } else {

      for (var i = 0, l = $tn("script").length; i < l; ++i) {

        if ($tn("script")[i].innerText.indexOf("Generate/") != -1) {
          jsoncontainer = i;
          break;
        }

      }

      nix = $tn("script")[jsoncontainer].innerText;
	  parsescripts(-1);

    }

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

    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() {
      
      if (mode == "live") {
          livelabel = "live ";
      }
      if (lang == "de") {
        if (mode == "live") {
          livelabel = "Live ";
        }
      }

      var topelementstream = document.createElement("a");
      topelementstream.setAttribute('id', 'arteuserjsstream');
      topelementstream.setAttribute('class', 'ds-1nr7pfe');

      var innerelementstream = document.createElement("span");
      innerelementstream.setAttribute('id', 'streamurl');
      innerelementstream.setAttribute('class', 'ds-1u5tqvm');
      innerelementstream.setAttribute('style', 'color: #FA481C');
      innerelementstream.innerText = livelabel + loc_stream;

      topelementstream.appendChild(innerelementstream);

      if (!($("arteuserjsstream"))) {
        if ($cn('ds-1r0jukn')[0]) {
          $cn('ds-1r0jukn')[0].insertBefore(topelementstream, null);
        } else if ($cn('ds-1rm5mah')[0]) {
          $cn('ds-1rm5mah')[0].insertBefore(topelementstream, null);
        }
      }

      if (mode == "archive") {

        var topelementdl = document.createElement("a");
        topelementdl.setAttribute('id', 'arteuserjsdl');
        topelementdl.setAttribute('class', 'ds-1nr7pfe');

        var innerelementdl = document.createElement("span");
        innerelementdl.setAttribute('id', 'arteuserjsdlinner');
        innerelementdl.setAttribute('class', 'ds-11ckmbs');
        innerelementdl.innerText = "";

        topelementdl.appendChild(innerelementdl);

        if (!($("topelementdl"))) {
          if ($cn('ds-1r0jukn')[0]) {
            $cn('ds-1r0jukn')[0].insertBefore(topelementdl, null);
          } else if ($cn('ds-1rm5mah')[0]) {
            $cn('ds-1rm5mah')[0].insertBefore(topelementdl, null);
          }
        }

        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() { streamurl() }
        } 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,
                fhdavail = 0,
                videosarr = new Array(),
                audiosarr = new Array(),
                subtisarr = new Array(),
                videosarrng = new Array(),
                vid = 0,
                aud = 0,
                sub = 0,
                vidng = 0,
                videolinksng = "",
                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 (!(/iframe/.test(line))) {

                if (!(/h265/.test(line))) {

                  if (videoformats.test(line)) {

                    if (/aka_me_session/.test(line)) {
                      mp4avail = 0;
                    }
                    if (/v1080/.test(line)) {
                      fhdavail = 1;
                    }

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

                  }

                } else {
                  videosarrng[vidng] = line;
                  vidng++
                }
                
              }

            }

            videosarr = videosarr.sort();
            if (fhdavail == 1) {
            videosarr.push(videosarr.shift());
            }

            videosarr = videosarr.reverse();
            
            audiosarr = audiosarr.sort();
            subtisarr = subtisarr.sort();
            
            var bp = "&#x95; ";

            for (var i = 0, l = subtisarr.length; i < l; ++i) {

              var subcom = subtisarr[i].split("#");
              subtilinks += '<option value="' + subcom[1] + '">' + subcom[0].replace("automatische", "erforderlich").replace("Für", "für").replace(" Untertitel", "").replace("forcé", "obligatoire") + '</option>';

            }

            for (var i = 0, l = audiosarr.length; i < l; ++i) {

              var audcom = audiosarr[i].split("#");
              audiolinks += '<option value="' + audcom[1] + '">' + audcom[0].replace(" (Original)", "").replace(" (VO)", "") + '</option>';

            }

            for (var i = 0, l = videosarr.length; i < l; ++i) {

              videolinks += '<option value="' + videosarr[i] + '">' + videosarr[i].replace(".m3u8", "").replace(vregex, "") + 'p</option>';

            }
            
            if (videosarrng.length > 0) {

              videosarrng = videosarrng.sort();
              
              videolinks += '<option value="">' + bp + 'h265 (hevc)/mp4 ' + loc_video + ':</option>';
              
              for (var i = 0, l = videosarrng.length; i < l; ++i) {

                videolinks += '<option value="' + videosarrng[i] + '">' + videosarrng[i].replace(".m3u8", "").replace("_h265", "").replace(vregex, "") + 'p</option>';

              }
              
            }

            if (mp4avail == 1) {
              result = '<form name="jump" action=""><select style="background-color:black;color:white; width: 40px" class="ds-1u5tqvm" name="dlmenu" onchange="opennewtab()">';
              result += '<option value="" selected="selected">&#x1f847; ' + loc_dl + '</option>'; // ??
              result += '<option value=""></option>';
              result += '<option value="">' + bp + 'h264 (avc)/mp4 ' + loc_video + ':</option>';
              result += videolinks;
              result += '<option value=""></option>';
              result += '<option value="">' + bp + 'aac/mp4 ' + loc_audio + ':</option>';
              result += audiolinks;
              if (subtisarr.length > 0) {
                result += '<option value=""></option>';
                result += '<option value="">' + bp + 'vtt/txt ' + loc_subs + ':</option>';
                result += subtilinks;
              }
              if ((kind == "concert") && (cuescriptid > 0)) {
                result += '<option value=""></option>';
                result += '<option value="">' + bp + loc_set + ':</option>';
                result += '<option value="cue">' + loc_cue + '</option>';
                result += '<option value="txt">' + loc_txt + '</option>';
              }
              result += '</select></form>';
              result = result.replaceAll(".m3u8", ".mp4").replaceAll("undefined", "");
            } else {
              result = loc_nodl;
            }

            $("arteuserjsdlinner").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');
                  var format;
                    if (optionvalue == "cue") { format = encodeURIComponent(window.cue) }
                    else { format = encodeURIComponent(window.txt) }
                    hiddenElement.href = 'data:attachment/text,' + encodeURIComponent(format);
                    hiddenElement.download = window.cuefilename + '.' + optionvalue;
                    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() { streamurl() }
      if ((kind == "concert") && (cuescriptid > 0)) { setlist() }
      $tn("body")[0].onclick = function() {}

    };

    setTimeout('document.getElementsByTagName("body")[0].click()', 2500);

  });

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址