SHOW:
|
|
- or go back to the newest paste.
| 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("&", "&");
| |
| 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 | } |