|
// ==UserScript== |
|
// @name Odysee - Direct URL Button |
|
// @match https://odysee.com/*/* |
|
// @grant none |
|
// @version 0.0.2 |
|
// @author aequabit |
|
// @description Adds a button to the video action bar, which links to the video source file |
|
// @downloadURL https://gist.github.com/aequabit/9390d0fc686337410d4e854ffb9549d2/raw/odysee-direct-url-button.user.js |
|
// ==/UserScript== |
|
|
|
// https://stackoverflow.com/a/35385518 |
|
const fromHTML = (html, trim = true) => { |
|
// Process the HTML string. |
|
html = trim ? html.trim() : html; |
|
if (!html) return null; |
|
|
|
// Then set up a new template element. |
|
const template = document.createElement('template'); |
|
template.innerHTML = html; |
|
const result = template.content.children; |
|
|
|
// Then return either an HTMLElement or HTMLCollection, |
|
// based on whether the input HTML had one or more roots. |
|
if (result.length === 1) return result[0]; |
|
return result; |
|
}; |
|
|
|
async function waitFor(conditional, interval = 20) { |
|
return new Promise((resolve) => { |
|
const _waitForInterval = setInterval(() => { |
|
if (conditional() === true) { |
|
clearInterval(_waitForInterval); |
|
resolve(); |
|
} |
|
}, interval); |
|
}); |
|
} |
|
|
|
(async () => { |
|
// Wait for the video action bar to appear and add the button |
|
await waitFor(() => document.querySelector("div.media__actions") !== null, 100); |
|
const divMediaActions = document.querySelector("div.media__actions"); |
|
const linkDirectUrl = fromHTML(` |
|
<a aria-label="Copy direct URL" class="button button--no-style button--disabled button--file-action" type="button" target="_blank" disabled> |
|
<span class="button__content" |
|
><svg |
|
xmlns="http://www.w3.org/2000/svg" |
|
viewBox="0 0 24 24" |
|
width="16" |
|
height="16" |
|
fill="none" |
|
stroke="currentColor" |
|
stroke-width="2" |
|
stroke-linecap="round" |
|
stroke-linejoin="round" |
|
class="icon icon--CopyLink" |
|
aria-hidden="true" |
|
> |
|
<g> |
|
<path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path> |
|
<path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path> |
|
</g> |
|
</svg> |
|
<span dir="auto" class="button__label">Direct URL</span></span |
|
> |
|
</a> |
|
`); |
|
|
|
divMediaActions.insertBefore(linkDirectUrl, divMediaActions.lastChild); |
|
|
|
// Wait for the player to load, set the link href and enable the button |
|
await waitFor(() => window.player?.claimSrcOriginal?.src !== undefined, 100); |
|
linkDirectUrl.href = window.player?.claimSrcOriginal?.src; |
|
linkDirectUrl.classList.remove("button--disabled"); |
|
linkDirectUrl.attributes.removeNamedItem("disabled") |
|
})(); |