Skip to content

Instantly share code, notes, and snippets.

@jlyon
Created June 24, 2018 04:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jlyon/3e01d72e87cb3c35de4588e7e549e60d to your computer and use it in GitHub Desktop.
Save jlyon/3e01d72e87cb3c35de4588e7e549e60d to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<body>
<!--
YouTube Video bookmark selector.
A Handlebars-based selector to create quicklink breakpoints on a Youtube video
-->
<div class="row">
<div class="col-md-6">
<button id="youtube-add" class="btn btn-default"><i class="fa fa-plus-circle fa-fw"></i>Add bookmark at current video time</button>
<div id="youtube-new" class="hide">
<button id="youtube-update-time" class="btn btn-default"><i class="fa fa-sync fa-fw"></i>Update bookmark time</button>
<form class="form-inline">
<input id="youtube-new-label" type="text" class="form-control" placeholder="Enter label" required>
<div class="input-group">
<input id="youtube-new-time" type="number" class="form-control input-youtube-time" required>
<div class="input-group-append">
<span class="input-group-text">secs</span>
</div>
</div>
<button id="youtube-new-submit" type="submit" class="btn btn-primary mb-2">Add</button>
</form>
</div>
<script id="youtube-list-template" type="text/x-handlebars-template">
<ul class="list-group">
{{#each youtube}}
<li class="list-group-item">
{{this.label}}
<span class="badge badge-default pull-right">
<a href="#" data-youtube-seek="{{this.seconds}}">{{this.seconds}} seconds</a>
</span>
<button type="button" class="close" aria-label="Close" data-youtube-remove="{{@index}}">
<span aria-hidden="true">&times;</span>
</button>
</li>
{{else}}
<p>Meeting videos can be long! Use bookmarks to help visitors find the part they are looking for.</p>
<p>Press play, find the correct place in the video and click the button above to add a bookmark.</p>
{{/each}}
</ul>
</script>
<div id="youtube-list"></div>
</div>
<div class="col-md-6">
<div id="player"></div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.11/handlebars.min.js"></script>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
youtube
<input type="text" id="youtube-input" />
<input type="text" id="bookmark-input" value='[{"label":"uytfyfu","seconds":"5"}]' />
<script>
var bookmarkInput = '#bookmark-input';
var youtubeInput = '#youtube-input';
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady() {
setVideo();
}
function setVideo() {
var val = $(youtubeInput).val();
if (!val) {
return;
}
var pattern = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/;
var matches = val.match(pattern);
var id = matches != null && matches[2] ? matches[2] : val;
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
playerVars: { 'autoplay': 1, 'controls': 1 },
});
$(youtubeInput).val(id);
}
$(youtubeInput).bind('change', function() {
setVideo();
})
var source = document.getElementById("youtube-list-template").innerHTML;
var template = Handlebars.compile(source);
function renderYoutubeList() {
var html = template({youtube: youtube});
var $html = $(html);
$html.find('button[data-youtube-remove]').bind('click', function(e) {
e.preventDefault();
youtube.splice($(this).data('youtube-remove'), 1);
setYoutube();
renderYoutubeList();
});
$html.find('button[data-youtube-seek]').bind('click', function(e) {
e.preventDefault();
player.seekTo($(this).data('youtube-seek'));
});
$('#youtube-list').html($html);
}
function getYoutube() {
var val = $(bookmarkInput).val();
if (!val) {
return [];
}
try {
return JSON.parse(val);
}
catch(error) {
return [];
}
}
var youtube = getYoutube();
function setYoutube() {
$(bookmarkInput).val(JSON.stringify(youtube));
}
renderYoutubeList();
$('#youtube-add').bind('click', function(e) {
e.preventDefault();
$('#youtube-new-time').val(Math.round(player.getCurrentTime()));
$('#youtube-new-label').val('');
$('#youtube-new').show();
$('#youtube-add').hide();
player.pauseVideo();
});
$('#youtube-update-time').bind('click', function(e) {
e.preventDefault();
$('#youtube-new-time').val(Math.round(player.getCurrentTime()));
player.pauseVideo();
});
$('#youtube-new-submit').bind('click', function(e) {
e.preventDefault();
youtube.push({
label: $('#youtube-new-label').val(),
seconds: $('#youtube-new-time').val()
});
setYoutube();
console.log(youtube);
renderYoutubeList();
$('#youtube-new').hide();
$('#youtube-add').show();
});
$('#youtube-new-time').bind('change', function(e) {
player.seekTo($(this).val());
player.pauseVideo();
});
</script>
<style>
.hidden {
display: none;
}
input.input-youtube-time {
width: 80px !important;
}
</style>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment