I know this has to be totally ghetto, but I'm trying to figure out how to get a feed of my youtube links to display on my homepage in a somewhat stylish fashion. I get tired of having to post something on youtube, then create a post on my website that is basically a duplication of the youtube post. Perhaps there is already something out there that has this functionality built in, but so far I haven't seen it. I have a couple questions about what I'm trying to accomplish thus far:
How can I update my code so I can use 'this' in my youTubeMe object verse having to reference the variable name. I'm pretty sure I understand why I can't use it how I'm doing it currently, but I don't know how to fix?
Second, the google api seems a bit weird to me. I'm not too stoked about using iFrames and the split operation I have to do in order to get the VideoId can't be correct.
Any advice would be greatly appreciated. I'll post the code, but you can also find a working example here
HTML:
<div id="pager">
</div>
<div id="player">
</div>
<script type="text/javascript">
var tag = document.createElement('script');
tag.src = "http://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
function onYouTubePlayerAPIReady() {
youTubeMe.init();
}
</script>
JAVASCRIPT:
var youTubeMe = {
pageSize: 10,
player: null,
startIndex: 1,
username: 'google',
init: function() {
$.getJSON('http://gdata.youtube.com/feeds/users/' + this.username + '/uploads?alt=json&start-index=' + this.startIndex + '&max-results=' + youTubeMe.pageSize, youTubeMe.createYouTubePlayers);
},
createYouTubePlayers: function(data) {
$('#player').empty();
$('#pager').empty();
if (data.feed.entry.length < youTubeMe.pageSize) {
youTubeMe.createPreviousButton();
} else {
if (youTubeMe.startIndex !== 1) {
youTubeMe.createPreviousButton();
}
youTubeMe.createNextButton();
}
for (var i = 0; i < data.feed.entry.length; i++) {
player = new YT.Player('player', {
height: '195',
width: '320',
videoId: data.feed.entry[i].id.$t.split('/')[5]
});
}
},
createNextButton: function() {
$('<a id=\"next\" href=\"#\">next</a>').appendTo('#pager');
$('#next').click(function(e) {
e.preventDefault();
youTubeMe.startIndex += youTubeMe.pageSize;
youTubeMe.init();
});
},
createPreviousButton: function() {
$('<a id=\"prev\" href=\"#\">prev</a>').appendTo('#pager');
$('#prev').click(function(e) {
e.preventDefault();
youTubeMe.startIndex -= youTubeMe.pageSize;
youTubeMe.init();
});
}
};
CSS:
iframe { margin: 20px; }
#pager { background-color: #666; line-height: 3em; text-align: center; }
#pager a { color: #fff; font-size: 1.8em; margin: 0 15px; }
The way you should go is create a closure and have everything contained in that. You can do it like this:
//a closure function that calls itself
(function(){
//with var it would be private and not accesable like this:
//youTubeMe.pageSize
var pageSize = 10;
//declare a global reference to the youTubeMe object
var youTubeMe = window.youTubeMe = function(){
};
//with youTubeMe.* it is accessable from anywhere in your page
//you can either
//declare a public variable like this
youTubeMe.player = "youtube player";
//or a public method like this
youTubeMe.foo = function(){
//this "this" here is your youTubeMe object
console.log(this);
bar();
};
//like the private variable at the top, this function is private
//and can only be called from inside the youTubeMe object
function bar(){
//this "this" here is the window
console.log(this);
}
})();
console.log(youTubeMe.player); //out puts youtube_player
youTubeMe.foo(); //outputs the youTubeMe object
youTubeMe.bar() //throws an undefined error
As for the youtube api; I've always found it to be really good. I've never used the iframe embed just because "iframe embed" sounds not right to me. If you use the youtube api you have two options: Embedded player or the chromeless player. Take a look at the embedded player because unless you want to build a custom skin for your player, its the way to go. Creating a playlist becomes easy when you use the api because you let javascript do all the playing and playlist stuff.
Hope that helps.
Related
I tried to test the code below on an android device, it didn't work (the switch button appeared but the camera output didn't.). I then decided to test it on a Mac and it worked (it just showed the camera output and the button, the button didn't do anything because there is no back camera.). Here is my code (the javascript portion of it.):
var constraints = {
audio: true,
video: {
width: 1280,
height: 720
}
};
navigator.mediaDevices.getUserMedia(constraints).then(function(mediaStream) {
var video = document.querySelector('#webcam');
video.srcObject = mediaStream;
video.onloadedmetadata = function(e) {
video.play();
};
}).catch(function(err) {
console.log(err.name + ": " + err.message);
});
var front = false;
document.getElementById('flip-button').onclick = function() {
front = !front;
};
var constraints = {
video: {
facingMode: (front ? "user" : "environment")
}
};
Here's the HTML portion of my code:
<video id="webcam">
</video>
<button Id="flip-button">switch
</button>
here's the css portion of my code:
#webcam {} #flip-button {
background-color: #202060;
height: 15%;
width: 20%;
border: none;
margin-left: 40%;
}
Thanks for your time.
You got your id wrong. Replace #webcam with #video.
Or just remove this line:
var video = document.querySelector('#webcam');
The latter works because ids are implicitly available in global scope for backwards compatibility. Some people frown on this, but it's neat for tidy fiddles.
Some beginner's advice: Always check your browser's web console for errors. Here it said:
TypeError: video is null
which was the clue that the result from querySelector was null.
PS: You also have two competing definitions of constraints, leaving your facingMode unused. Lastly, flipping front won't do much, unless front is used again, which it is not.
Dear Community!
I want to show multiple videos on my website. The speakers should be deactivated by default (i use the mute()-function).
And the videos should start to play automatically when the user scrolls and the videos come into the browser viewport.
I built this with one single video- worked like a charm. But not with multiple Vidoes on one site..
please help what do i miss in my Code?
This ist html-Part:
<div class="video-container">
<div data-id="olBOo_S5AHY"></div>
</div>
<div class="video-container">
<div data-id="3IXKIVZ9T-U"></div>
</div>
<div class="video-container">
<div data-id="LAQDcnwwspQ"></div>
</div>
This ist the js-Part:
function onYouTubePlayerAPIReady() {
var players = document.querySelectorAll('.video-container div')
for (var i = 0; i < players.length; i++) {
new YT.Player(players[i], {
width: 600,
height: 400,
videoId: players[i].dataset.id,
events: {
onReady: initialize
}
});
}
}
function initialize(){
players[i].mute(); // I know that players[i] is wrong..
var waypoints = jQuery('.video-container').waypoint(function() {
if( players[i]) { // I know that players[i] is wrong..
var fn = function(){
players[i].playVideo(); // I know that players[i] is wrong..
}
setTimeout(fn, 1000);
}
}, {
offset: '50%'
})
}
So the videos show up on my site but i do not have an idea how to add these events to each single video? What am i doing wrong
(a lot i guess ;( ....)
Thank you!
Melanie
Hej Milenoi,
your players variable is a nodeList of the divs you query - and does not contain the addressable YouTube elements.
You have to assign those youtube player objects to some place to address them. (Or there might be some other magic to find them?)
Have a look at my bin here: http://jsbin.com/hozaluzaho
It is a working setup - when you scroll down, you will trigger the other players.
You can have a look at how I created the needed objects and so on.
// get .player nodes
var playerDivs = document.querySelectorAll(".player");
// nodelist to array to use forEach();
var playerDivsArr = [].slice.call(playerDivs);
var players = new Array(playerDivsArr.length);
var waypoints = new Array(playerDivsArr.length);
// when youtube stuff is ready
function onYouTubeIframeAPIReady() {
// create yt players
playerDivsArr.forEach(function(e, i) { // forEach ...
players[i] = new YT.Player(e.id, {
height: '390',
width: '640',
videoId: 'M7lc1UVf-VE',
events: { /* no events set */ }
})
})
// create waypoints
$(".player").each(function(i, e) {
waypoints[i] = new Waypoint({
element: e,
handler: function() {
players[i].playVideo();
}
})
});
}
EDIT ADDITION:
Hej again,
No worries,
The initialize function needs to iterate over the array with the many youtube player objects, you are just talking to one player variable in your initialize function (which might not even be set when you followed my code?).
Look at the place where it says create yt players above. You see that each slot of the array players[] gets stuffed with a player-object. Then you have to talk to each of them again to tell them .mute().
In the forEach loop the current object from the array is handed over to the yt variable.
function initialize() {
players.forEach(function(yt, i) {
yt.mute();
});
}
another bin:
http://jsbin.com/ficoyo/edit?html,output
cheers!
I have a base website system which is using ajax load content without refreshing pages. I have a game page that load many html5 game links via ajax json and when I click on any games it will load the game source files which display as pop up. I am wonder while I'm playing then if I click the close button for stopping the game and then I remove the element of the source files game. Will it free up the memory? As I have noticed, it seems to getting slow the broswer. Anyone has experienced with that, please share with me.
Note: I need some suggestions in order to remove the elements and free up the memory.
eg:
<div id="pop-up">
<a id="close" href="#">Close Button</a>
<div id="inner-pop-up">
<script src="game sources" type="text/javascript"></script>
<script src="game sources" type="text/javascript"></script>
<script src="game sources" type="text/javascript"></script>
<div id="game">
<canvas></canvas>
</div>
</div>
</div>
$('#pop-up').modal('view', {
speed: 750,
close: '.close-favourite',
easing: 'easeOutBounce',
animation: 'top',
position: 'center',
overlayClose: true
});
$('#close').on('click', function() {
$('#inner-pop-up').children().remove();
});
The only real way to free up any resources used by script functions is to add a JavaScript file that basically calls delete window.myFunction for every possible object and function (functions are objects really) your specified script files may define. To me, for obvious reasons, this is a really bad idea.
Note that these objects would be script (window) objects so you cannot use .remove() to remove those.
I would also note that your should use $('#inner-pop-up').empty(); rather than your $('#inner-pop-up').children().remove(); since that would remove the text of the element if any, as well and specifically removes the data and event handlers from those elements prior to removal from the DOM.
You might have some very specific functions and objects from your scripts that you might want to remove here but only the contents of your scripts would tell that. If you create global window objects that gets really messy fast.
Note it is REALLY hard to determine what a script file creates and then remove it.
To prove a point open up your favorite browser console and execute $("script").remove(). stuff in that script still runs.
Eg: This is my game file which contained the object like that
FootballChallenge.Game = function (game) {
FootballChallenge._scoreText = null;
FootballChallenge._score = 0;
FootballChallenge.kickBoard;
this._preventClick = true;
FootballChallenge.kaboomGroup;
FootballChallenge.ball;
FootballChallenge.shoe;
FootballChallenge.self;
};
FootballChallenge.Game.prototype = {
create: function () {
FootballChallenge.self = this.game;
this.game.physics.startSystem(Phaser.Physics.ARCADE);
this.game.physics.arcade.checkCollision.up = false;
this.bg = this.game.add.image(this.game.world.centerX, this.game.world.centerY, 'field');
this.bg.anchor.setTo(0.5);
FootballChallenge.kickBoard = this.game.add.sprite(10, 20, 'kickBoard');
FootballChallenge._scoreText = this.game.add.bitmapText(0, FootballChallenge.kickBoard.height/2 + 20, 'white-font', ''+FootballChallenge._score+'', 32);
FootballChallenge._scoreText.align = 'center';
FootballChallenge._scoreText.x = (FootballChallenge.kickBoard.width-FootballChallenge._scoreText.width + 20)/2;
FootballChallenge.ball = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY - 100, 'ball');
this.game.physics.arcade.enable(FootballChallenge.ball);
FootballChallenge.ball.anchor.setTo(0.5);
FootballChallenge.ball.scale.setTo(0.5);
FootballChallenge.ball.body.collideWorldBounds = true;
FootballChallenge.ball.body.gravity.y = 0;
FootballChallenge.ball.body.bounce.setTo(1);
FootballChallenge.shoe = this.game.add.sprite(this.game.world.centerX, this.game.world.centerY, 'shoe');
this.game.physics.arcade.enable(FootballChallenge.shoe);
FootballChallenge.shoe.anchor.setTo(0.5);
FootballChallenge.shoe.scale.setTo(0.5);
FootballChallenge.shoe.body.setSize(130,50,0,20);
FootballChallenge.shoe.body.collideWorldBounds = true;
FootballChallenge.kaboomGroup = this.game.add.group();
FootballChallenge.kaboomGroup.createMultiple(10, 'kaboom');
FootballChallenge.kaboomGroup.forEach(this.explosion, this);
this.play();
},
explosion: function(kick) {
kick.anchor.x = 0.7;
kick.anchor.y = 0.5;
kick.animations.add('kaboom');
},
play: function() {
this.bitmask = this.game.make.bitmapData(this.game.width, this.game.height);
this.bitmask.fill(50,50,50);
this.mask = this.game.add.sprite(0, 0, this.bitmask);
this.mask.tint = 0x000000;
this.mask.alpha = 0.6;
this.game.paused = true;
var pausedText = this.game.add.bitmapText(this.game.world.centerX, this.game.world.centerY - 200, 'white-font', 'click anywhere to begin!', 32);
pausedText.align = 'center';
pausedText.tint = 0xff0e25;
pausedText.anchor.setTo(0.5);
this.game.input.onDown.add(function(){
pausedText.destroy();
this.game.paused = false;
this.mask.alpha = 0;
FootballChallenge.ball.body.gravity.y = 1500;
this.game.canvas.style.cursor = "none";
}, this);
},
countScore: function(ball, shoe) {
ball.body.velocity.y = -1000;
ball.body.gravity.x = FootballChallenge.self.rnd.integerInRange(-80, 80);
FootballChallenge._scoreText.setText(FootballChallenge._score +=1);
FootballChallenge._scoreText.x = (FootballChallenge.kickBoard.width-FootballChallenge._scoreText.width + 20)/2;
var boom = FootballChallenge.kaboomGroup.getFirstExists(false);
boom.reset(shoe.x, shoe.y);
boom.play('kaboom', 40, false, true);
},
lose: function() {
this.game.state.start('EndGame');
},
update: function() {
if(FootballChallenge.ball.y >= this.game.height - 100) {
FootballChallenge.ball.body.gravity = false;
this.game.time.events.add(Phaser.Timer.SECOND * 0.2, this.lose, this);
}
this.game.physics.arcade.collide(FootballChallenge.ball, FootballChallenge.shoe, this.countScore);
this.game.physics.arcade.moveToPointer(FootballChallenge.shoe, 30, this.game.input.activePointer, 50);
}
};
I have been trying for days and can't get wikitude example app run. I'm new in this framework bu documentation doesn't give me a clear explanation. I'm trying this:
* Inside my head tag I have included the wikitude plugin (and of course I have put mi licence trial key), like this:
<script src="js/WikitudePlugin.js"></script>
Next, I have written the sample code:
var World = {
loaded: false,
init: function initFn() {
this.createOverlays();
},
createOverlays: function createOverlaysFn() {
this.tracker = new AR.ClientTracker("assets/magazine.wtc", {
onLoaded: this.worldLoaded
});
this.imgButton = new AR.ImageResource("assets/wwwButton.jpg");
/*
The next step is to create the augmentation. In this example an image resource is created and passed to the AR.ImageDrawable. A drawable is a visual component that can be connected to an IR target (AR.Trackable2DObject) or a geolocated object (AR.GeoObject). The AR.ImageDrawable is initialized by the image and its size. Optional parameters allow for position it relative to the recognized target.
*/
var imgOne = new AR.ImageResource("assets/imageOne.png");
var overlayOne = new AR.ImageDrawable(imgOne, 1, {
offsetX: -0.15,
offsetY: 0
});
/*
For each target an AR.ImageDrawable for the button is created by utilizing the helper function createWwwButton(url, options). The returned drawable is then added to the drawables.cam array on creation of the AR.Trackable2DObject.
*/
var pageOneButton = this.createWwwButton("http://n1sco.com/specifications/", 0.1, {
offsetX: -0.25,
offsetY: -0.25,
zOrder: 1
});
/*
This combines everything by creating an AR.Trackable2DObject with the previously created tracker, the name of the image target as defined in the target collection and the drawable that should augment the recognized image.
Note that this time a specific target name is used to create a specific augmentation for that exact target.
*/
var pageOne = new AR.Trackable2DObject(this.tracker, "pageOne", {
drawables: {
cam: [overlayOne, pageOneButton]
}
});
/*
Similar to the first part, the image resource and the AR.ImageDrawable for the second overlay are created.
*/
var imgTwo = new AR.ImageResource("assets/imageTwo.png");
var overlayTwo = new AR.ImageDrawable(imgTwo, 0.5, {
offsetX: 0.12,
offsetY: -0.01
});
var pageTwoButton = this.createWwwButton("http://goo.gl/qxck1", 0.15, {
offsetX: 0,
offsetY: -0.25,
zOrder: 1
});
/*
The AR.Trackable2DObject for the second page uses the same tracker but with a different target name and the second overlay.
*/
var pageTwo = new AR.Trackable2DObject(this.tracker, "pageTwo", {
drawables: {
cam: [overlayTwo, pageTwoButton]
}
});
},
createWwwButton: function createWwwButtonFn(url, size, options) {
/*
As the button should be clickable the onClick trigger is defined in the options passed to the AR.ImageDrawable. In general each drawable can be made clickable by defining its onClick trigger. The function assigned to the click trigger calls AR.context.openInBrowser with the specified URL, which opens the URL in the browser.
*/
options.onClick = function() {
AR.context.openInBrowser(url);
};
return new AR.ImageDrawable(this.imgButton, size, options);
},
worldLoaded: function worldLoadedFn() {
var cssDivInstructions = " style='display: table-cell;vertical-align: middle; text-align: right; width: 50%; padding-right: 15px;'";
var cssDivSurfer = " style='display: table-cell;vertical-align: middle; text-align: left; padding-right: 15px; width: 38px'";
var cssDivBiker = " style='display: table-cell;vertical-align: middle; text-align: left; padding-right: 15px;'";
document.getElementById('loadingMessage').innerHTML =
"<div" + cssDivInstructions + ">Scan Target #1 (surfer) or #2 (biker):</div>" +
"<div" + cssDivSurfer + "><img src='assets/surfer.png'></img></div>" +
"<div" + cssDivBiker + "><img src='assets/bike.png'></img></div>";
// Remove Scan target message after 10 sec.
setTimeout(function() {
var e = document.getElementById('loadingMessage');
e.parentElement.removeChild(e);
}, 10000);
}
};
World.init();
I don't know what I'm doing wrong, if I write some alert in the init functionit doesn't show anything.
Since your question requires some back and forth and isn't really suitable for the StackOverflow question/answer format. I'll suggest we move this discussion to your thread on our forums: http://www.wikitude.com/developer/developer-forum/-/message_boards/message/690051?p_p_auth=Br6dzsxQ
I am trying to build a web interface for Subsonic and was trying to switch its default implementation of JWPlayer to Flowplayer.
I tried the default method of loading the video in both JWPlayer and Flowplayer and neither works, so I looked at the existing interface which used the below relevant code:
var player;
var position;
var maxBitRate = 1000;
var timeOffset = 0;
function init() {
var flashvars = {
id:"player1",
skin:"flash/whotube.zip",
screencolor:"000000",
controlbar:"over",
autostart:"false",
bufferlength:3,
backcolor:"EFEFEF",
frontcolor:"000000",
provider:"video"
};
var params = {
allowfullscreen:"true",
allowscriptaccess:"always"
};
var attributes = {
id:"player1",
name:"player1"
};
var width = "100%";
var height = "85%";
swfobject.embedSWF("flash/jw-player-5.6.swf", "placeholder1", width, height, "9.0.0", false, flashvars, params, attributes);
}
function playerReady(thePlayer) {
player = $("player1");
player.addModelListener("TIME", "timeListener");
play();
}
function play() {
var list = new Array();
list[0] = {
file:"http://domain.com:4040/rest/stream.view?u=username&p=password&v=1.6.0&c=appname&id=number",
duration:9999 - timeOffset, //testing value for duration
provider:"video"
};
player.sendEvent("LOAD", list);
player.sendEvent("PLAY");
}
I can't even same to make anything run under flowplayer. Any ideas? I am stuck at:
Getting something equivalent to playerReady();
Getting the video to load using:
flowplayer.addClip({'url':videoURL},0);
flowplayer.play({'url':videoURL},0);
Which gives me: has no method 'addClip' and has no method 'play'
My JS include are for both FlowPlayer and JWPlayer:
flowplayer-3.2.11.min.js
Jquery
Prototype
swfobject
and my own JS file from which above is a snippet.
Help would be very much appreciated.
Thanks,
flowplayer("player", "flowplayer-3.2.15.swf", {
clip: {
scaling: 'orig'
},
plugins: {
controls: null
},
// player events are defined directly to "root" (not inside a clip)
onLoad: function() {
$f().play({url: "http://pseudo01.hddn.com/vod/demo.flowplayervod/Extremists.flv"});
}
});