-
-
Save c3founder/0d47fe3f15f677a0a6f0e96b4868e46a to your computer and use it in GitHub Desktop.
// ==UserScript== | |
// @name Responsive YouTube with Timestamp Control for Roamresearch | |
// @author Connected Cognition Crumbs <[email protected]> | |
// @require Roam42: Wait until Roam42 loads completely | |
// @version 0.3 | |
// @description Add timestamp controls to YouTube videos embedded in Roam and makes the player responsive. | |
// Parameters: | |
// Shortcuts: for grabbing title and current time as a timestamp. | |
// grabTitleKey: if in a DIRECT child block of the YT video, | |
// grabs the title and paste it to the beginning of the current block. | |
// grabTimeKey: if in ANY child blocks of the YT video, | |
// grabs the current time of the player and paste it to the beginning. | |
// Player Size: Video height and width when the right sidebar is closed. | |
// @match https://*.roamresearch.com | |
const ytParams = { | |
//Player Size | |
vidHeight : 480, | |
vidWidth : 720, | |
//Shortcuts | |
grabTitleKey : 'alt+a t', | |
grabTimeKey : 'alt+a n' | |
}; | |
const players = new Map(); | |
var ytReady = setInterval(() => { | |
if(typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') { | |
const tag = document.createElement('script'); | |
tag.src = 'https://www.youtube.com/iframe_api'; | |
const firstScriptTag = document.getElementsByTagName('script')[0]; | |
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); | |
clearInterval(ytReady); | |
} | |
}, 1000); | |
//Fill out the current block with the given text | |
function fillTheBlock(givenTxt){ | |
var setValue = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set; | |
let newTextArea = document.querySelector("textarea.rm-block-input"); | |
setValue.call(newTextArea, givenTxt); | |
var e = new Event('input', { bubbles: true }); | |
newTextArea.dispatchEvent(e); | |
} | |
var mouseTrapReady = setInterval(() => { | |
if(Mousetrap === undefined) return; | |
Mousetrap.bind(ytParams.grabTitleKey, async function(e) { | |
e.preventDefault() | |
if (e.srcElement.localName == "textarea") { | |
var container = e.srcElement.closest('.roam-block-container'); | |
var parContainer = container.parentElement.closest('.roam-block-container'); | |
var myIframe = parContainer.querySelector("iframe"); | |
if(myIframe === null) return false; | |
var oldTxt = document.querySelector("textarea.rm-block-input").value; | |
var newValue = players[myIframe.id].getVideoData().title + " " + oldTxt; | |
fillTheBlock(newValue); | |
} | |
return false; | |
}); | |
Mousetrap.bind(ytParams.grabTimeKey, async function(e) { | |
e.preventDefault() | |
for (var plyId in players) { | |
if(players[plyId].getPlayerState() == 1){ | |
var timeStr = new Date(players[plyId].getCurrentTime() * 1000).toISOString().substr(11, 8) | |
var oldTxt = document.querySelector("textarea.rm-block-input").value; | |
fillTheBlock(timeStr + " " + oldTxt); | |
return false; | |
} | |
} | |
return false; | |
}); | |
clearInterval(mouseTrapReady); | |
}, 1000); | |
const activateYtVideos = () => { | |
if(typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') return; | |
Array.from(document.getElementsByTagName('IFRAME')) | |
.filter(iframe => iframe.src.includes('youtube.com')) | |
.forEach(ytEl => { | |
if(ytEl.closest('.rm-zoom-item') !== null) { | |
return; //ignore breadcrumbs | |
} | |
const block = ytEl.closest('.roam-block-container'); | |
if(ytEl.src.indexOf("enablejsapi") === -1){ | |
var ytId = extractVideoID(ytEl.src); | |
var frameId = "yt-" + ytEl.closest('.roam-block').id; | |
ytEl.parentElement.id = frameId; | |
ytEl.remove(); | |
players[frameId] = new window.YT.Player(frameId, { | |
height: ytParams.vidHeight, | |
width: ytParams.vidWidth, | |
videoId: ytId | |
}); | |
wrapIframe(frameId); | |
} else { | |
var frameId = ytEl.id | |
} | |
addTimestampControls(block, players[frameId]); | |
var sideBarOpen = document.getElementById("right-sidebar").childElementCount - 1; | |
//Make iframes flexible | |
adjustIframe(frameId, sideBarOpen); | |
}); | |
}; | |
const addTimestampControls = (block, player) => { | |
if (block.children.length < 2) return null; | |
const childBlocks = Array.from(block.children[1].querySelectorAll('.roam-block-container')); | |
childBlocks.forEach(child => { | |
const timestamp = getTimestamp(child); | |
const buttonIfPresent = child.querySelectorAll('.timestamp-control')[0] | |
if (buttonIfPresent) { | |
buttonIfPresent.remove(); | |
} | |
if (timestamp) { | |
addControlButton(child, () => player.seekTo(timestamp, true)); | |
} | |
}); | |
}; | |
const adjustIframe = (frameId, sideBarOpen) => { | |
var child = document.getElementById(frameId); //Iframe | |
var par = child.parentElement; | |
if(sideBarOpen){ | |
child.style.position = 'absolute'; | |
child.style.margin = '0px'; | |
child.style.border = '0px'; | |
child.style.width = '100%'; | |
child.style.height = '100%'; | |
child.style.borderStyle = 'inset'; | |
child.style.borderRadius = '25px'; | |
par.style.position = 'relative'; | |
par.style.paddingBottom = '56.25%'; | |
par.style.height = '0px'; | |
} else { | |
child.style.position = null; | |
child.style.margin = '0px'; | |
child.style.border = '0px'; | |
child.style.width = ytParams.vidWidth + 'px'; | |
child.style.height = ytParams.vidHeight + 'px'; | |
child.style.borderStyle = 'inset'; | |
child.style.borderRadius = '25px'; | |
par.style.position = null; | |
par.style.paddingBottom = '0px'; | |
par.style.height = ytParams.vidHeight + 20 + 'px'; | |
} | |
} | |
const wrapIframe = (frameId) => { | |
var child = document.getElementById(frameId); //Iframe | |
var par = document.createElement('div'); | |
child.parentNode.insertBefore(par, child); | |
par.appendChild(child); | |
child.style.position = 'absolute'; | |
child.style.margin = '0px'; | |
child.style.border = '0px'; | |
child.style.width = '100%'; | |
child.style.height = '100%'; | |
par.style.position = 'relative'; | |
par.style.paddingBottom = '56.25%'; | |
par.style.height = '0px'; | |
}; | |
const getControlButton = (block) => block.querySelectorAll('.timestamp-control')[0]; | |
const addControlButton = (block, fn) => { | |
const button = document.createElement('button'); | |
button.innerText = '►'; | |
button.classList.add('timestamp-control'); | |
button.style.borderRadius = '50%'; | |
button.addEventListener('click', fn); | |
const parentEl = block.children[0]; | |
parentEl.insertBefore(button, parentEl.querySelectorAll('.roam-block')[0]); | |
}; | |
const getTimestamp = (block) => { | |
const innerBlockSelector = block.querySelectorAll('.roam-block'); | |
const blockText = innerBlockSelector.length ? innerBlockSelector[0].textContent : ''; | |
const matches = blockText.match(/^((?:\d+:)?\d+:\d\d)\D/); // start w/ m:ss or h:mm:ss | |
if (!matches || matches.length < 2) return null; | |
const timeParts = matches[1].split(':').map(part => parseInt(part)); | |
if (timeParts.length == 3) return timeParts[0]*3600 + timeParts[1]*60 + timeParts[2]; | |
else if (timeParts.length == 2) return timeParts[0]*60 + timeParts[1]; | |
else return null; | |
}; | |
const extractVideoID = (url) => { | |
var regExp = /^(https?:\/\/)?((www\.)?(youtube(-nocookie)?|youtube.googleapis)\.com.*(v\/|v=|vi=|vi\/|e\/|embed\/\/?|user\/.*\/u\/\d+\/)|youtu\.be\/)([_0-9a-z-]+)/i; | |
var match = url.match(regExp); | |
if ( match && match[7].length == 11 ){ | |
return match[7]; | |
}else{ | |
return null; | |
} | |
}; | |
setInterval(activateYtVideos, 1000); |
Hi Yulin-Rog, you need to install the new version of the code. Here is the link with what you need plus three demo videos:
https://c3founder.github.io/Roam-Enhancement/
hi, There is no alt key for mac, what shortcut can I use? a lot of thanks.
Hi, you can see all of the possible key combinations here:
https://craig.is/killing/mice
I don't have Mac but I assume you can replace all 'alt' with 'option' and things should work.
thanks
I replaced all 'alt' with 'option', and when I type 'option+a+t' in a child block of the YT video, it just shows 'å†', nothing else happened, then I replaced all 'option' with 'command', nothing changed neither.🤣
P.S. I only install the code above,
thanks
I replaced all 'alt' with 'option', and when I type 'option+a+t' in a child block of the YT video, it just shows 'å†', nothing else happened, then I replaced all 'option' with 'command', nothing changed neither.🤣
P.S. I only install the code above,
I have the same problem...😂
A couple of points to test/consider:
- You need roam42 installed.
- I was told by other mac users (@abhay) that the weird 'å†' can be fixed as follow: "you can disable the special characters by switching your input keyboard to Unicode HEX"
- Make sure that they are no other conflicting extension that uses alt+a. For example, I was told that the roam highlighter uses that.
thanks
I replaced all 'alt' with 'option', and when I type 'option+a+t' in a child block of the YT video, it just shows 'å†', nothing else happened, then I replaced all 'option' with 'command', nothing changed neither.🤣
P.S. I only install the code above,
@growingtreesss @CherryC99 Just use ctrl
@c3founder thanks for your patience and kind advices
@alanzchen thanks for your kind advice also
I tried the methods you mentioned above:
- Yes. even tried roam42 test version once(deleted later), roam42 preserved.
- successfully switching to Unicode HEX, 'option' or 'ctrl' didn't work
...then I used a Win to check , press "alt+a+n" , no response
my workflow is:
- install roam42
- install codes in https://c3founder.github.io/Roam-Enhancement/
- embed youtube video in roam
- use shortcuts in a child block of the YT video
Are there any steps I'm missing?
@c3founder thanks for your patience and kind advices
@alanzchen thanks for your kind advice alsoI tried the methods you mentioned above:
- Yes. even tried roam42 test version once(deleted later), roam42 preserved.
- successfully switching to Unicode HEX, 'option' or 'ctrl' didn't work
...then I used a Win to check , press "alt+a+n" , no responsemy workflow is:
- install roam42
- install codes in https://c3founder.github.io/Roam-Enhancement/
- embed youtube video in roam
- use shortcuts in a child block of the YT video
Are there any steps I'm missing?
same error ! windows doesn't work! If there is a button, testing is easier. The shortcut often conflict!!
@c3founder thanks for your patience and kind advices
@alanzchen thanks for your kind advice alsoI tried the methods you mentioned above:
- Yes. even tried roam42 test version once(deleted later), roam42 preserved.
- successfully switching to Unicode HEX, 'option' or 'ctrl' didn't work
...then I used a Win to check , press "alt+a+n" , no responsemy workflow is:
- install roam42
- install codes in https://c3founder.github.io/Roam-Enhancement/
- embed youtube video in roam
- use shortcuts in a child block of the YT video
Are there any steps I'm missing?
I want to make this question/answer more structured. Can you please initiate an issue here:
https://github.com/c3founder/Roam-Enhancement/issues
Also, sorry that I'm checking the basics but this can happen, make sure that the code block is indented under {{[[roam/js]]}}.
the issue is updated here c3founder/Roam-Enhancement#1
I'm using a mac. I've changed the shortcuts to ctrl+a n and ctrl+a t but for some reason it's not picking up the change. The new shortcut is does nothing but the original alt+ still works (even though I'm on a mac). Any ideas?
Hi having trouble installing. When I copy from https://c3founder.github.io/Roam-Enhancement/ nothing changes to my embedded youtube videos. I am indenting and placing it correctly, I have installed other roam/js code blocks without issue.
I can get the rounded corners on my youtube videos but only if I place this https://gist.github.com/c3founder/0d47fe3f15f677a0a6f0e96b4868e46a#file-responsive-timestamped-youtube-js
in to the javascript code block. But I don't have the timestamp button. I also don't have the ability to resize the youtube window. I really like the idea of working with youtube videos in Roam research. Any help would be appreciated!
Also the page, if entered in to a browser window, https://c3founder.github.io/Roam-Enhancement/enhancedX.css
States that the above file can not be found. It is giving me a 404 error.
Hi having trouble installing. When I copy from https://c3founder.github.io/Roam-Enhancement/ nothing changes to my embedded youtube videos. I am indenting and placing it correctly, I have installed other roam/js code blocks without issue.
I can get the rounded corners on my youtube videos but only if I place this https://gist.github.com/c3founder/0d47fe3f15f677a0a6f0e96b4868e46a#file-responsive-timestamped-youtube-js
in to the javascript code block. But I don't have the timestamp button. I also don't have the ability to resize the youtube window. I really like the idea of working with youtube videos in Roam research. Any help would be appreciated!Also the page, if entered in to a browser window, https://c3founder.github.io/Roam-Enhancement/enhancedX.css
States that the above file can not be found. It is giving me a 404 error.
Hey,
X here is a template!
https://c3founder.github.io/Roam-Enhancement/enhanced**X**.css
e.g., use this for YT:
@import url('https://c3founder.github.io/Roam-Enhancement/enhancedYouTube.css');
Hi there! I think i installed roam/js and code for Timestamp properly, but its not functioning after I implement the code and relaunching the browser multiple times😭 I mean it look the same as the original embed, cant resize, cant grab timestamp
any help on that plz?