Skip to content

Instantly share code, notes, and snippets.

@jangxx
Last active September 25, 2023 06:25
Show Gist options
  • Save jangxx/ac4985fbfbf8b44bf12854768b7939c0 to your computer and use it in GitHub Desktop.
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.
// ==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