Leque

audio d+

Dec 15th, 2021
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.86 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Disney+ Audio Downloader
  3. // @name:fr Disney+ Audio Downloader
  4. // @namespace https://greasyfork.org/users/572942-stegner
  5. // @homepage https://greasyfork.org/scripts/405994-disney-audio-downloader
  6. // @description Download audio from Disney+
  7. // @description:fr Télécharger l'audio de Disney+
  8. // @version 1.5
  9. // @author stegner
  10. // @match https://www.disneyplus.com/*
  11. // @grant none
  12. // @run-at document-start
  13. // ==/UserScript==
  14.  
  15. (function(open) {
  16. 'use strict';
  17. var debug = (location.hash=="#debug");
  18. debuglog("Script loaded : Disney+ Audio Downloader");
  19.  
  20. function init(){
  21. debuglog("Document state : "+document.readyState);
  22. if (document.readyState == "complete" || document.readyState == "loaded"){
  23. start();
  24. debuglog("Already loaded");
  25. }
  26. else {
  27. if (window.addEventListener) {
  28. window.addEventListener("load", start, false);
  29. debuglog("Onload method : addEventListener");
  30. } else if (window.attachEvent) {
  31. window.attachEvent("onload", start);
  32. debuglog("Onload method : attachEvent");
  33. } else {
  34. window.onload = start;
  35. debuglog("Onload method : onload");
  36. }
  37. }
  38. document.listen=true;
  39. }
  40.  
  41. function start(){
  42. debuglog("start");
  43. if (typeof document.initaudio !== "undefined") {
  44. document.initaudio();
  45. }
  46. if (typeof document.initsub !== "undefined") {
  47. document.initsub();
  48. }
  49. listensend();
  50. document.handleinterval = setInterval(buttonhandle,100);
  51. }
  52.  
  53. if(!document.listen){
  54. init();
  55. }
  56.  
  57. document.initaudio = function(){
  58. debuglog("initaudio");
  59. document.audios = new Array();
  60. document.content = new Uint8Array();
  61. document.baseurl="";
  62. document.m3u8found=false;
  63. document.wait=false;
  64. document.downloading=false;
  65. document.filename="";
  66. document.episode="";
  67. document.audioid=null;
  68.  
  69. // Add download icon
  70. document.styleSheets[0].addRule('#audioTrackPicker > div:before','content:"";color:#fff;padding-right:35px;padding-top:2px;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAIGNIUk0AAHonAACAgwAA+mQAAIDSAAB2hgAA7OkAADmeAAAV/sZ+0zoAAAE4SURBVHja1JS7LkRRFIa/M6aYRCEuCUEUgihFBolGVGqiFY1ConfpNB7CiygUGm8hOiMukwiCCMl8mj2xc5yZM8M0/mTlrLP2v75zydo7UclRL3AGlIAl4L6ZuUC+5oEZYBoo55lbAdai/LPTwFongG3pfwI3gZ3ovhjlXVG+BWz/6FbjKPuto1CbjWoLobYf1RZjRho4pt5F5g11QK2F6FFXo/UXdbwZEHVQvY2aztWPECdR/TkNawREHUpB03pSJ7J6Cf9gL3xOvDiiXmfAHtSplLek7qorqI/BeJjxxFG1kgNDPQjrn4VoLPozRqgCzAGXwFXILzJ8w+H6XgRegW7grcGs3gCTOfP8UgfGg139wwapxrugDl0H+oCkTZjAcsiTxBaO7HZUBI6BtfCmv4Un4aw8/RoA7wq6AO4uOhAAAAAASUVORK5CYII=) no-repeat right;width:20px;height:18px;position:absolute;top:6px;right:10px;opacity:0.6;cursor:pointer;');
  71. document.styleSheets[0].addRule('#audioTrackPicker > div:hover:before','opacity:1;');
  72. }
  73.  
  74. // Catch M3U8 files
  75. function listensend(){
  76. debuglog("listensend");
  77.  
  78. var newOpen = function(...args) {
  79. if(!document.m3u8found && args.length>=2){
  80. if(args[1].indexOf(".m3u8")>0 && document.url!=args[1]) {
  81. // m3u8 url
  82. debuglog("m3u8 found : "+args[1]);
  83. document.url = args[1];
  84. document.langs = [];
  85. document.baseurl=document.url.substring(0,document.url.lastIndexOf('/')+1);
  86. document.m3u8found=true;
  87. getpagecontent(m3u8loaded,document.url);
  88. }
  89. }
  90.  
  91. switch(args.length){
  92. case 1:
  93. open.call(this,args[0]);
  94. break;
  95. case 2:
  96. open.call(this,args[0],args[1]);
  97. break;
  98. case 3:
  99. open.call(this,args[0],args[1],args[2]);
  100. break;
  101. }
  102. }
  103.  
  104. if(typeof unsafeWindow !== "undefined"){
  105. debuglog("Window state : unsafe");
  106. let define = Object.defineProperty;
  107. let exported = exportFunction(newOpen, window);
  108. define(unsafeWindow.XMLHttpRequest.prototype, "open", {value: exported});
  109. }
  110. else {
  111. debuglog("Window state : safe");
  112. XMLHttpRequest.prototype.open = newOpen;
  113. }
  114. }
  115.  
  116. function m3u8loaded(response) {
  117. debuglog("m3u8loaded");
  118. if (typeof document.m3u8sub !== "undefined") {
  119. document.m3u8sub(response);
  120. }
  121. if (typeof document.m3u8audio !== "undefined") {
  122. document.m3u8audio(response);
  123. }
  124. }
  125.  
  126. document.m3u8audio = function(response){
  127. var lines = response.split('#');
  128. var found = false;
  129. if(lines[2].indexOf("EXT-X-INDEPENDENT-SEGMENTS")==0){
  130. // Audio tracks list
  131. var quality=null;
  132. lines.forEach(function(line) {
  133. if(line.indexOf('TYPE=AUDIO')>0) {
  134. // audio infos
  135. if(line.indexOf('GROUP-ID="eac-3"')>0 && (quality==null||quality=="eac-3")){
  136. quality="eac-3";
  137. document.audios.push(linetoarray(line));
  138. debuglog("Audio found : "+document.audios[document.audios.length-1].NAME);
  139. }
  140. else if(line.indexOf('GROUP-ID="aac-128k"')>0 && (quality==null||quality=="aac-128k")){
  141. quality="aac-128k";
  142. document.audios.push(linetoarray(line));
  143. debuglog("Audio found : "+document.audios[document.audios.length-1].NAME);
  144. }
  145. else if(line.indexOf('GROUP-ID="aac-64k"')>0 && (quality==null||quality=="aac-64k")){
  146. quality="aac-64k";
  147. document.audios.push(linetoarray(line));
  148. debuglog("Audio found : "+document.audios[document.audios.length-1].NAME);
  149. }
  150. }
  151. });
  152. }
  153. else if(response.indexOf(".mp4a")>0) {
  154. downloadmp4a(response);
  155. }
  156.  
  157. }
  158.  
  159. function downloadmp4a(m3u8data){
  160. debuglog("downloadmp4a");
  161. var lines = m3u8data.split(/\r?\n/g);
  162. var mapfound=false;
  163. var percent;
  164. var i=0;
  165. document.downloadInterval = setInterval(function () {
  166. var line = lines[i];
  167. var url=null;
  168. if(line!=null){
  169. var uri = document.audios[document.audioid].URI;
  170. if(line.indexOf("map.mp4a")>0 && !mapfound){
  171. // Get mp4a map
  172. debuglog("Download map");
  173. url = document.baseurl+uri.substring(0,uri.lastIndexOf("/")+1)+line.substring(line.indexOf('"')+1,line.lastIndexOf('"'));
  174. mapfound=true;
  175. }
  176. else if(line.indexOf("_000.mp4a")>0 && line.indexOf("DUB_CARD")<0){
  177. // Get mp4a data
  178. url = document.baseurl+uri.substring(0,uri.lastIndexOf("/")+1)+line;
  179. }
  180.  
  181. if(url!=null && !document.downloading){
  182. // Download file
  183. getpagecontent(mp4aloaded,url,true);
  184. document.downloading=true;
  185. i++;
  186. }
  187. else if(url==null){
  188. // Skip line
  189. i++;
  190. }
  191.  
  192. if(percent!=Math.round((i/lines.length)*100)){
  193. percent=Math.round((i/lines.length)*100);
  194. document.styleSheets[0].addRule('#audioTrackPicker > div:nth-child('+(document.audioid+1)+'):before','content:"'+percent+'%";');
  195. }
  196. }
  197. else {
  198. // Download finished
  199. clearInterval(document.downloadInterval);
  200. document.styleSheets[0].addRule('#audioTrackPicker > div:nth-child('+(document.audioid+1)+'):before','content:"";');
  201. exportblob(document.content, 'video/mp4');
  202. document.content=new Uint8Array();
  203. document.wait=false;
  204. }
  205. },10);
  206. }
  207.  
  208.  
  209. function mp4aloaded(response) {
  210. debuglog("mp4aloaded");
  211. document.downloading=false;
  212. document.content=appendbuffer(document.content,response);
  213. }
  214.  
  215. function linetoarray(line) {
  216. var result = new Array();
  217. var values = line.split(',');
  218. values.forEach(function(value) {
  219. var data = value.replace(/\r\n|\r|\n/g,'').split('=');
  220. if(data.length>1) {
  221. var key = data[0];
  222. var content = data[1].replace(/"/g,'');
  223. result[key]=content;
  224. }
  225. });
  226. return result;
  227. }
  228.  
  229. function buttonhandle() {
  230. var buttons = document.getElementsByClassName("control-icon-btn");
  231. if(buttons.length>0) {
  232. if (typeof document.clickhandlesub !== "undefined") {
  233. document.clickhandlesub();
  234. }
  235. if (typeof document.clickhandleaudio !== "undefined") {
  236. document.clickhandleaudio();
  237. }
  238.  
  239. document.filename = document.getElementsByClassName("title-field")[0].innerText;
  240. if(document.getElementsByClassName("subtitle-field").length>0) {
  241. document.episode = document.getElementsByClassName("subtitle-field")[0].innerText
  242. }
  243. }
  244.  
  245. if(document.oldlocation!=window.location.href&&document.oldlocation!=null) {
  246. // location changed
  247. document.m3u8found=false;
  248. document.audios = [];
  249. document.langs = [];
  250. }
  251.  
  252. document.oldlocation=window.location.href;
  253. }
  254.  
  255. document.clickhandleaudio = function() {
  256. var picker = document.getElementsByClassName("options-picker audio-track-picker");
  257. picker[0].childNodes.forEach(function(child) {
  258. var element = child.childNodes[0];
  259. var lang = element.childNodes[1].innerHTML;
  260. if(child.onclick==null) {
  261. child.onclick = selectaudio;
  262. }
  263. });
  264. }
  265.  
  266. function selectaudio(e) {
  267. debuglog("selectaudio");
  268. var width = this.offsetWidth;
  269. // Check click position
  270. if(e.layerX>=width-30&&e.layerX<=width-10&&e.layerY>=5&&e.layerY<=25){
  271. // Download audio
  272. download(this.childNodes[0].childNodes[1].innerHTML);
  273. // Cancel selection
  274. return false;
  275. }
  276. }
  277.  
  278. function download(langname) {
  279. if(!document.wait){
  280. debuglog("Download audio : "+langname);
  281. var count=0;
  282. document.audios.forEach(function(audio) {
  283. if(audio.NAME==langname) {
  284. document.audioid=count;
  285. document.ad=(audio.NAME.indexOf("[Audio Description]")>0);
  286. getpagecontent(m3u8loaded,document.baseurl+audio.URI);
  287. document.wait=true;
  288. }
  289. count++;
  290. });
  291. if(count==0){
  292. alert("An error has occurred, please reload the page.");
  293. }
  294. }
  295.  
  296. }
  297.  
  298. function getpagecontent(callback,url,binary) {
  299. debuglog("Downloading : "+url);
  300. var http=new XMLHttpRequest();
  301. http.open("GET", url, true);
  302. if(binary){
  303. http.responseType = "arraybuffer";
  304. }
  305. http.onloadend = function() {
  306. if(http.readyState == 4 && http.status == 200) {
  307. if(binary){
  308. callback(http.response);
  309. }
  310. else {
  311. callback(http.responseText);
  312. }
  313. }
  314. else if (http.status === 404) {
  315. debuglog("Not found");
  316. callback("");
  317. }
  318. else {
  319. debuglog("Unknown error, retrying");
  320. setTimeout(function () { getpagecontent(callback,url,binary); },100);
  321. }
  322. }
  323. http.send();
  324. }
  325.  
  326. function appendbuffer(buffer1, buffer2) {
  327. var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);
  328. tmp.set(new Uint8Array(buffer1), 0);
  329. tmp.set(new Uint8Array(buffer2), buffer1.byteLength);
  330. return tmp;
  331. };
  332.  
  333. // Save file as arraybuffer
  334. function exportblob(data, mimeType) {
  335. debuglog("exportblob");
  336. var blob, url;
  337. var output = document.filename;
  338. if(document.episode!="") {
  339. output+= " - "+document.episode.replace(':','');
  340. }
  341. output += "."+document.audios[document.audioid].LANGUAGE;
  342. if(document.ad){
  343. output +=".ad";
  344. }
  345. output += ".mp4";
  346.  
  347.  
  348. blob = new Blob([data], {
  349. type: mimeType
  350. });
  351. url = window.URL.createObjectURL(blob);
  352. downloadurl(url, output);
  353. setTimeout(function() {
  354. return window.URL.revokeObjectURL(url);
  355. }, 1000);
  356. };
  357.  
  358. function downloadurl(data, fileName) {
  359. debuglog("Save audio");
  360. var a;
  361. a = document.createElement('a');
  362. a.href = data;
  363. a.download = fileName;
  364. document.body.appendChild(a);
  365. a.style = 'display: none';
  366. a.click();
  367. a.remove();
  368. };
  369.  
  370. function debuglog(message){
  371. if(debug){
  372. console.log("%c [debug] "+message, 'background: #222; color: #bada55');
  373. }
  374. }
  375. })(XMLHttpRequest.prototype.open);
Add Comment
Please, Sign In to add comment