I am trying to make a youtube video loop at a specific section of a video.
https://www.youtube.com/v/zeI-JD6RO0k?autoplay=1&loop=1&start=30&end=33&playlist=%20zeI-JD6RO0k
From what I know:
To start and end:
start=30&end=33
To make it loop:
autoplay=1&loop=1&playlist=%20zeI-JD6RO0
The problem is that it doesn't start the next loop at the time I specify
You can use Youtube Iframe-API to loop a video section.
Place this tag in your HTML-page:
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="player"></div>
Load Youtube Iframe-API
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
Create player and loop video:
var section = {
start: 30,
end: 33
};
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player(
'player',
{
height: '360',
width: '640',
videoId: 'zeI-JD6RO0k',
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
}
);
}
function onPlayerReady(event) {
player.seekTo(section.start);
player.playVideo();
}
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
var duration = section.end - section.start;
setTimeout(restartVideoSection, duration * 1000);
}
}
function restartVideoSection() {
player.seekTo(section.start);
}
See this example in action
Note first, if one is not familiar with html or javascript beyond basics, the youtube player api link in the answer by maiermic will provide everything necessary to develop the solution provided there -on one page without a lot of skimming.
also, in case one would like to add a hh:mm:ss converter that accepts down to seconds - add / modify the code provided in the answer by maiermic with the following;
var timeStart = "HH:MM:SS";
var timeEnd = "HH:MM:SS";
var loopStart = getSeconds(timeStart);
var loopEnd = getSeconds(timeEnd);
var section = {
start: loopStart,
end: loopEnd
};
and add the function;
function getSeconds(str) {
var p = str.split(':'),
s = 0, m = 1;
while (p.length > 0) {
s += m * parseInt(p.pop(), 10);
m *= 60;
}
return s;
}
And in the case one would like to include slower playback up to normal speed with this code, alter the following function with
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
var duration;
var playerSpeed = player.getPlaybackRate();
if (playerSpeed == .25)
duration = (section.end - section.start) * 4;
else if (playerSpeed == .5)
duration = (section.end - section.start) * 2;
else if (playerSpeed == .75)
duration = (section.end - section.start) * 1.5;
else if (playerSpeed == 1)
duration = (section.end - section.start);
setTimeout(restartVideoSection, duration * 1000);
}
}
as well as
function onPlayerReady(event) {
player.seekTo(section.start);
player.setPlaybackRate(.25); // choose .25, .50, .75, or 1
player.playVideo();
}
Of course, you will have to modify the video id/ HH:MM:SS fields in the code every time you want a different video / section of video. Additionally, if one chooses to include support for variable player speed as above, those values will have to be added as desired. The playback speed can be altered via the player buttons once started if the code above is included, but if it is changed during play back, the duration will not refresh until the video begins at the start again.
Is it possible to stop a video using the YouTube API one second before the end or just stopping it resetting back to the beginning? This is regardless of the length of the video itself.
Thanks in advance
I disagree with the argument of NOT being able to stop a video before it ends. Specifically, in the API, you have access to:
https://developers.google.com/youtube/js_api_reference#Playback_status
Player.getCurrentTime();
Player.getDuration();
If you were to monitor the player object and compare these two, you could easily stop the video before it ends. An example would be (although probably not good in production):
setInterval(function() {
var player = getPlayer(); //retrieve the player object
if(player) {
var duration = player.getDuration();
var current = player.getCurrentTime();
if((duration - current) <= 1) {
player.stopVideo();
}
}
}, 1000); //every second
I ran into an issue where for some reason the iframe player was stopping the video before the video's end, and so not triggering the ENDED event, and ran into this question while trying to find a solution for that. Since my approach can solve your problem as stated, here's what I did (I left the console.log() debug lines in to make it easier for someone else using this to play around with):
var player_timeout;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING) {
console.log("PLAY [" + event.data + "]");
timeout_set();
}
if (event.data == YT.PlayerState.PAUSED) {
console.log("PAUSED [" + event.data + "]");
clearTimeout(player_timeout);
}
}
function timeout_func() {
console.log("timeout_func");
player.stopVideo(); // or whatever other thing you want to do 1 second before the end of the video
}
function timeout_set() {
console.log("timeout_set");
var almostEnd_ms = (player.getDuration() - player.getCurrentTime() - 1) * 1000;
console.log("almostEnd_ms: " + almostEnd_ms);
console.log("player.getCurrentTime(): " + player.getCurrentTime());
player_timeout = setTimeout(timeout_func, almostEnd_ms);
}
As a part of my final year project in university I'm analysing Twitter data using graph entropy. To briefly outline the purposes:
I want to collect all tweet from a certain area (London) containing keywords "cold", "flu" etc. This part is done using Streaming API.
Then I want to access each of the user's (who tweeted about being ill, collected in previous section) list of followers and following to be able to build a graph for further analysis. And here I'm stuck.
I assume for the second part I should be using Search API, but I keep getting error 88 even for a single user.
Below is the code I use for the first part:
final TwitterStream twitterStream = new TwitterStreamFactory(cb.build())
.getInstance();
StatusListener listener = new StatusListener() {
public void onStatus(Status status) {
User user = status.getUser();
long userid = user.getId();
String username = status.getUser().getScreenName();
String content = status.getText();
GeoLocation geolocation = status.getGeoLocation();
Date date = status.getCreatedAt();
if (filterText(content)) {
System.out.println(username+"\t"+userid);
System.out.println(content);
System.out.println(geolocation);
System.out.println(date);
try {
getConnections(userid);
} catch (TwitterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//OTHER LISTENER METHODS
};
twitterStream.addListener(listener);
// London
double lat3 = 51.23;
double lat4 = 51.72;
double lon3 = -0.56;
double lon4 = 0.25;
double[][] bb = { { lon3, lat3 }, { lon4, lat4 } };
FilterQuery fq = new FilterQuery();
fq.locations(bb);
twitterStream.filter(fq);
private static boolean filterText(String tweet) {
return tweet.contains("flu")
|| tweet.contains("cold")
|| tweet.contains("cough")
|| tweet.contains("virus");
}
And this is what I'm trying to complete the second part with:
private static void getConnections(long id) throws TwitterException {
Twitter twitter = new TwitterFactory().getInstance();
long lCursor = -1;
IDs friendsIDs = twitter.getFriendsIDs(id, lCursor);
System.out.println(twitter.showUser(id).getName());
System.out.println("==========================");
do
{
for (long i : friendsIDs.getIDs())
{
System.out.println("follower ID #" + i);
System.out.println(twitter.showUser(i).getName());
}
}while(friendsIDs.hasNext());
}
Any suggestions?
When you receive error 88, that's Twitter telling you that you're being rate limited:
The request limit for this resource has been reached for the current rate limit window.
The search call is limited to either 180 or 450 calls in a 15 minute period. You can see the rate limits here and this documentation explains the rate limiting in detail.
As for how to get around it, you may have to throttle your search calls to the API. Twitter4J provides ways to inspect current limits/exhaustion which may help - see Twitter#getRateLimitStatus().
I am needing to have some info passed to scripts when onPlayerStateChange() function fires off.
What I am after is the current videoID of the currently playing video and the array position number from the playlist.
(-_-)ZZZzzz...
EDIT....
Ok. So I have progressed a bit.
In the player code, I have this fire off
if (event.data == -1) {
getPlaylistIndex();
}
I then have this script.
function getPlaylistIndex() {
var str = ""+ytplayer.getPlaylist();
var viedoString = str.split(',');
var videoID = viedoString[ytplayer.getPlaylistIndex()];
if(videoID == undefined){
} else {
alert(videoID);
loadComents(videoID);
loadVideoINFO(videoID);
}
}
You will notice an IF condition which is needed to not fire the code for normal videos... just on the PL's.
It is working apart from the fact that when I load the playlist in, I do not get a videoID from the script. If I select any video in the playlist and also go back to the first one, it works fine. Just not working when first loading the playlist.
Any ideas ?
P.S. the alert is for testing only.
RE-EDIT.... ;P
Ok. I have been playing with this for the whole day going in and out of all scripts.
I have it working now (so it seems).
First I added into my code to give me this.
function getPlaylistIndex() {
var str = ""+ytplayer.getPlaylist();
var viedoString = str.split(',');
var videoID = viedoString[ytplayer.getPlaylistIndex()];
if(videoID == undefined){
} else {
if(videoID == ''){
var str2 = ytplayer.getVideoUrl();
videoID = (str2.substring(31,42));
}
loadComents(videoID);
loadVideoINFO(videoID);
}
}
And so it works first time, I needed to change
event.data == -1 to event.data == 1 as YTplayer fires them in a particular order.
If anyone has anything to ad or correct, please do so.
Is there any way to implement waiting for, say, 3 seconds in ActionScript, but to stay within same function? I have looked setInterval, setTimeOut and similar functions, but what I really need is this:
public function foo(param1, param2, param3) {
//do something here
//wait for 3 seconds
//3 seconds have passed, now do something more
}
In case you wonder why I need this - it is a legal requirement, and no, I can't change it.
Use the Timer to call a function after 3 seconds.
var timer:Timer = new Timer(3000);
timer.addEventListener(TimerEvent.TIMER, callback); // will call callback()
timer.start();
To do this properly, you should create the timer as an instance variable so you can remove the listener and the timer instance when the function is called, to avoid leaks.
class Test {
private var timer:Timer = new Timer(3000);
public function foo(param1:int, param2:int, param3:int):void {
// do something here
timer.addEventListener(TimerEvent.TIMER, fooPartTwo);
timer.start();
}
private function fooPartTwo(event:TimerEvent):void {
timer.removeEventListener(TimerEvent.TIMER, fooPartTwo);
timer = null;
// 3 seconds have passed, now do something more
}
}
You could also use another function inside your foo function and retain scope, so you don't need to pass variables around.
function foo(param1:int, param2:int, param3:int):void {
var x:int = 2; // you can use variables as you would normally
// do something here
var timer:Timer = new Timer(3000);
var afterWaiting:Function = function(event:TimerEvent):void {
timer.removeEventListener(TimerEvent.TIMER, afterWaiting);
timer = null;
// 3 seconds have passed, now do something more
// the scope is retained and you can still refer to the variables you
// used earlier
x += 2;
}
timer.addEventListener(TimerEvent.TIMER, afterWaiting);
timer.start();
}
For AS3 use Radu's answer.
For AS2 use the setInterval function like so:
var timer = setInterval(function, 3000, param1, param2);
function (param1, param2) {
// your function here
clearInterval(timer);
}
You can also use delayedCall, from TweenMax. IMHO, it's the sharpest way to do that if you are familiar to TweenMax family.
TweenMax.delayedCall(1, myFunction, ["param1", 2]);
function myFunction(param1:String, param2:Number):void
{
trace("called myFunction and passed params: " + param1 + ", " + param2);
}
In your case, using a anonymous function:
public function foo(param1, param2, param3) {
//do something here
trace("I gonna wait 3 seconds");
TweenMax.delayedCall(3, function()
{
trace("3 seconds have passed");
});
}
why you are doing some confused ways instead of doing the right way?
there is a method named:"setTimeout()";
setTimeout(myFunction,3000);
myFunction is the function you want to call after the period.and 3000 is the period you want to wait(as miliseconds).
you don't need to set then clear interval, or make a timer with one repeat count or do sth else with more trouble☺.
There is no Sleep in ActionScript. But there are other ways to achieve the same thing without having all your code in a single function and wait within that function a specific amount of time.
You can easily have your code in two functions and call the 2nd one after a specific timeout you set in your 1st function.
THIS IS NOT WITHIN ONE FUNCTION - ANSWERS: "How to wait for X seconds in AS2 & 3"
...without using setInterval or clearInterval.
The answers posted above are much faster and easier to use. I posted this here, just in case...
Sometimes you may not be able to use set/clearInterval or other methods based on development restrictions. Here is a way to make a delay happen without using those methods.
AS2 - If you copy/paste the code below to your timeline, make sure to add two movie clips to the stage, btnTest and btnGlowTest (include like instance names). Make "btnGlowTest" larger, a different color, & behind "btnTest" (to simulate a glow and a button, respectively).
Compile and check the output panel for the trace statements to see how the code is working. Click on btnTest - btnGlowTest will then become visible throughout the duration of the delay, (just for visual representation).
I have an onEnterFrame countdown timer in here as well, (demos stopping/switching timers).
If you want the delay/glow to be longer - increase the glowGameTime number. Change the names to fit your own needs and/or apply the logic differently.
var startTime:Number = 0;
var currentTime:Number = 0;
var mainTime:Number = 5;//"game" time on enter frame
var glowStartTime:Number = 0;
var glowCurrentTime:Number = 0;
var glowGameTime:Number = 1.8;//"delayed" time on press
btnGlowTest._visible = false;
this.onEnterFrame = TimerFunction;
startTime = getTimer();
function TimerFunction()
{
currentTime = getTimer();
var timeLeft:Number = mainTime - ((currentTime - startTime)/1000);
timeLeft = Math.floor(timeLeft);
trace("timeLeft = " + timeLeft);
if(timeLeft <= 0)
{
trace("time's up...3 bucks off");
//...do stuff here
btnGlowTest._visible = false;//just for show
btnTest._visible = false;//just for show
StopTime();
}
}
function glowTimerFunction()
{
glowCurrentTime = getTimer();
var glowTimeLeft:Number = glowGameTime - ((glowCurrentTime - glowStartTime)/1000);
glowTimeLeft = Math.floor(glowTimeLeft);
//trace("glowTimeleft = " + glowTimeLeft);
if(glowTimeLeft <= 0)
{
trace("TIME DELAY COMPLETE!");
//...do stuff here
btnGlowTest._visible = false;//just for show
btnTest._visible = false;//just for show
StopTime();
}
}
btnTest.onPress = function()
{
trace("onPress");
btnGlowTest._visible = true;
StopTime();
GlowTime();
}
function GlowTime()
{
trace("GlowTime Function");
this.onEnterFrame = glowTimerFunction;
glowStartTime = getTimer();
}
function StopTime()
{
trace(">>--StopTime--<<");
delete this.onEnterFrame;
}
AS3 - Below is the code from above setup to run in AS3. There are different ways to accomplish similar results, yet based on the project scope, these are the methods that were used in order to get things functioning properly.
If you copy/paste the code below to your timeline, make sure to add two movie clips to the stage, btnTest and btnGlowTest (include like instance names). Make "btnGlowTest" larger, a different color, & behind "btnTest" (to simulate a glow and a button, respectively).
Compile and check the output panel for the trace statements to see how the code is working. Click on btnTest - btnGlowTest will then become visible throughout the duration of the delay, (just for visual representation).
If you want the delay/glow to be longer - increase the GlowTimer:Timer number, (currently set to 950). Change the names to fit your own needs and/or apply the logic differently.
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
var startTime:Number = 0;
var currentTime:Number = 0;
var gameTime:Number = 4;//"game" time on enter frame
var GlowTimer:Timer = new Timer(950,0);//"delayed" time on press
btnGlowTest.visible = false;
GlowTimer.addEventListener(TimerEvent.TIMER, GlowTimeListener, false, 0, true);
btnTest.addEventListener(MouseEvent.MOUSE_DOWN, btnTestPressed, false, 0, true);
addEventListener(Event.ENTER_FRAME,TimerFunction, false, 0, true);
startTime = getTimer();
function TimerFunction(event:Event)
{
currentTime = getTimer();
var timeLeft:Number = gameTime - ((currentTime - startTime)/1000);
timeLeft = Math.floor(timeLeft);
trace("timeLeft = " + timeLeft);
if(timeLeft <= 0)
{
trace("time's up, 3 bucks off");
StopTime();
}
}
function GlowTimeListener (e:TimerEvent):void
{
trace("TIME DELAY COMPLETE!");
StopTime();
}
function btnTestPressed(e:MouseEvent)
{
trace("PRESSED");
removeEventListener(Event.ENTER_FRAME, TimerFunction);
btnGlowTest.visible = true;
GlowTimer.start();
}
function StopTime()
{
trace(">>--Stop Time--<<");
btnGlowTest.visible = false;//just for show
btnTest.visible = false;//just for show
GlowTimer.stop();
removeEventListener(TimerEvent.TIMER, GlowTimeListener);
removeEventListener(Event.ENTER_FRAME, TimerFunction);
}