Created
December 15, 2018 13:04
-
-
Save rubyu/bebedb90f8a5c707914f177b8c714e44 to your computer and use it in GitHub Desktop.
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 HIDIVE Screenshot | |
// @version 1.0 | |
// @description Tested on Chrome 64 and Firefox 61 with Tampermonkey 4.7. | |
// @include /^https?://www\.hidive\.com/stream/.*$/ | |
// @require http://html2canvas.hertzen.com/dist/html2canvas.js | |
// @grant GM_notification | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
// The trigger key to capture screenshot. | |
const invocationKey = "F9"; | |
// Modifier keys required when the trigger key to be activated. (acceptable values: "alt", "ctrl", "shift", "meta") | |
const invocationKeyModifiers = []; | |
// Mime type of output image file. (acceptable values: "image/png", "image/jpeg", "image/webp") | |
const outputMimeType = "image/png"; | |
// Quality argument indicates the quality of output image file. (range: 0.0 to 1.0; 1.0 is best and 0.0 is worst) | |
// Note: png encoder won't be effected by this parameter because it is a lossless format. | |
const outputQuality = 0.9; | |
// Add episode title to the filename if true. | |
const outputEpisodeTitle = true; | |
// Set to true if you need to pause the video to capture it precisely. | |
const pausePlaybackBeforeCapturing = false; | |
// Set to true if you need to focus the player element to control by keys assigned to it. | |
const focusPlayerOnLoad = true; | |
// Set to true if you need to focus the player element after capturing. | |
const focusPlayerAfterCapturing = true; | |
// Settings for notification feature. | |
const notificationEnabled = true; | |
const notificationTimeout = 2000; | |
const appName = "HIDIVE Screenshot"; | |
function saveCavnasAsImageFile(canvas, filename) { | |
canvas.toBlob(function (blob) { | |
const link = document.createElement("a"); | |
link.download = filename; | |
link.href = window.URL.createObjectURL(blob); | |
dispatchClickEvent(link); | |
}, outputMimeType, outputQuality); | |
} | |
function dispatchClickEvent(target) { | |
const evnt = document.createEvent("MouseEvents"); | |
evnt.initMouseEvent("click", { | |
view: window, | |
bubbles: true, | |
cancelable: true | |
}); | |
target.dispatchEvent(evnt); | |
} | |
function parseSeconds(seconds) { | |
const sec = Math.floor(seconds); | |
const msec = Math.floor((seconds - sec) * 1000); | |
const minute = Math.floor(sec / 60); | |
const hour = Math.floor(minute / 60); | |
return { | |
msec: msec, | |
sec: sec % 60, | |
minute: minute % 60, | |
hour: hour | |
}; | |
} | |
function lzerofill(obj, minLength) { | |
const str = obj.toString(); | |
return ("0".repeat(minLength) + str).slice(-Math.max(minLength, str.length)); | |
} | |
function secondsToCurrentTimeString(seconds) { | |
const ct = parseSeconds(seconds); | |
return lzerofill(ct.hour, 2) + "_" + lzerofill(ct.minute, 2) + "_" + lzerofill(ct.sec, 2) + "." + lzerofill(ct.msec, 3); | |
} | |
function getPrefferedExtension() { | |
if (outputMimeType == "image/png") return "png"; | |
else if (outputMimeType == "image/jpeg") return "jpg"; | |
else if (outputMimeType == "image/webp") return "webp"; | |
else return outputMimeType.split("/")[1]; | |
} | |
function removeQuotes(str) { | |
return str.replace("“", "").replace("”", ""); | |
} | |
function getPrefferedFileName(currentTime) { | |
const title = document.querySelector(".bottom-gutter-15 h1 a").textContent; | |
const descriptions = document.querySelectorAll("#StreamTitleDescription h2"); | |
const seasonAndEpisode = descriptions[0].textContent.replace(/^ /, "").replace(/ \|.+/, ""); | |
const episodeTitle = descriptions[1].textContent; | |
const ct = secondsToCurrentTimeString(currentTime); | |
const ext = getPrefferedExtension(); | |
return title + " [" + seasonAndEpisode + "] " + episodeTitle + " [" + ct + "]." + ext; | |
} | |
if (focusPlayerOnLoad) { | |
window.addEventListener("load", function(evnt) { | |
const player = document.getElementById("rmpPlayer"); | |
player.focus(); | |
}); | |
} | |
document.addEventListener("keydown", function(evnt) { | |
if (evnt.key != invocationKey || | |
invocationKeyModifiers.indexOf("alt") >= 0 && !evnt.altKey || | |
invocationKeyModifiers.indexOf("ctrl") >= 0 && !evnt.ctrlKey || | |
invocationKeyModifiers.indexOf("shift") >= 0 && !evnt.shiftKey || | |
invocationKeyModifiers.indexOf("meta") >= 0 && !evnt.metaKey) { | |
return; | |
} | |
try { | |
console.log(appName + " was invoked"); | |
const player = document.getElementById("rmpPlayer"); | |
const action = player; | |
const vs = player.getElementsByClassName("rmp-video")[0]; | |
const sub = player.getElementsByClassName("rmp-cc-area")[0]; | |
if (pausePlaybackBeforeCapturing) { | |
dispatchClickEvent(action); | |
} | |
const w = vs.clientWidth; | |
const h = vs.clientHeight; | |
console.log("width: " + w); | |
console.log("height: " + h); | |
const canvas = document.createElement("canvas"); | |
canvas.width = w; | |
canvas.height = h; | |
const ctx = canvas.getContext("2d"); | |
ctx.drawImage(vs, 0, 0, w, h); | |
html2canvas(sub, {backgroundColor: null}).then(function(sub_canvas) { | |
if (sub_canvas.width > 0 && sub_canvas.height > 0) { | |
//ctx.drawImage(sub_canvas, 0, sub.offsetTop, w, h); | |
ctx.drawImage(sub_canvas, 0, 0, w, h); | |
} | |
const filename = getPrefferedFileName(vs.currentTime); | |
saveCavnasAsImageFile(canvas, filename); | |
const successMessage = "Screenshot was saved to \"" + filename + "\""; | |
console.log(successMessage); | |
if (notificationEnabled) { | |
GM_notification({ | |
image: "http://d10xkldqejj5hr.cloudfront.net/misc/HD_Logo_PR.png", | |
text: successMessage, | |
timeout: notificationTimeout | |
}); | |
} | |
if (focusPlayerAfterCapturing) { | |
player.focus(); | |
} | |
}); | |
} catch (ex) { | |
const errorMessage = "An error has occurred: " + ex.toString(); | |
console.log(errorMessage); | |
if (notificationEnabled) { | |
GM_notification({ | |
image: "http://d10xkldqejj5hr.cloudfront.net/misc/HD_Logo_PR.png", | |
title: "Oops!", | |
text: errorMessage, | |
timeout: 10000 | |
}); | |
} | |
} | |
// Cancel the key down event. | |
return false; | |
}); | |
document.addEventListener("keyup", function(evnt) { | |
if (evnt.key != invocationKey || | |
invocationKeyModifiers.indexOf("alt") >= 0 && !evnt.altKey || | |
invocationKeyModifiers.indexOf("ctrl") >= 0 && !evnt.ctrlKey || | |
invocationKeyModifiers.indexOf("shift") >= 0 && !evnt.shiftKey || | |
invocationKeyModifiers.indexOf("meta") >= 0 && !evnt.metaKey) { | |
return; | |
} | |
// Cancel the key up event. | |
return false; | |
}); | |
console.log(appName + " was loaded"); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment