Last active
September 25, 2023 06:25
-
-
Save jangxx/ac4985fbfbf8b44bf12854768b7939c0 to your computer and use it in GitHub Desktop.
A userscript to extract video URLs from video embedded into RWTHonline, which are not uploaded as regular files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name RWTHmoodle Opencast Video Catcher | |
// @namespace https://literalchaos.de | |
// @version 0.2 | |
// @description Captures video urls played by the player embedded into RWTHmoodle | |
// @author Jan Scheiper | |
// @match https://moodle.rwth-aachen.de/* | |
// @match https://engage.streaming.rwth-aachen.de/* | |
// @grant GM_webRequest | |
// @grant GM_xmlhttpRequest | |
// @downloadURL https://gist.github.com/jangxx/ac4985fbfbf8b44bf12854768b7939c0/raw/rwthmoodle_video_urls.user.js | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
if (window == window.top && window.location.href.includes("moodle")) { | |
let containerNode = document.createElement("div"); | |
containerNode.innerHTML = `<b>Captured video URLs:</b>`; | |
containerNode.style.cssText = "position: absolute; top: 50px; right: 10px; background-color: white; padding: 10px; border-width: 1px; border-style: solid; border-color: black"; | |
let listNode = document.createElement("ul"); | |
listNode.style.cssText = "margin: 5px 0px"; | |
containerNode.appendChild(listNode); | |
let elemAppended = false; | |
window.addEventListener("message", msgRaw => { | |
let msg = JSON.parse(msgRaw.data); | |
if (msg.type == "captured") { | |
let listElem = document.createElement("li"); | |
listElem.innerHTML = `<a href="${msg.url}">Download</a> <input type="text" value="${msg.title}" onclick="this.select()" size="60" readonly>`; | |
listElem.style.cssText = "margin: 2px 0px;"; | |
listNode.appendChild(listElem); | |
if (!elemAppended) { | |
elemAppended = true; | |
document.querySelector("nav.fixed-top.navbar").appendChild(containerNode); | |
} | |
} | |
}); | |
} else { | |
let captured = []; | |
GM_webRequest([ | |
{ "selector": "*episode.json*" , "action": { redirect: { from: "(.*)", to: "$1" } } } // redirect to same url to be able to get the url and it's parameters | |
], (info, message, details) => { | |
let url = details.url; | |
if (!captured.includes(url)) { | |
captured.push(url); | |
let xhr = new XMLHttpRequest(); | |
xhr.open("GET", url); | |
xhr.send(); | |
xhr.addEventListener("load", () => { | |
let body; | |
try { | |
body = JSON.parse(xhr.response); | |
} catch(e) { | |
console.error(e); | |
return; | |
} | |
let tracks = body["search-results"].result.mediapackage.media.track; | |
let track = tracks.find(t => t.url.includes(".mp4")); | |
let title = body["search-results"].result.dcTitle; | |
if (track != null) { | |
console.log(`Captured: ${title}`); | |
console.log(track.url); | |
window.top.postMessage(JSON.stringify({ | |
type: "captured", | |
title, | |
url: track.url | |
}), "*"); | |
} | |
}); | |
} | |
}); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment