gur111

download OpenU Video Recordings

Jul 30th, 2019
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var downloadedFilesCounter = 0;
  2. var numOfChunksToDownload;
  3. var downloadQueue = [];
  4. var currentDownloadName;
  5. var status = "idle";
  6. var theWindow = null;
  7. var firstTimeOpenWindow = 1;
  8.  
  9. var chunksBaseUrl, quality, chunksURLQuery;
  10.  
  11. function updataStatus(){
  12.     downloadedFilesCounter++;
  13.     let completedPercentage = (downloadedFilesCounter / (numOfChunksToDownload+1) ) ;
  14.     let fullWidth = $("#progressBar"+downloadQueue[0].playlistid).width();
  15.     let percentageDivWidth = $("#progressBarPercent"+downloadQueue[0].playlistid).width();
  16.     let updatedWidth = parseInt(completedPercentage*fullWidth);
  17.     if ( updatedWidth > percentageDivWidth)
  18.         $("#progressBarPercent"+downloadQueue[0].playlistid).css("width", updatedWidth);
  19.     if ( downloadedFilesCounter == (numOfChunksToDownload+1)  )
  20.         $("#progressBarPercent"+downloadQueue[0].playlistid).css({"background-color": "#e91e63", "width":"100%"}).text("ההורדה הושלמה!");
  21.     else
  22.         $("#progressBarPercent"+downloadQueue[0].playlistid).text("בהורדה: " + parseInt(completedPercentage*100) + "%");
  23. }
  24.  
  25. var tmrCheckPlaylistLoad;
  26. var currentOpenCollectionId = $("#ovc_collections_list").find("li.active").find("a").attr("c-value");
  27. addDownloadButtons(currentOpenCollectionId);
  28.  
  29. // add click event for all download buttons
  30. $(document).on("click", ".downloadButton", function(){
  31.     var url = "https://opal.openu.ac.il/mod/ouilvideocollection/actions.php";
  32.     var context = $(this).attr('context');
  33.     var playlistId = $(this).attr('playlistid');
  34.     downloadQueue.push( { context: context, playlistid: playlistId } );
  35.  
  36.     // add progress bar
  37.     let videoTop = $("#playlist"+playlistId).find(".ovc_playlist_border");
  38.     let progressBarDiv = $("<div id='progressBar"+playlistId+"'></div>").css({"background-color": "#01579B"});
  39.     let progressBarPercentDiv = $("<div id='progressBarPercent"+playlistId+"'>ממתין להתחלת הורדה... <a href='javascript:void(0);' class='cancelDownload' context="+context+" playlistid="+playlistId+" style='color:lightgreen;font-size: 120%;margin-right:10px;'><b>בטל</b></a></div>").css({"color": "white"});
  40.     progressBarDiv.append(progressBarPercentDiv);
  41.     videoTop.prepend(progressBarDiv);
  42.  
  43.     $(".downloadButton[playlistid="+playlistId+"]").hide();
  44.  
  45.     getVideosOnQueue();
  46. });
  47.  
  48. // add click event for all cancel download buttons
  49. $(document).on("click", ".cancelDownload", function(){
  50.     var playlistId = $(this).attr('playlistid');
  51.     downloadQueue = downloadQueue.filter(video => video.playlistid !== playlistId );
  52.     $("#progressBar"+playlistId).remove();
  53.     $(".downloadButton[playlistid="+playlistId+"]").show();
  54. });
  55.  
  56.  
  57. // automatically add download buttons when a new collection is loaded
  58. function onPlaylistLoad(){
  59.     $(".collection_link").each(function(){
  60.         $(this).on("click", function(){
  61.             var cValue = $(this).attr("c-value");
  62.             tmrCheckPlaylistLoad = setInterval(function(){handleCollectionChange(cValue)}, 300);
  63.         });  
  64.     });
  65. }
  66. onPlaylistLoad();
  67.  
  68. function handleCollectionChange (cValue) {
  69.     if( $('#collection'+cValue).is(':visible') ){
  70.         addDownloadButtons(cValue);
  71.         clearInterval(tmrCheckPlaylistLoad);
  72.     }
  73. }
  74.  
  75. // adds download buttons to an open collection( a collection that has been loaded )
  76. function addDownloadButtons(collectionId) {
  77.     // add buttons only if not been added before
  78.     if ( $( "#collection"+collectionId ).find("button").length == 0 ) {
  79.         var collectionDiv = $("#collection"+collectionId);
  80.         var currentContext = collectionDiv.attr("cid");
  81.         var videoCount = 0;
  82.         collectionDiv.children().each(function(i) {
  83.             let videoDescription = $(this).find("span.instructor_row");
  84.             let currentPlaylistId = $(this).attr("id").substring(8);
  85.             let buttonElement = $("<button></button>").text("הורד סרטון").attr('class','downloadButton').attr('context',currentContext).attr('playlistid',currentPlaylistId);
  86.             buttonElement.css({"margin-right":"10px","background":"rgb(202, 60, 60)","color":"white","borderRadius":"4px","textShadow":"0 1px 1px rgba(0, 0, 0, 0.2)"});
  87.             videoDescription.append(buttonElement);
  88.         });
  89.     }
  90. }
  91.  
  92.  
  93. function getPlaylistFile(context, playlistid){
  94.     var courseIdStart = $('.coursename_header').children()[0].href.indexOf("id=");
  95.     var courseIdNum = $('.coursename_header').children()[0].href.substring(courseIdStart+3);
  96.     jQuery.ajax({
  97.         type: "POST",
  98.         url: "https://opal.openu.ac.il/mod/ouilvideocollection/actions.php",
  99.         data: {action: "getplaylist", context: context, playlistid: playlistid, course: courseIdNum},
  100.         success: function(data) {
  101.           let anotherURL = "https://opal.openu.ac.il/local/ouil_video/player.php?mediaid=" + data.media.cipher;
  102.           currentDownloadName = data.title;
  103.            
  104.                     $.get(anotherURL, function(data) {
  105.                         let mediaStart = data.indexOf("media: ");
  106.                         let mediaEnd = data.indexOf("\"", mediaStart+11);
  107.                         let myMedia = data.substring(mediaStart+8, mediaEnd);
  108.                         let url = myMedia;
  109.  
  110.                         $.get(url, function(data) {
  111.                             let playlistStart = data.indexOf("file=")+5;
  112.                             let playlistEnd = data.indexOf("\"", playlistStart+8);
  113.                             var playlistURL = data.substring(playlistStart+1, playlistEnd).replace("&amp;", "&");
  114.                             let url = playlistURL;
  115.                        
  116.                             $.get(url, function(data) {
  117.                                 let baseURL = playlistURL.substring(0, playlistURL.indexOf("playlist."))
  118.                                 let quality_list = data.match(/BANDWIDTH=\d+/g).map(function(n){return parseInt(n.replace("BANDWIDTH=", ""))}).sort(function(a,b){ return a-b; });
  119.                                 let highestQuality = quality_list[quality_list.length-1];
  120.                                 let URLQuery = playlistURL.substring(playlistURL.indexOf("?"));
  121.  
  122.                                 chunksBaseUrl = baseURL;
  123.                                 quality = highestQuality;
  124.                                 chunksURLQuery = URLQuery;
  125.                                 let url = chunksBaseUrl+"chunklist_b"+quality+".m3u8"+chunksURLQuery;
  126.                                 $.get(url, function(data) {
  127.                                     data = data.split("\n");
  128.                                     let lastChunkLine = data[data.length-3];
  129.                                     let lastChunkStart = lastChunkLine.indexOf("_", lastChunkLine.indexOf(quality));
  130.                                     let lastChunkEnd = lastChunkLine.indexOf(".ts");
  131.                                     let lastChunkNum = lastChunkLine.substring(lastChunkStart+1, lastChunkEnd);
  132.                                     numOfChunksToDownload = parseInt(lastChunkNum);
  133.                                     startVideoDownload();
  134.                                 });
  135.                             });
  136.                         }, "text");  
  137.                     });    
  138.         }
  139.     });    
  140. }
  141.  
  142. function getVideosOnQueue(){
  143.     if ( downloadQueue.length > 0 && status === "idle"  ){
  144.         status = "downloading";        
  145.         $("#progressBar"+downloadQueue[0].playlistid).css({"background-color": "#ddd"});
  146.         $("#progressBarPercent"+downloadQueue[0].playlistid).css({"background-color": "#4CAF50", "display": "inline-block", "font-weight": "bold"}).html("בהורדה: 0%");
  147.         getPlaylistFile(downloadQueue[0].context, downloadQueue[0].playlistid);
  148.     }
  149. }
  150.  
  151. function startVideoDownload(){
  152.     if ( theWindow === null ){
  153.         theWindow = window.open('https://opal.openu.ac.il/'+new Date().getTime(), "", 'toolbar=no,status=no,width=250,height=100');
  154.         if (theWindow == null || typeof(theWindow)=='undefined') {  
  155.             alert('יש לאפשר פתיחת חלון נוסף (popup). ליד שורת הכתובת בדפדפן מופיע סימן קטן של אפשרות לאפשר popup,\n יש ללחוץ עליו ולבחור ב "Always allow pop-ups from. לאחר מכאן לרענן את הדף ולהפעיל שוב את הסקריפט. אחרי פעולה זה הסקריפט יפעל כהלכה.');
  156.         }
  157.     }
  158.     var theDoc = theWindow.document,
  159.     theScript = document.createElement('script');
  160.  
  161.     function injectThis() {
  162.         var fileData = [];
  163.  
  164.         function addData(data, index){
  165.             fileData[index] = data;
  166.             window.opener.updataStatus();
  167.             if ( window.opener.downloadedFilesCounter == (window.opener.numOfChunksToDownload+1) ){
  168.                 saveDownloadedFile();
  169.                 setTimeout(function(){window.opener.windowFinishedDownloading()}, 200);                
  170.             }
  171.         }
  172.  
  173.         function startVideoDownload(chunksBaseUrl, quality, chunksURLQuery){
  174.             for (i = 0; i <= window.opener.numOfChunksToDownload; i++) {
  175.                 let currentIndex = i;
  176.                 let xhr = new XMLHttpRequest();
  177.                 let url=chunksBaseUrl+"media_b"+quality+"_"+i+".ts"+chunksURLQuery;
  178.                 xhr.open('GET', url, true);
  179.                 xhr.responseType = 'blob';
  180.                 xhr.onload = function(e) {
  181.                      addData(xhr.response, currentIndex);
  182.                 }
  183.                 xhr.addEventListener("error", function(){ retryFailedRequest(chunksBaseUrl, quality, chunksURLQuery, currentIndex); });  
  184.                 xhr.send();
  185.             }
  186.         }
  187.  
  188.         function retryFailedRequest(chunksBaseUrl, quality, chunksURLQuery, chunkNumber){
  189.             let currentIndex = chunkNumber;
  190.             let xhr = new XMLHttpRequest();
  191.             let url = chunksBaseUrl+"media_b"+quality+"_"+currentIndex+".ts"+chunksURLQuery;
  192.             xhr.open('GET', url, true);
  193.             xhr.responseType = 'blob';
  194.             xhr.onload = function(e) {
  195.                 addData(xhr.response, currentIndex);
  196.             }
  197.             xhr.addEventListener("error", function(){ setTimeout(function(){ retryFailedRequest(chunkStartUrl, chunkEndNameWithoutExtension, chunkNumber); }, 5000); });
  198.             xhr.send();
  199.         }
  200.  
  201.         function saveDownloadedFile() {
  202.             let blob = new Blob(fileData, {type: "video/mp2t"});
  203.             let a = document.body.appendChild(document.createElement('a'));
  204.             let objectURL2 = URL.createObjectURL(blob);
  205.             a.href = objectURL2;
  206.             a.download = window.opener.currentDownloadName+".ts";
  207.             a.click();
  208.             a.remove(a);
  209.  
  210.             URL.revokeObjectURL(objectURL2);
  211.             blob = null;
  212.             a = null;
  213.  
  214.             // reset data for next download
  215.             fileData = [];
  216.             window.opener.downloadedFilesCounter = 0;
  217.             window.opener.status = "idle";
  218.             window.opener.downloadQueue.shift();  
  219.         }
  220.        
  221.         startVideoDownload(window.opener.chunksBaseUrl, window.opener.quality, window.opener.chunksURLQuery);
  222.     }
  223.     if ( firstTimeOpenWindow ){
  224.         theScript.innerHTML = 'window.onload = ' + injectThis.toString() + ';';
  225.         firstTimeOpenWindow = 0;
  226.     }
  227.     else {
  228.         theScript.innerHTML = injectThis.toString() + 'injectThis();';
  229.     }
  230.     theDoc.body.appendChild(theScript);  
  231. }
  232.  
  233. function windowFinishedDownloading(){
  234.     if ( downloadQueue.length === 0 ){
  235.         theWindow.close();
  236.         theWindow = null;
  237.         firstTimeOpenWindow = 1;
  238.     }
  239.     else {        
  240.         theWindow.location.reload();
  241.         getVideosOnQueue();
  242.     }
  243. }
Add Comment
Please, Sign In to add comment