wavesurfer get elapsed time in real time - javascript

I'm using katspaugh's waveSurfer library for playing sound files.
I wrote code to show 'elapsed time / total time' in this way.
waveSurfer.on('play', function() {
$scope.getCurrentDuration();
});
$scope.getCurrentDuration() is a function to transform floating-type variable to string-type variable, like below:
$scope.getDuration = function() {
if ($scope.waveSurferReady) {
var time = waveSurfer.getDuration(); // get duration(float) in second
var minute = Math.floor(time / 60); // get minute(integer) from time
var tmp = Math.round(time - (minute * 60)); // get second(integer) from time
var second = (tmp < 10 ? '0' : '') + tmp; // make two-figured integer if less than 10
return String(minute + ':' + second); // combine minute and second in string
}
else {
return 'not ready yet'; // waveSurfer is not ready yet
}
};
But the problem is,
in this part:
waveSurfer.on('play', function() ...)
the callback function execute only once.
I expect the callback function called periodically, but it executes only once, so as the result, elapsed time is shown only at the start time.
How can I solve this?

Looking into the source, I've found the audioprocess event paired with html5 timeupdate event.
Try it out.
waveSurfer.on('audioprocess', function() {
// do stuff here
});

Related

Trigger client side javascript based on datetime

I have an event_start time and I want to run a script 10 seconds after that event start but can't figure out how to trigger the script.
const date = Date().toString();
const currentDateParse = Date.parse(date);
const trigger = Date.parse(startTime) + 1000 * 10
Then this is how I'm attempting to trigger the script but it's not working. How do I start my function when the currentDateParse is equal to trigger. Or, put more simply, 10 seconds after the event starts.
if (currentDateParse = trigger)
<function code underneath works already>
Calculate the time difference between now and when you want to trigger the script, and use setTimeout() to call it then.
const timediff = trigger - new Date().getTime();
setTimeout(function() {
// do what you want
}, timediff);
Try this (explanations below):
let startTime = "18:00";
let currentTime = new Date();
let target = new Date().parse(startTime);
let timeout = target - currentTime + 1000 * 10; // how long should it wait till the functions is executed
function runTenSecAfterEvent() {
// do something here
}
setTimeout(runTenSecAfterEvent, timeout);
Explanations
After you calculated target (the start time) and currentTime, you need to know the time difference between them (timeout), so target minus currentTime. After that, you add the 10000ms.
And then you define the function which will be executed 10 seconds after the event occurred (runTenSecAfterEvent()).
Finally, you create a timeout.

Loop to Open A WebPage with PhantomJS (With Different Parameters Per Loop Iteration) Not Working

