Skip to content

Instantly share code, notes, and snippets.

@denisnazarov
Created February 20, 2014 03:51
Show Gist options
  • Save denisnazarov/9106811 to your computer and use it in GitHub Desktop.
Save denisnazarov/9106811 to your computer and use it in GitHub Desktop.
Ember Youtube Loop Component http://emberjs.jsbin.com/tadaseku/3/
/* Put your CSS here */
html, body {
margin: 10px;
}
form{
width: 560px;
margin-bottom: 10px;
}
.ui-slider-horizontal .ui-slider-handle {
width: 2px;
margin-left: -1px;
border: 1px solid black;
background: black;
}
App = Ember.Application.create();
App.deferReadiness();
function onYouTubeIframeAPIReady(){
App.advanceReadiness();
}
var playerVars = {
html5: 1,
controls: 0,
disablekb: 1,
iv_load_policy: 3,
rel: 0,
showinfo: 0,
modestbranding: 1,
playsinline: 1
};
App.YoutubeLoopContainerComponent = Ember.Component.extend({
videoDuration: null, //set by video
sliderStart: 1676,
sliderEnd: 1727,
loopStart: function(){
var sliderStart = this.get('sliderStart'),
videoDuration = this.get('videoDuration');
return parseInt(sliderStart / 2000 * videoDuration, 10);
}.property('sliderStart', 'videoDuration'),
loopEnd: function(){
var sliderEnd = this.get('sliderEnd'),
videoDuration = this.get('videoDuration');
return parseInt(sliderEnd / 2000 * videoDuration, 10);
}.property('sliderEnd', 'videoDuration'),
convertToTime: function(totalSec){
var hours = parseInt( totalSec / 3600 , 10) % 24;
var minutes = parseInt( totalSec / 60 , 10) % 60;
var seconds = totalSec % 60;
return result = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (seconds < 10 ? "0" + seconds : seconds);
},
startTime: function(){
return this.convertToTime(this.get('loopStart'));
}.property('loopStart'),
endTime: function(){
return this.convertToTime(this.get('loopEnd'));
}.property('loopEnd')
});
App.YoutubeLoopVideoComponent = Ember.Component.extend({
classNames: ['youtube-player'],
shouldLoop: true,
width: null, //set in template
height: null, //set in template
videoId: null, //set in template
loopStart: null,
loopEnd: null,
duration: null, //set by api
currentTime: null,
startLoopPoll: function(){
var self = this;
var player = this.get('player');
this._intervalId = window.setInterval(function(){
var currentTime = player.getCurrentTime();
self.set('currentTime', currentTime);
}, 100);
},
stopLoopPoll: function(){
window.clearInterval(this._intervalId);
},
loopPollInitializer: function(){
var isPlaying = this.get('isPlaying'),
shouldLoop = this.get('shouldLoop');
if (!shouldLoop){return;}
if (isPlaying){
this.startLoopPoll();
}else{
this.stopLoopPoll();
}
}.observes('isPlaying'),
currentTimeObserver: function(){
var currentTime = this.get('currentTime'),
loopStart = this.get('loopStart'),
loopEnd = this.get('loopEnd'),
player = this.get('player');
if (currentTime > loopEnd){
player.seekTo(loopStart);
}
}.observes('currentTime'),
loopStartChanged: function(){
var loopStart = this.get('loopStart'),
player = this.get('player');
console.log(loopStart);
player.seekTo(loopStart, true);
}.observes('loopStart'),
setupYouTubeApi: function(){
var self = this;
var elementId = this.get('elementId'),
videoId = this.get('videoId'),
loopStart = this.get('loopStart');
var player = new YT.Player(elementId, {
height: this.get('height'),
width: this.get('width'),
videoId: videoId,
playerVars: playerVars,
events: {
onReady: function(event){
var player = event.target;
player.mute();
player.seekTo(loopStart);
player.playVideo();
self.set('player', player);
},
onStateChange: function(e){
var ended = YT.PlayerState.ENDED,
playing = YT.PlayerState.PLAYING,
paused = YT.PlayerState.PAUSED,
state = e.data;
if(state === ended || state === paused ){
Ember.run(function(){
self.set('isPlaying', false);
});
}else if( state === playing){
Ember.run(function(){
if (!self.get('duration')){
var duration = e.target.getDuration();
self.set('duration', duration);
}
self.set('isPlaying', true);
});
}
}
}
});
},
didInsertElement: function(){
this.setupYouTubeApi();
},
willDestroyElement: function(){
this.stopLoopPoll();
}
});
// Based on http://jsfiddle.net/FPCRb/1/
App.RangeSliderComponent = Ember.Component.extend({
didInsertElement: function(){
var self = this;
var start = this.get('start'),
end = this.get('end');
this.$(".slider").slider({
min: 0,
max: 2000,
step: 1,
range: true,
values: [start, end],
slide: function(event, ui) {
for (var i = 0; i < ui.values.length; ++i) {
if (i === 0){
self.set('start', ui.values[i]);
}else{
self.set('end', ui.values[i]);
}
}
}
});
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ember Starter Kit</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.2.1.js"></script>
<script src="http://builds.emberjs.com/tags/v1.4.0/ember.js"></script>
<script src="https://www.youtube.com/player_api"></script>
<link href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.min.css" rel="stylesheet" type="text/css" />
</head>
<body>
<script type="text/x-handlebars">
<h2>Ember YouTube Loop Component</h2>
{{outlet}}
<p><a href="http://www.twitter.com/Iiterature" target="_blank">@Iiterature</a></p>
</script>
<script type="text/x-handlebars" data-template-name="components/range-slider">
<form>
<div>
START: {{parentView.startTime}}
END: {{parentView.endTime}}
</div>
<br />
<div class="slider"></div>
</form>
</script>
<script type="text/x-handlebars" data-template-name="index">
{{#youtube-loop-container}}
{{range-slider start=view.sliderStart end=view.sliderEnd}}
{{youtube-loop-video width=560 height=315 videoId="XY5KTVA_2ys" loopStart=view.loopStart loopEnd=view.loopEnd duration=view.videoDuration}}
{{/youtube-loop-container}}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment