using jquery + <audio> w/ php/mysql to loop playback times - php

I've got a page with an iframe. The iframe is using jquery.scrollTo to detect the audio playback time and keep the contents, lyrics for example, linked to the right point in the audio.
Each line of text is being pulled from a mysql table. What I'm trying to do is to allow the user to click on a line in the <iframe> and have the audio in the parent page play at that point. Here's the code that grabs the times, which exists after the jquery that handles the other audio functions:
<?php
include 'mysqlt.php';
$entries=mysql_query("SELECT * FROM `database`.`table`") or die(mysql_error());
while ($ent = mysql_fetch_object($entries)) {
$segment = $ent->index;
$starttime = $ent->time;
$nextline = $ent->time2;
$length = ($nextline - $starttime); ?>
That same information is also duplicated in the iframe source page along with the individual lines of lyrics. The jquery that uses this info follows:
$("#iframe_id").contents().find("#button_in_iframe<?php echo $segment;?>").bind("click", function(){
audioplayer.currentTime = <?php echo $time;?>;
audioplayer.play();
}
<?php } ?>
This second part loops, echoed once for each each potential line in the iframe that can be clicked. #button_in_iframe<?php echo $segment;?> ends up as something like #button_in_iframe23 for the 23rd line.
I've got jquery loaded up in both the parent and the iframe. As far as I can tell, the syntax is what it should be. If I remove this bit of code, everything works normally. if it's in there, the basic audio functions on the normal controls I have set stop working. So this is not only not working, but it's causing everything else associated with the audio tag's controls to stop working as well. I know that any small error in the audio controls' jquery is enough to make it stop working, but in this case I'm not sure where the problem is.
Thanks in advance for any insights anyone might be able to offer.
update:
I've got it so it no longer crashes the audio tag. Now it's more an issue of the iframe's item not triggering an event. Here's the code now:
$('#iframe_id').contents().find("button.loop2").bind("click", function() {
alert ("test");
});
I'm not getting any console errors except for a Google Maps imbedded in the page in another location. When i click the <button> with class loop2 in the iframe, all of which exist, nothing's happening. That seems to be the root of the problem as it was earlier.

I figured out how to do it. I've set the loop on the parent to read as follows:
play<?php echo $segment; ?> = function(){
sfx.currentTime = sounds.getCueById(id).startTime;
sfx.play();
};
Then in the iframe's page, I've told each button to call parent.play<?php echo $segment;?>();
I'm not sure why finding the tags in the iframe didn't work, but no matter. This get's the job done.
Thanks, shanabus, for all the suggestions.

Would it work to use media cues?
Example:
var sfx = new Audio('sfx.wav');
var sounds = a.addTextTrack('metadata');
// add sounds we care about
sounds.addCue(new TextTrackCue('dog bark', 12.783, 13.612, '', '', '', true));
sounds.addCue(new TextTrackCue('kitten mew', 13.612, 15.091, '', '', '', true));
function playSound(id) {
sfx.currentTime = sounds.getCueById(id).startTime;
sfx.play();
}
You can find a better definition of the spec half way down the page here - http://dev.w3.org/html5/spec/Overview.html
So in your case, maybe something like:
$("#iframe_id").contents().find("#button_in_iframe<?php echo $segment;?>").bind("click", function(){
sounds.addCue(new TextTrackCue('<?php echo $segment; ?>', <?php echo $starttime; ?>, <?php echo ($starttime + $length); ?>, '', '', '', true));
var id = '<?php echo $segment; ?>';
sfx.currentTime = sounds.getCueById(id).startTime;
sfx.play();
}
Or maybe separate your logic into two loops. One for building the cues, then one for building/binding the click events.
Hope this helps!

Related

setting iframe ID via fancybox2 to allow webdriver switchTo()->frame(id)

I'm using fancybox2 to create iframes but I can't see a way of setting the ID of the iframe that gets created, which is preventing me from using php-webdriver and selenium to test the contents of the iframe.
Simplified version of the code:
iframe
<script>
$(document).ready(function() {
$(".various").fancybox()
});
</script>
Which works, but using Chrome's inspector, the iframe was (this time) generated with an ID of
fancybox-frame1443817733402, which appears to be random. This means when I try to use php-webdriver to switch to this frame (having clicked the link to create the iframe), I can't predict the frame's ID to pass in:
$frame_id = 'fancybox-frame1443817733402'; // can't predict this in advance
$driver->switchTo()->frame($frame_id);
The iframe is always generated with a class of fancybox-iframe but calls to
$iframe = $driver->findElement(WebDriverBy::class("fancybox-iframe"))
return nothing.
I've also tried using fancybox2's afterLoad callback to try explicitly setting the iframe's ID before trying to switch to the frame by this ID, but that also fails (I think because current is an object, not an element?)
$(".various").fancybox({
afterLoad: function(current, previous) {
//console.log(current);
current.attr('id', 'rob');
}});
Is there a way of explicitly setting the iframe's ID so that I can switch to it via selenium/webdriver? Or is there a simpler way of doing this?
I don't know about setting the frame id here, but you can switch to a frame via xpath (such as //frame):
protected WebElement gotoIframeByXpath(final String iframeXpath) {
if (driver.findElements(By.xpath(iframeXpath)).size() > 0) { // find elements so an exception isn't thrown if not found
WebElement contentFrame = driver.findElement(By.xpath(iframeXpath));
driver.switchTo().frame(contentFrame);
return contentFrame;
} else {
System.out.println("Unable to find " + iframeXpath);
}
return null;
}
For anyone interested, following #EGHM's answer above, this is how I did it.
// this also works & is a little simpler
//$iframes = $driver->findElements(WebDriverBy::tagName('iframe'));
$iframes = $driver->findElements(WebDriverBy::xPath('//*[starts-with(#id,"fancybox-frame")]'));
$id = $iframes[0]->getAttribute('id');
$driver->switchTo()->frame($id);
echo $driver->getPageSource();

PHP: Dynamic Pages with multiple dynamic content

I'm using this a particular code to dynamically load content on a webpage.
Problem is, I want to use it to load multiple things on the same page. How do I go about making this possible? I've already isolated the problem to the fact that the second instance of the code that runs replaces the entire URL instead of appending an additional ?="pageurl" but I'm stuck right there.
I've got a second script that uses the variable p instead of b so the browser knows to load p's content in a different location.
This is what the code does:
http://www.youtube.com/watch?v=Qg-EBdNaUbo
[edit]
Not sure why you guys can't see the link, it explains everything. I'm calling the script via a link Here is the link again youtube.com/watch?v=Qg-EBdNaUbo
CODE:
<?php
$pages_dir = 'pages';
if(!empty($_GET['b']))
{
$pages = scandir($pages_dir, 0);
unset($pages [0], $pages [1]);
$b = $_GET['b'];
if(in_array($b, $pages))
{
include($pages_dir.'/'.$b);
}
else
{
echo 'sorry page not found';
}
}
else
{
}
?>

Increasing PHP Variable onSroll without reloading the page

Ok,
I've seen a couple of solutions out there but I am looking for the most lightweight version to accomplish this following:
<?php
$number = 20;
$counter = 0;
$i = 1;
$friends = $facebook->api('/me/friends');
foreach($friends['data'] as $friend)
{
if ($counter++ == $number) {
break;
}
echo '<li id="'.$i++.'"><img src="http://graph.facebook.com/'.$friend['id'].'/picture"/>'.$friend['name'].'</li>';
}
?>
I want to be able to increase $number = 20 when the user scrolls past a speecific div.
So for instance I know I can use jQuery for the scrolling mechanism:
<script>
$('#20').waypoint(function(event, direction) {
if (direction === 'down') {
"Increase php variable to 40"
};
});
</script>
If you guys can provide any knowledge it would be much appreciated.
Thanks!
PHP runs server sided, meaning that the whole page gets computed before outputting. What you are doing is not possible the way you are approaching it.
There are two approaches that will work in this situation:
Output all the information to begin with, but hide it and when the user scrolls to whatever point show it programatically with Javascript
Use AJAX to do dynamic page generation.
AJAX allows you to make requests to the server from Javascript to request remote content. For example, you could grab the content of myFile.php?count=123 and output the result in a div.
See http://www.w3schools.com/ajax/ajax_example.asp for an example on how to use AJAX.

Refresh individual table cells without refreshing whole page

I have a table with lots of cells that have little php scripts in them that search a text document called foo.txt for a snippit of numbers. The code really isn't needed to understand my problem but just in case:
<?php
$input = "3.000000";
$file = file_get_contents("foo.txt");
$pos = strrpos($file, $input);
if($pos !== false){
$start = $pos + strlen($input);
$end = strpos($file, "00", $start);
$data = substr($file, $start, $end - $start);
$dataprocessed = round($data, 2, PHP_ROUND_HALF_DOWN);
echo $dataprocessed;
}else{
echo "Error";
}
?>
From that i would get a number like "34.23" which is correct. The problem is that foo.txt changes/gets overwritten every minute, changing that "34.23", but the webpage wont display the new data unless the whole page is refreshed. I want to somehow have it so that the new/overwritten data is displayed in a tag without refreshing the entire page every minute. I have experience in HTML/XHTML, PHP, limited experience in JavaScript/JQuery, and have been reading posts and tutorials on AJAX but cant quite get it to work. Im open to creative solutions and any solution. Thanks so much in advance!
You can use setInterval and $.load() to use AJAX to reload parts of your page every couple of seconds:
$(function(){
setInterval(function(){
$('div#table-container').load('website_url.php?randval=' + Math.random() + ' div#table-container table');
},10000);
});
Every 10 seconds, this will load website_url.php via AJAX and grab just the div#table-container table portion and insert into the current page by replacing what is currently inside div#table-container
the ?randval=' + Math.random() is a workaround to solve an IE6 caching issue, if you are worried about IE compatibility.
http://api.jquery.com/load/
if you id your table cells in a uniform fashion like:
<tr>
<td id ="a1"></td>
<td id ="a2"></td>
<tr>
<tr>
<td id ="b1"></td>
<td id ="b2"></td>
<tr>
then have an ajax call set up on an interval to a php page, thats server chages in JSON format like: [{'cell': 'a1', 'value': '34.7}];
you could replace them with calls like:
for (item in results) {
$("#" + item.cell).val(item.value);
}
The only thing left after that is keeping a serial# for the data. Every time it changes, it gets a new serial number. So when the client askes for changes, it presents a serial number, and you can update it. The next time that client askes it should present the newest serial number. That way you aren't constantly sending all changes to every client.
I would use AJAX with the setInterval to check if changes are to be made (comet) nd for the tagging get the number of column and line and use a nth-child() modifier with jquery example:
$(table#example tr:nth-child(2) td:nth-child(5)).html('my new html answer');
// meaning 2nd row 5th column
To obtain the nth child values, possibly useful, you would use
$(this).index()+1 because nth-child is not 0 based

Protect a generate image with php

I'm having a problem here and I think people here can help me.
I have a file that generates an image, ler.php, and the file that loads the images through a while, carregar.php.
I need to block direct access to the images generated by ler.php, tried to make a system like this session:
carregar.php:
<?
$_session['a'] = 1;
while($a != 50) { echo "<img src='ler.php?imagem=$a'>"; $a++; }
$_session['a'] = 0;
?>
ler.php:
<? if($_session['a'] == 1) { //load image } ?>
The result is the only loading the first image.
I'm trying to now use the $_SERVER ["PHP_SELF"], placing the IF of ler.php, what happens is I load it through <img src=''> she identifies as carregar.php.
Who has the best solution?
I've tried several ways with $_SESSION and it seems to not really work.
I could suggest two ways:
Easy to implement, less protective: in ler.php check that $_SERVER["HTTP_REFERER"] refers to "carregar.php".
A little bit more complicated: in carregar.php generate an unique code for each image you're going to output and store it in $_SESSION. Then pass the code to ler.php as a GET parameter. In ler.php check if the code exists in $_SESSION object, then generate an image and remove the code from $_SESSION.
I have a hard time identifying the problem, but your use of the session is going to lead to unexpected results:
You are adding 50 (I guess...) image tags to a page and right after you have added these tags, you set the session variable to 0.
The browser only loads a few files from the same server at the same time, so when the script is done and the first image is loaded, the browser is going to request the next image but that will fail as you have set the session variable to 0 already.
The only way to reliably set the session variable to 0 after all images have loaded, is an ajax request from your page that checks and triggers after all images have completely loaded.
Good! I managed to resolve one way and improvised without using AJAX:
ler.php:
<?php
if(isset($_SERVER["HTTP_REFERER"])) {
$check2 = (strpos($_SERVER["HTTP_REFERER"], 'carregar.php') > 0) ? true : false;
if(print_r($check2) != 11) {
// Blank
}
} else {
if(isset($_SERVER["HTTP_REFERER"]))
{
// Load Image
}
if(!isset($_SERVER["HTTP_REFERER"]))
{
// Blank
}
?>
So, the image only can be loaded into my page. Maybe...

Categories