When I try to use the following loop to open a page:
console.log("Just before time, endTime and loopnumber gets declared.");
var time, endTime;
var loopnumber = 6;
console.log("time declared as '"+time+"', loopnumber as '"+ loopnumber+"'");
for (time = 1490543999999999, endTime = time - 518400000000 * 10; time > endTime; time -= 518400000000) {
console.log("inside loop. time declared as '"+time+"', loopnumber as '"+ loopnumber+"'");
var mintime = time - 518399999999;
page.open('https://myactivity.google.com/item?min='+mintime+'&max='+time+'&product=5,6,7,10,11,12,13,15,19,20,25,27,28', function () {
console.log("inside callback");
page.render('/Users/jMac-NEW/Documents/FILEMAKER OCLC/login_test33.1_brkpoint'+loopnumber+'.png');
fs.write('/Users/jMac-NEW/Documents/FILEMAKER OCLC/login_test33.1_brkpoint'+loopnumber+'html.html',page.content,'w');
});
loopnumber++;
}
console.log("inside loop. time declared as '"+time+"', loopnumber as '"+ loopnumber+"'"); gets called, but not the console.log inside the callback function of page.open. page.render and fs.write also does not work (I do not see the expected result file in my directory.)
How come?
EDIT:
If it's just because page.open doesn't have enough time, how can I give it enough time? with setInterval()?
EDIT2:
What I am trying to get the code to do is to call myactivity.google.com/item with a different set of arguments for each iteration of the loop, save the webpage as a .png file and an .html file.
Yes, I have imported fs before this code segment, just that it isn't shown here.
Perhaps the easiest way is to have the next page load be trigger by the callback from the previous page load. That way you know that the previous page has finished loading (note however, that loaded doesn't necessarily mean rendered and if there's a bunch of Javascript running on your page to render something - like a chart for example, you still my be rendering your screen before it's finished)
Something like this:
var time = 1490543999999999;
var endTime = time - 518400000000 * 10;
var mintime = time - 518399999999;
page.open('https://myactivity.google.com/item?min=' + mintime + '&max=' + time + '&product=5,6,7,10,11,12,13,15,19,20,25,27,28', callback);
function callback() {
console.log("inside callback");
page.render('/Users/jMac-NEW/Documents/FILEMAKER OCLC/login_test33.1_brkpoint' + loopnumber + '.png');
fs.write('/Users/jMac-NEW/Documents/FILEMAKER OCLC/login_test33.1_brkpoint' + loopnumber + 'html.html', page.content, 'w');
time -= 518400000000;
if (time > endTime) {
var mintime = time - 518399999999;
page.open('https://myactivity.google.com/item?min=' + mintime + '&max=' + time + '&product=5,6,7,10,11,12,13,15,19,20,25,27,28', callback);
}
}

Problems with youtube API function

I am looking for a way to have player.getDuration() and player.getCurrentTime() from youtube API, written in normal time (Minute:Seconds) Like this bellow:
var mind = player.getCurrentTime() /*or player.getDuration()*/ % (60 * 60);
var m = Math.floor(mind / 60);
var secd = mind % 60;
var s = Math.ceil(secd)
document.write(m,":",s); seconds;
But it keeps sending an error NaN:NaN
Also I want to change an image when the video has finished using the function YT.PlayerState.ENDED like this:
if(YT.PlayerState.ENDED){
$("#change").attr('src', "../play button.png");
}
But it is not working?
Make sure you call these function when the video has been loaded or else it will be NaN. Just alert(player.getCurrentTime()); and see what the output is.
-
Your if statment if wrong. You are comparing ENDED with nothing. See this for an example
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) {
}
}
Most likely player is not properly set.
Also, the value of getCurrentTime() changes during playing; put the code in a function which you call every second.
Maybe use jquery.min.js to display the value.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type='text/javascript'>
var player; // Reference to global player object.
// call the function every 1 second.
setInterval(displTime,1000); // PUT THIS STATEMENT JUST AFTER THE PLAYER HAS BEEN CREATED.
function displTime() {
if (! player)
alert("NO player object !"); // Check if player has been set.
// player.getCurrentTime() or player.getDuration()
var mind = player.getCurrentTime(); // returns elapsed time in seconds
var m = Math.floor(mind / 60);
var secd = mind % 60;
var s = Math.ceil(secd)
$("#pt").html(m + ":" + s); // Using the JQUERY library to write to body
}
</script>
<div id="pt"></div> <!-- Put this in the html BODY to display m:s -->

Gmail-like countdown timer not working

I've been trying to recreate a countdown timer similar to the one gmail uses that when you get disconnected from internet. The ajax request fails then it begin a short countdown then makes another ajax request and if it fails again then begin a longer countdown and so forth. Once a determined countdown value is reached (lets say 1 minute), the countdown is maintained at 1 minute until the internet connection is recovered or the servers comes back.
I don't want to use a plugin because this code will be embedded in a micro-controller that has limited space and also prefer not to place it as external file for practical reasons, even though jQuery library will already be external.
Everything should trigger onload, and continue automatically (i.e. no control inputs will be used).
So far I've developed code that does what I want if the ajax request succeeds or fails immediately but if there is a latency on the ajax request status (as for example having the server down) the browser won't produce an immediate result and my code fails.
I know what I stated above because I actually took the server down and was been help by firebug on Mozilla Firefox to see that the ajax result (success or failure) wasn't triggered immediately but keep waiting for several seconds.
Help please!
html code:
<div id='tempFail' ></div>
jQuery code:
$(document).ready(function()
{
//do when DOM ready - http://api.jquery.com/ready/
var timerSpeed = [1000, 5000, 10000, 20000, 30000, 60000];
// current time in ms since 1/1/1970, plus the initial reload interval
var end = (new Date).getTime() + timerSpeed[1];
var n=0;
var m=0;
setInterval(function()
{
var now = (new Date).getTime();
// Current time left to re-load in seconds, sometimes it goes to negative values, see below
var secLeft = Math.floor(( end - now ) / 1000);
// if secLeft is negative multiply by zero...equal to secLeft=0, this will produce an error of one second approximately
var timeToload = (secLeft < 0) ? secLeft * 0 : secLeft;
if (n!=0)
{
//check for failed or delayed request\n\
$('#tempFail').html('Failed or delayed response. Will auto load in: '+timeToload+ ' seconds!');
}
if( (secLeft)<=0)// if reload time is reached do
{
if (m==0)//used to prevent multiple continue reloads when ajax request status is not yet defined
{
m=1;
$.getScript('script_vars.js').done(function (data)
{
//if request succeeded
m=0;
n = 0;
end = (new Date).getTime() + timerSpeed[1];
// Time to load after the initial interval set above
$('#tempFail').html('');
//other code on success here
})
.fail(function()
{
//if request failed
m=0;
n ++;
if(n==6) n=5;
switch(n){ //timer delay for failed request\n\
case 1:
end = (new Date).getTime() + timerSpeed[1];
break;
case 2:
end = (new Date).getTime() + timerSpeed[2];
break;
case 3:
end = (new Date).getTime() + timerSpeed[3];
break;
case 4:
end = (new Date).getTime() + timerSpeed[4];
break;
case 5:
end = (new Date).getTime() + timerSpeed[5];
break;
}
});
}
}
}, 1000);
});
You asked for an example so I've written the following, you may want to wrap the contents of the function within another function so you can repeat it/don't have to worry about namespaces/etc. Didn't test so don't expect bug free!
Using window.setTimeout for every action, separated each stage into it's own function so code paths can more easily be followed.
$(document).ready(function () { // http://api.jquery.com/ready/
var $tempFail = $('#tempFail'),
delay = [1000, 5000, 10000, 20000, 30000, 60000],
delay_index = 0,
delay_ends = 0,
inform_user_ref = null,
inform_user = function inform_user() {
var now = (new Date).getTime(),
delta; // for difference, calculate later
if (delay_ends > now) { // if we're waiting for a retry
delta = Math.floor((delay_ends - now ) / 1000); // calculate time to wait
$tempFail.html('Failed or delayed response. Will auto load in: '+delta+ ' seconds!'); // let people know
window.setTimeout(inform_user, 200); // loop countdown timer
// can fast refresh this as it's just a countdown
}
},
get_success = function () {
$tempFail.html('');
// .. code on success
},
get_fail = function () {
delay_index < 5 && ++delay_index; // increment delay_index
get_initialise(); // retry
window.clearTimeout(inform_user_ref); // remove any old countdown timer
inform_user_ref = inform_user(); // and display new countdown
},
get_try = function () {
$.getScript('script_vars.js')
.done(get_success)
.fail(get_fail);
},
get_initialise = function () {
delay_ends = (new Date).getTime() + delay[delay_index];
window.setTimeout(get_try, delay[delay_index]); // retry
};
get_initialise(); // initial
});
Wow! Mr Paul S. your code was crazy good. I just made a couple of adjustments to have it perfectly working as I need it.
Added the following on ajax success:
delay_index = 0; //reset delay_index
get_initialise(); // retry
so I keep the code running every 5 seconds if everything goes ok.
2.
Added two new variables: let_cntDwn_end and ajax_rqst_status to avoid countdown number jumping (to let countdown finish before beginning the next one ) and to display a message while the ajax request haven't given any result respectively.
Here is the new code:
$(document).ready(function(){ //do when DOM ready - http://api.jquery.com/ready/
var $tempFail = $('#tempFail'),
delay = [5000, 5000, 10000, 20000, 30000, 60000],
delay_index = 0,
delay_ends = 0,
inform_user_ref = null,
let_cntDwn_end = 0,
ajax_rqst_status = 0, //ajax success or failure triggered
inform_user = function inform_user() {
var now = (new Date).getTime(),
delta; // for difference, calculated later
if (delay_ends > now) { // if we're waiting for a retry
let_cntDwn_end = 1;
delta = Math.floor((delay_ends - now ) / 1000); // calculate time to wait
if (ajax_rqst_status==0){
$tempFail.html('Failed response. Will auto load in: '+delta+ ' seconds!'); // let people know
window.setTimeout(inform_user, 900); // loop countdown timer
// can fast refresh this as it's just a countdown
}
}
else {let_cntDwn_end = 0; get_try();}
},
get_success = function () {
ajax_rqst_status =0;
$tempFail.html('');
// .. code on success
delay_index = 0; //reset delay_index
get_initialise(); // retry
},
get_fail = function () {
ajax_rqst_status =0;
delay_index < 5 && ++delay_index; // increment delay_index
get_initialise(); // retry
window.clearTimeout(inform_user_ref); // remove any old countdown timer
inform_user_ref = inform_user(); // and display new countdown
},
get_try = function () {
if (let_cntDwn_end == 0){
ajax_rqst_status=1;
$tempFail.html('Waiting for Ajax request success or failure'); // let people know
$.getScript('script_vars.js')
.done(get_success)
.fail(get_fail);
}
},
get_initialise = function () {
delay_ends = (new Date).getTime() + delay[delay_index];
window.setTimeout(get_try, delay[delay_index]); // retry
};
get_initialise(); // initial
});
There's also JS lib which handles this for you by monitoring ajax requests.
https://github.com/HubSpot/offline

Facebook server time in javascript

Im trying to show on my site changeable clock synchronized with facebook server.
The fb server time is available at:
https://api.facebook.com/method/fql.query?query=SELECT+now%28%29+FROM+link_stat+WHERE+url+%3D+%271.2%27&format=json
How to make it changeable every second without refreshing the page?
Assuming some non-written functions, it should look like that:
var requestBegin = Date.now();
getServertimeFromFacebook(function callback(fbTime) {
var requestEnd = Date.now();
var latency = (requestEnd - requestBegin) / 2;
var curDevicetime = Date.now(); // = requestEnd, of course
var difference = fbTime - latency - curDeviceTime;
function clock() {
var cur = Date.now();
var curFbTime = cur + difference;
show(curFbTime); // print, log, whatever
};
setInterval(clock, …); // you could use a self-adjusting clock
// by using a setTimeout for each tick
});
You could do
show = function(t) { console.log(new Date(t).toString()); };
getServertimeFromFacebook = function(cb) {
ajax("https://api.facebook.com/method/fql.query?query=SELECT+now%28%29+FROM+link_stat+WHERE+url+%3D+%271.2%27&format=json", function(responsetext) {
var obj = JSON.parse(responsetext);
var ts = obj[0].anon,
tms = ts * 1000;
cb(tms);
});
};
I wouldn't call the API every second.
Instead, I would get the Facebook server time only one time at the beginning. And then, I would increment my time value every second by looping using javascript :
setTimeout(function() { /* increment time */ }, 1000);
Bergi: [{"anon":1354654854}] is a unix time. Indeed, Facebook often (always?) deals with time using this representation.

Categories

Resources