Skip to content

Instantly share code, notes, and snippets.

@ajwinn
Created October 25, 2013 07:48
Show Gist options
  • Save ajwinn/7150928 to your computer and use it in GitHub Desktop.
Save ajwinn/7150928 to your computer and use it in GitHub Desktop.
The first commented line is your dabblet’s title
/**
* The first commented line is your dabblet’s title
*/
background: white;
background: white;
min-height: 100%;
<!-- YouTube -->
<div id="yt_status">YouTube</div>
<div id="yt_player"></div>
<!-- Vimeo -->
<div id="v_status">Vimeo</div>
<div id="v_player"></div>
<!-- Test Controls -->
<table>
<tr>
<td>Time:<span id="time"></span>
</td>
<td>
<input type="text" id="setNote-text">
</td>
<td>
<button id="setNote-button">setNote</button>
</td>
<td>
<input type="radio" name="player-options" value="y" checked>YouTube
<br>
<input type="radio" name="player-options" value="v">Vimeo
<br>
</td>
</tr>
<tr>
<td>Remove Note At Start Time:</td>
<td>
<input type="text" id="removeNote-text">
</td>
<td>
<button id="removeNote-button">removeNote</button>
</td>
</tr>
<tr>
<td>Note:
<input type="text" id="note-text">
</td>
</tr>
<tr>
<td>
<button id="play">Play</button>
<button id="pause">Pause</button>
</td>
<td>Seek To:
<input type="text" id="seekTo-text">
</td>
<td>
<button id="seekTo-button">Seek To</button>
</td>
</tr>
</table><!-- content to be placed inside <body>…</body> -->
function Zebra(options){
var self = this;
/* Initializer */
this.init = function(){
var site = this.getSite();
window.youtube_player = '';
window.vimeo_player = '';
switch(site){
case 'youtube':
this.insertYouTube();
break;
case 'vimeo':
this.insertVimeo();
break;
}
}
/* Options for Player like Height
required: target, url, height, width
optional: playerVars, duringUpdateTime,
duringNote, onSetNote, onRemoveNote
*/
this.options = {};
for(key in options){
this.options[key] = options[key];
}
this.get = function(key){
return this.options[key];
}
this.set = function(key,value){
this.options[key] = value;
}
this.customCallback = function(callback, data){
/* Custom Callback */
if (self.get(callback)) {
self.get(callback)(data);
};
}
/* Data Related to Player like Current Time */
this.data = {};
this.getData = function(key){
return this.data[key];
}
this.setData = function(key,value){
this.data[key] = value;
}
/* Methods to CRUD Notes */
this.notes = options.notes || [];
this.getNote = function(seconds){
var time = parseFloat(seconds);
var notes = this.notes;
for (var i = 0; i < notes.length; i++) {
if(notes[i].start == time){
return notes[i];
break;
}
};
}
this.setNote = function(note){
/* set default end to 3 seconds after */
note.start = parseFloat(note.start) || 0;
note.end = note.end ? parseFloat(note.end) : note.start + 3;
this.notes.push(note);
/* Custom Callback */
this.customCallback('onSetNote',note);
}
this.removeNote = function(seconds){
var notes = this.notes,
index = -1,
time = parseFloat(seconds);
for(var i = 0; i < notes.length; i++) {
if (notes[i].start == time) {
index = i;
break;
}
}
var result = '';
if (index == -1) {
result = false;
this.customCallback('onRemoveNote',result);
return false;
} else {
result = notes[index];
/* Custom Callback */
this.customCallback('onRemoveNote',result);
this.notes.splice(index,1);
return true;
}
}
this.useNote = function(seconds){
var notes = self.notes
, index = -1
, time = parseFloat(seconds)
, active_note = false;
for(var i = 0; i < notes.length; i++) {
var note = notes[i];
if (note.start <= seconds && note.end >= seconds) {
active_note = true;
if (note.used == false || !note.used) {
self.setUsed(i);
if (note.callback) {
note.callback(note);
} else {
self.customCallback('duringNote',note);
};
};
break;
}
}
if (!active_note) {
self.customCallback('duringTimeline');
};
}
this.setUsed = function(index){
this.notes[index].used = true;
}
this.removeUsed = function(index){
this.notes[index].used = false;
}
this.clearAllUsed = function(){
var notes = this.notes;
for (var i = 0; i < notes.length; i++) {
this.removeUsed(i);
};
}
/* Return Site from URL */
this.getSite = function(){
var site = '';
var REGEX_MAP = {
youtube: /(?:https?:\/\/www\.|https?:\/\/|www\.|\.|^)youtu/,
vimeo: /(?:https?:\/\/www\.|https?:\/\/|www\.|\.|^)vimeo/
}
var url = this.get('url');
for(site in REGEX_MAP){
if (url.match(REGEX_MAP[site]) !== null ) {
return site;
};
}
}
/* YOUTUBE = YT*/
/* Insert YT into DOM */
this.insertYouTube = function(){
/* Insert jQuery & YT scripts, if needed */
if (!window.jQuery) {this.insertScript('jQuery')};
if (!window.YT) {this.insertScript('YT')};
/* Set Options */
window.intervalId = '';
var url = this.get('url')
, target = this.get('target')
, events = {
'onReady':this.onPlayerReady,
'onPlaybackQualityChange': this.onPlayerPlaybackQualityChange,
'onStateChange': this.onPlayerStateChange,
'onError': this.onPlayerError,
'onApiChange' : this.onPlayerApiChange
}
, config = {
width: this.get('width'),
height: this.get('height'),
playerVars: this.get('playerVars') || {},
videoId: this.getYouTubeId(),
events: events
};
/* Required Globals
(1) YT Player object
(2) 'onYouTubeIframeAPIReady' function
*/
window.intervalId = '';
window.onYouTubeIframeAPIReady = function() {
youtube_player = new YT.Player( target, config );
}
}
/* YT Video ID */
this.getYouTubeId = function(){
var url = this.get('url');
var videoId = url.split('v=')[1];
var ampersandPosition = videoId.indexOf('&');
if(ampersandPosition != -1) {
videoId = videoId.substring(0, ampersandPosition);
}
return videoId;
}
/* YT Listeners */
this.onPlayerReady = function(){
console.log('youtube ready');
}
this.onPlayerPlaybackQualityChange = function(e){
console.log('Playback Quality Change: '+e.target);
}
this.onPlayerStateChange = function(e){
if (e) {
/* playing */
if (e.data == 1) {
window.intervalId = setInterval(self.playing,100);
/*console.log('state 1');*/
};
/* paused */
if (e.data == 2) {
window.clearInterval(window.intervalId);
self.paused();
/*console.log('state 2');*/
};
/* buffering */
if (e.data == 3) {
/*console.log('state 3');*/
};
/* cued */
if (e.data == 5) {
/*console.log('state 5');*/
};
/* ended */
if (e.data == 0) {
console.log('state 0');
};
};
}
this.onPlayerError = function(e){
console.log('Error: '+e.target);
}
this.onPlayerApiChange = function(e){
console.log('Api Change: '+e.target);
}
/* COMMON Listeners */
this.time = '';
this.playing = function(data,id){
self.updateTime(data,id);
self.useNote(self.time);
}
this.paused = function(data,id){
self.clearAllUsed();
self.updateTime(data,id)
}
this.updateTime = function(data,id){
self.clearAllUsed();
var site = this.getSite();
switch(self.getSite()){
case 'youtube':
self.time = youtube_player.getCurrentTime();
break;
case 'vimeo':
vimeo_player.api('getCurrentTime',function(value,id){
self.time = value;
});
break;
}
/* Custom Callback */
self.customCallback('duringUpdateTime',self.time);
}
/* COMMON Controls */
this.getControls = function(site){
var controls = {
youtube: {
play: (function(){youtube_player.playVideo()}),
pause: (function(){youtube_player.pauseVideo()}),
seekTo: (function(seconds){youtube_player.seekTo(seconds)}),
duration: (function(){youtube_player.getDuration()}),
},
vimeo:{
play: (function(){vimeo_player.api('play')}),
pause: (function(){vimeo_player.api('pause')}),
seekTo: (function(seconds){vimeo_player.api('seekTo',seconds)}),
duration: (function(){vimeo_player.getDuration()}),
}
}
return controls[site];
}
this.play = function(){
var site = this.getSite();
var player = this.getControls(site);
player.play();
}
this.pause = function(){
var site = this.getSite();
var player = this.getControls(site);
player.pause();
}
this.seekTo = function(seconds){
var site = this.getSite();
var player = this.getControls(site);
player.seekTo(seconds);
player.pause();
}
this.requireScripts = function(libraries){
self.ready.total_scripts = libraries.length;
for (var i = 0; i < libraries.length; i++) {
this.insertScript(libraries[i],self.ready.script);
};
}
this.insertVimeoIframe = function(){
var target = this.get('target')
, url = this.get('url')
, api_params = '?api=1&player_id='+target
, width = this.get('width')
, height = this.get('height');
var playerVars = self.get('playerVars') || ''
, config_params = '';
for (key in playerVars){
config_params += '&'+key+'='+playerVars[key];
}
console.log(url+api_params+config_params);
$('#'+target).replaceWith(
'<iframe id="'+target+
'" src="'+url+api_params+config_params+
'" width="'+width+
'" height="'+height+
'" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>').ready(function(){
self.onVimeoIframeAPIReady();
});
}
this.onVimeoIframeAPIReady = function(){
console.log('vimeo running');
var iframe = document.getElementById(self.get('target'));
vimeo_player = $f(iframe);
vimeo_player.addEvent('ready', function() {
console.log('vimeo ready');
vimeo_player.addEvent('pause', self.paused);
vimeo_player.addEvent('finish', self.finished);
vimeo_player.addEvent('playProgress', self.playing);
});
}
this.insertVimeo = function(){
var scripts = ['jQuery','Froogaloop'];
this.requireScripts(scripts);
}
this.ready = {
total_scripts:0,
loaded_scripts:0,
script: function(library){
self.ready.loaded_scripts++;
if (self.ready.loaded_scripts >= self.ready.total_scripts) {
self.insertVimeoIframe();
};
},
iframe: function(target){
console.log(target);
}
}
this.insertScript = function(library, onLoadCallback){
var script = this.libraries()[library];
var tag = document.createElement('script');
tag.src = script;
tag.type = 'text/javascript';
if (onLoadCallback) {
tag.onload = function(){
onLoadCallback(library)
};
tag.onreadystatechange = function() {
if (this.readyState == 'complete') {
(function(){
onLoadCallback(library)
})();
}
}
};
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
};
this.libraries = function(){
return {
YT: 'https://www.youtube.com/iframe_api',
Froogaloop: 'http://a.vimeocdn.com/js/froogaloop2.min.js',
jQuery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js'
}
}
this.init.call(this);
}
/* Instantiate a YouTube & Vimeo version of Zebra */
window.onload = function(){
var setNoteButton = document.getElementById('setNote-button');
setNoteButton.addEventListener('click', setNote, false);
var playButton = document.getElementById('play');
playButton.addEventListener('click', play, false);
var pauseButton = document.getElementById('pause');
pauseButton.addEventListener('click', pause, false);
var seekToButton = document.getElementById('seekTo-button');
seekToButton.addEventListener('click', seekTo, false);
var removeNoteButton = document.getElementById('removeNote-button');
removeNoteButton.addEventListener('click', removeNote, false);
var y = new Zebra({
url: 'https://www.youtube.com/watch?feature=player_embedded&v=PaOaEjdCkoY',
target: 'yt_player',
width: '400',
height: '225',
playerVars: {
'autohide': 2,
'autoplay': 0,
'cc_load_policy': '',
'color': 'white',
'controls': 1,
'disablekb': 0,
'end': '',
'iv_load_policy': 1,
'list': '',
'listType': '',
'playlist': '',
'loop': 0,
'modestBranding': '',
'origin': '',
'rel': 0,
'showinfo': 1,
'start': '',
'theme': 'light',
},
duringUpdateTime: duringUpdateTime,
duringNote: duringNote,
duringTimeline: duringTimeline,
onSetNote: onSetNote,
onRemoveNote: onRemoveNote
});
var v = new Zebra({
url: 'http://player.vimeo.com/video/23469566',
target: 'v_player',
width: '400',
height: '225',
playerVars: {
'autoplay': 0,
'autopause': 1,
'badge': 1,
'byline': 1,
'color': '', //use hex wihtout #
'loop': 0,
'portrait': 1,
'title': 1
},
duringUpdateTime: duringUpdateTime,
duringNote: duringNote,
duringTimeline: duringTimeline,
onSetNote: onSetNote,
onRemoveNote: onRemoveNote
});
}
/* Following Code Is Not Required - Just Demo Stuff */
function duringUpdateTime(current_time) {
var span = document.getElementById('time');
while (span.firstChild) {
span.removeChild(span.firstChild);
}
span.appendChild(document.createTextNode(current_time));
}
function duringNote(note) {
var text = note.text;
document.getElementById('note-text').value = text;
}
function duringTimeline() {
document.getElementById('note-text').value = '';
}
function onSetNote(note) {
console.log('i just set:', note);
}
function onRemoveNote(note) {
console.log('i just removed:', note);
}
function getPlayer() {
var player_string;
var options = document.getElementsByName('player-options');
for (var i = 0; i < options.length; i++) {
var item = options[i];
if (item.checked) {
player_string = item.value;
}
};
var player = window[player_string];
return player;
}
function setNote() {
var player = getPlayer(),
time = player.time,
text = document.getElementById('setNote-text').value;
var note = {
start: time,
text: text
}
player.setNote(note);
}
function removeNote() {
var player = getPlayer(),
time = document.getElementById('removeNote-text').value;
player.removeNote(time);
}
function seekTo() {
var player = getPlayer(),
time = document.getElementById('seekTo-text').value;
console.log(time);
player.seekTo(time);
}
function play() {
var player = getPlayer();
player.play();
}
function pause() {
var player = getPlayer();
player.pause();
}
{"view":"split","fontsize":"100","seethrough":"","prefixfree":"1","page":"javascript"}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment