MX.Youtube = MX.Object3D.extend({ init: function (ops) { this.type = "Youtube" this.media = ops.media this.width = ops.media.width this.height = ops.media.height this.x = ops.x || 0 this.y = ops.y || 0 this.z = ops.z || 0 this.rotationX = ops.rotationX || 0 this.rotationY = ops.rotationY || 0 this.rotationZ = ops.rotationZ || 0 this.scale = ops.scale || 1 this.backface = ops.backface || false ops.className && this.el.classList.add(ops.className) this.backface && this.el.classList.add("backface-visible") this.el.classList.add("video") this.el.classList.add("mx-scenery") this.paused = !! this.media.autoplay this.muted = app.muted || !! this.media.mute }, load: function (ops) { var base = this var uid = 'player-' + Uid () var preload = document.createElement("div") preload.id = uid preload.style.backgroundImage = "url(" + this.media.thumbnail + ")" preload.style.backgroundSize = "cover" preload.style.width = "100%" preload.style.height = "100%" preload.style.pointerEvents = "none" preload.style.position = "absolute" preload.style.top = "0" preload.style.left = "0" preload.style.zIndex = "1" preload.className = "preload" this.el.appendChild(preload) var overlay = this.overlay = document.createElement("div") overlay.style.width = "100%" overlay.style.height = "100%" overlay.style.position = "absolute" overlay.style.top = "0" overlay.style.left = "0" overlay.style.zIndex = "2" overlay.className = "overlay" this.el.appendChild(overlay) this.defer(uid) }, defer: function (uid){ if (! YT || ! YT.loaded) { setTimeout(function(){ this.defer(uid) }.bind(this), 300) } else { // not sure why i need to delay here.. // stopped working until i added the setTimeout setTimeout(function(){ this.build(uid) }.bind(this), 20) } }, build: function(uid){ this.player = new YT.Player(uid, { videoId: this.media.token, width: this.width, height: this.height, events: { onReady: this.ready.bind(this), onError: this.error.bind(this), onStateChange: this.statechange.bind(this), }, playerVars: { autohide: 1, autoplay: 0, disablekb: 1, controls: 0, enablejsapi: 1, origin: window.location.origin, fs: 0, modestbranding: 1, iv_load_policy: 3, // no annotations loop: 0, showinfo: 0, rel: 0, wmode: 'opaque', }, }) }, ready: function(){ console.log("youtube ready") if (this.media.autoplay) { this.play() } else { this.pause() } if (this.media.mute) { this.mute() } else { this.unmute() } this.seek( this.media.keyframe || 0 ) }, error: function(err){ console.log("youtube error", err) }, statechange: function(e){ switch (e.data) { case -1: // unstarted break case 0: // finished this.finished() break case 1: // play if (this.paused) { this.pause() } break case 2: // pause break case 3: // buffering break case 5: // cued break } }, play: function(){ this.paused = false this.player.playVideo() }, pause: function(){ this.paused = true this.player.pauseVideo() }, seek: function(n, allowSeekAhead){ if (n < 1) { n = n * this.duration() } allowSeekAhead = typeof allowSeekAhead == "boolean" ? allowSeekAhead : true this.player.seekTo(n, true) // set to false if seeking manually }, duration: function(){ return this.player.getDuration() }, mute: function(){ this.player.mute() this.muted = true }, unmute: function(){ this.player.unMute() this.player.setVolume(80) this.muted = false }, setLoop: function(state){ this.media.loop = state }, finished: function(){ console.log("youtube finished") if (this.media.loop) { this.seek(0) this.play() } else if (this.bound) { $(".playButton").removeClass('playing') } } }) window.onYouTubePlayerAPIReady = function(){ // console.log("youtube api ready") }