Log in

View Full Version : Array to Provide One Random MP3 to Audio Tag



KennyP
01-13-2015, 11:40 AM
Can you guys please tell me why the PHP code below fails to provide an MP3 file to the audio tag?

There are seven mp3 files in the folder "bgAudio" that is in the root directory.


<?php
$files = glob('/bgAudio/*.mp3'); // get all seven .mp3 files in bgAudio directory - 1.mp3, 2.mp3, 3.mp3, 4.mp3, 5.mp3, 6.mp3, and 7.mp3
$fname = $files[array_rand($files)]; // get a random filename
echo $fname;
?>

<audio autoplay="autoplay" id="bgAudio">
<source src="<?php echo $fname; ?>"/>
</audio>

<script>
jQuery(function($) {
$("#bgAudio").prop('volume', .7);

window.setVolume = function(bgAudio,vol) {
sounds[bgAudio].volume = .7;
}
});
</script>

Beverleyh
01-13-2015, 12:56 PM
Looks like its due to the first backslash here;
$files = glob('/bgAudio/*.mp3');

Putting a backslash at the start of a path translates as "from the root", which wont work on a server (although it will in client-side HTML/CSS when it can resolve to your domain).

Your actual server root path will be something like '/home/www/mywebsite.com/' or '/home/user/public_html/mywebsite/', etc., so you can either use an absolute path;
$files = glob('/home/www/mywebsite.com/path/to/bgAudio/*.mp3'); OR use a relative path;
$files = glob('bgAudio/*.mp3');

The good news is that your code works fine - I tested it with a relative path here :)

KennyP
01-13-2015, 08:04 PM
Thank you for your reply Beverley. It's also working for me by just removing the backslash as ('bgAudio/*mp3');
However, I fail to understand just how the script is able to find the folder 'bgAudio', which is sitting in the root, which is about four to five levels away from the header.php file.

Wait a second... is it able to find it because the header file is actually being called by the index.php file that is also located in the root?

Just out of curiosity however, why won't it work by using the server root path... /home/billyjoe/public_html/bgAudio/*.mp3
I believe that path is correct; 'bgAudio' is in the 'public_html' folder.

Question: Can a fade-in function be added to the audio tag or the rest of the code? I thought it would be a good idea to fade-in the sound in order to prevent visitors from being jolted out of their seats in case their sound volume is up too high

Thanks again

EDIT: Beverley - I got it working :)

I added...

$("#bgAudio").animate({volume: 1}, 6000);

Deadweight
01-13-2015, 11:38 PM
I am not sure if this is what you are entirely looking for:
http://www.html5tutorial.info/html5-audio.php

KennyP
01-14-2015, 12:14 AM
Thanks for your feedback deadweight, but no, that is not it.
I wanted the audio to fade-in, and finally I got it working by adding...


$("#bgAudio").animate({volume: 1}, 6000);

Beverleyh
01-14-2015, 06:18 AM
Wait a second... is it able to find it because the header file is actually being called by the index.php file that is also located in the root?Yes. It doesn't matter where the header or any other included files are - if the main index file/page is the one that's pulling them all together when its viewed in a web browser, then the audio folder path will be relative to that.

It should work with a full/absolute server path. It does for me. Double check what that is to make sure you haven't mistyped.

Glad you got the audio fade working though.

KennyP
01-15-2015, 04:35 AM
Thanks Beverley.

I tried using the server path again unsuccessfully. According to the cPanel, the path is /home/billyjoe
Then, the folder bgAudio is in the public_html folder, which contains the rest of the website.
Therefore, you would think /home/billyjoe/public_html/bgAudio/*.mp3 is the correct full path. Not so. That still doesn't work.

I'm glad bgAudio/*.mp3 does work, so I'll just leave it at that for now.

Beverley, there is one last function I've been trying to add to this audio setup unsuccessfully.

Do you know how I can get a small overlay to display over the page only during the time that a music selection is playing, in order to display its title?

Random music selections play here (http://www.billyjoeconor.com/), but only on a visitor's first visit per browsing session, and after the close of the splash/welcome page.

Thanks

Beverleyh
01-15-2015, 09:54 AM
Like this? http://fofwebdesign.co.uk/template/_testing/audio-random-caption.php

To get the Song Title from $fname, do something like this;
$ftext = ucwords(str_replace('_', ' ', basename($fname, '.mp3')));I use underscores instead of spaces in my filenames so I used str_replace() to switch them back.

Beverleyh
01-15-2015, 04:09 PM
Can you guys please tell me why the PHP code below fails to provide an MP3 file to the audio tag?

You know, I read your first post again and the penny just dropped...

Ok, so when you use the absolute server path $files = glob('/home/www/mywebsite.com/path/to/bgAudio/*.mp3'); and read all the mp3s in to the $files array, the paths that they print out will each be like "/home/billyjoe/public_html/bgAudio/*.mp3", which of course won't work in an HTML page (in the audio src) because an absolute path in HTML need to be something like "http://billyjoe.com/bgAudio/*.mp3" or "/bgAudio/*.mp3" (the way you formatted the absolute path in you first post makes total sense now). You would need to manipulate the $fname variable to strip it back to an HTML-friendly path format.

Whereas the relative path suits the PHP and HTML audio src just fine.

Doh, I am dippy sometimes. I only realised what was happening after I manipulated it for the $ftext variable in my post/demo above (and had a break, and ate lunch...)

KennyP
01-16-2015, 03:36 AM
Beverley:

Thank you so much. The demo you posted is exactly what I'm looking for.
However, I tried reproducing it and although the overlay does display, I
can't get the song title to display. Below is the full code if you could see
what I'm doing wrong:

Website (http://www.billyjoeconor.com/)

"The penny just dropped..." That is very funny. I've never heard it before.
I'll play around with the path again after completing this title overlay.
Thank you for that.

CSS

#info-box { width:800px; height:326px; float:right; display:none; color:#fff; text-align:center; vertical-align:middle; font:22px/1.85em Arial, Verdana, Helvetica, sans-serif; position:relative; top:20%; right:10%; color:white; z-index:55;}

SCRIPT


<!-- START | SONG PREVIEW ONLY ON FIRST VISIT -->
<div style="background-image:url(/imgs/guitar-background.png); position:center center; repeat: no repeat;" id="info-box"><p style="margin-top:100px; margin-right:400px;">A Preview Of<br>' <b><?php echo $ftext; ?></b> '<br>from <b><span style="color:red;">Billy Joe's</span> Debut CD</b></p></div>
<?php
if($revisit){
?>

<?
} else {
?>

<?php
$files = glob('bgAudio/*.mp3'); // get all .mp3 files in the music directory
$fname = $files[array_rand($files)]; // get a random filename
echo $fname;
$ftext = ucwords(str_replace('_', ' ', basename($fname, '.mp3'))); // get song title from $fname for display
echo $ftext;
?>

<audio autoplay="autoplay" id="bgAudio">
<source src="<?php echo $fname; ?>"/>
</audio>

<script>
jQuery(function($) {
$("#bgAudio").prop('volume', .7);

window.setVolume = function(bgAudio, vol) {
sounds.volume = .7;
}

$('#bgAudio').on('playing', function() {
$("#info-box").fadeIn();
});
$('#bgAudio').on('ended', function() {
$("#info-box").fadeOut();
});
});

</script>
<?php
}
?>
<!-- END | SONG PREVIEW ONLY ON FIRST VISIT -->

Also, for some reason, in Firefox the title display doesn't work in the demo as well as on the website.

Thank you so much Beverley.

PS - On your demo page there is just one path to one song . There are no additional selections listed,
and yet, on new page loads a different song plays? How is that possible?

[B]EDIT: When you resize the window as in the attached screenshot, the song title and path display at the left upper corner.

Beverleyh
01-16-2015, 01:46 PM
The #info-box markup is placed before the PHP so the $ftext variable isn't available to be echo'd into the div. If you move the PHP above #info-box, it should work though.


<?php
$files = glob('bgAudio/*.mp3'); // get all .mp3 files in the music directory
$fname = $files[array_rand($files)]; // get a random filename
//echo $fname;
$ftext = ucwords(str_replace('_', ' ', basename($fname, '.mp3'))); // get song title from $fname for display
//echo $ftext;
?>

<!-- START | SONG PREVIEW ONLY ON FIRST VISIT -->
<div style="background-image:url(/imgs/guitar-background.png); position:center center; repeat: no repeat;" id="info-box"><p style="margin-top:100px; margin-right:400px;">A Preview Of<br>' <b><?php echo $ftext; ?></b> '<br>from <b><span style="color:red;">Billy Joe's</span> Debut CD</b></p></div>
<?php
if($revisit){
?>

<?
} else {
?>

<audio autoplay="autoplay" id="bgAudio">
<source src="<?php echo $fname; ?>"/>
</audio>

<script>
jQuery(function($) {
$("#bgAudio").prop('volume', .7);

window.setVolume = function(bgAudio, vol) {
sounds[bgAudio].volume = .7;
}

$('#bgAudio').on('playing', function() {
$("#info-box").fadeIn();
});
$('#bgAudio').on('ended', function() {
$("#info-box").fadeOut();
});
});

</script>
<?php
}
?>
<!-- END | SONG PREVIEW ONLY ON FIRST VISIT -->And I would imagine that the text you're seeing when you resize the browser is from the echo lines - 2 slashes in front will comment them out so that they don't execute (lines in red), but you can still keep them for future reference.


PS - On your demo page there is just one path to one song . There are no additional selections listed,
and yet, on new page loads a different song plays? How is that possible?I'm not fully understanding what you mean by "one path to one song" and "no additional selections listed". Can you clarify please?

As for a different song loading on each page load, that's only because I have nothing in there to stop it after the first view. Its easier that way to demonstrate the PHP randomising effect when your press F5.


Also, for some reason, in Firefox the title display doesn't work in the demo as well as on the website.Which version of Firefox are you using and what OS? I'm on Windows 7 at the moment, running Firefox 29.0.1, and its OK on that. I'm just downloading an update so I'll see what happens when that's installed...

... waiting ...

Firefox 32.0.2, and we're still good there... but another update is downloading so I'll try again in a mo...

... more waiting ...

Firefox 35.0 and everything is still fine.

Try updating at your side and see if it works for you then.

KennyP
01-16-2015, 09:21 PM
Thank you once again Beverley. Just as you said, by moving the #info-box markup below the php and commenting out //echo $fname; and //echo $ftext; it works just great in IE and Chrome. However, still for some reason nothing at all displays in firefox. It was version 34.0.5 and now updated to version 35. I also am running Windows 7. It's weird that the same version browser doesn't display the box for me. Any ideas?

Beverleyh
01-16-2015, 10:56 PM
Hmmmm, I'm not a regular Firefox user (hence the version leaps on today's update) and I tend to skip around 3 or 4 desktop/laptops depending on which office I'm in or if I'm at home or my dad's, so maybe it's because the computer I was at today had a vanilla FireFox install -- no plugins or addons (whatever the prefered term is for Firefox). Could you have extra things installed that are maybe creating a conflict at your side? Are you able to reset it to default settings?

I will be able to check on a laptop tomorrow, and I'll make a point of checking on my dads PC when I see him on Monday.

I'll post back with my findings then.

Have a great weekend!

jscheuer1
01-16-2015, 11:09 PM
Exsqueeze me please. I haven't read all of this but I have some observations. If this is a PHP issue - the browser shouldn't make any difference. But - that said, as I say, I haven't been paying that close attention.

Anyways, if your PHP writes something out, all browsers will see that. Now of course it's possible that what the PHP writes out isn't standard. If that's the problem, you need to find out what the standard code is for what you are trying to output is and have the PHP on your server write it that way. It's also possible that there is no standard for what you want - not yet. That can happen. If that's the case you need the PHP to write out the provisional code (code that can be read by various browsers depending upon their capabilities). Again though, if that's the issue - it's still not PHP. It's how that code needs to be written. Google that, then write your PHP code to produce it.

KennyP
01-16-2015, 11:45 PM
Beverley / John:

Thank you both very much for your help and input. Unfortunately however, your advice is way over my head. Any additional help from you would be very much appreciated.

A great weekend also to you, thank you.

jscheuer1
01-17-2015, 04:56 AM
OK, this page seems to work well in Firefox here:

http://www.billyjoeconor.com

What exactly is the problem? No sound? No overlay? something else?

KennyP
01-17-2015, 06:37 AM
Thanks for checking John. In every version of Firefox, including the last update, version 35, there is no overlay to display the name of the selection. In other browsers, IE and Chrome, it works perfectly.

Beverleyh
01-17-2015, 10:46 AM
Hmmm, interesting.

I'm on a laptop here and am now seeing a problem, even on my demo page: http://fofwebdesign.co.uk/template/_testing/audio-random-caption.php

I have found a fix, but bear with me while I explain how I got to it...

It seems that the song plays fine but the overlay only shows on its second play, like the song needs to be cached and start playing immediately for Firefox to trigger the overlay. So, if you hit refresh several times you'll intermittently start seeing the overlay and it will get more and more frequent as all the songs start being cached.

So this got me thinking - the autoplay setting in the audio tag markup is the problem because that's not being controlled by JavaScript, while the overlay is. They are not bound together in any way.

So now the fix... If you take autoplay="autoplay" out of the markup, and trigger autoplay via JavaScript instead, everything seems to be fine $('#bgAudio').trigger('play');. The song will play when enough of it has loaded and then the event listener for 'playing' can trigger the #info-box overlay at the same time.

(Demo updated with working code)

KennyP
01-17-2015, 01:17 PM
WOW - Beverley - I'm amazed how you were able to figure it out! I just replaced the autoplay code and It's working for me in Firefox as well.

Thank you so, so much.

-- By tomorrow I hope to have a timeline and pause button displaying on the fretboard.

KennyP
01-19-2015, 08:01 PM
Beverley:

Now I was able to add a working timeline and a play/pause button with the second section of javascript below.

Everything works well except for the audio fade-in function that I had removed and now I put back. It worked

previously, so something in the rest of the script is over-riding it. Can you please see what it is so it can work again?

A final detail: Because the audio starts automatically on page load, the button continues to display the Play mode

when it should display Pause. Can it be made to display Pause initially?

Test Page (www.billyjoeconor.com/)


<?php
$files = glob('bgAudio/*.mp3'); // get all .mp3 files in the music directory
$fname = $files[array_rand($files)]; // get a random filename
//echo $fname;
$ftext = ucwords(str_replace('_', ' ', basename($fname, '.mp3'))); // get song title from $fname for display
//echo $ftext;
?>
<div style="background-image:url(/imgs/guitar-background.png); max-width:100%; background-position:center center; background-repeat: no repeat;" id="info-box">

<div style="float:left; width:382px; margin-left:15px; margin-top:141px; line-height:1.9;"><!--<span style="color:red;"><b>Now Playing</b></span> a Preview of<br>-->'<b><i><?php echo $ftext; ?></i></b>'<!--<br>from <b><span style="color:red;">Billy Joe's</span></b> Debut CD--></div>

<audio id="bgAudio" preload="true">
<source src="<?php echo $fname; ?>">
</audio>

<div style="width:400px; float:right; margin-right:0px; margin-left:0px; margin-top:132px" id="audioplayer">

<div style="margin-left:0px; float:left; width:253px;" id="timeline">
<div id="playhead">
</div>
</div>

</div>

<?php
}
?>

<script>
jQuery(function($) {

$('#bgAudio').trigger('play');

$("#bgAudio").animate({volume: 1}, 6000);

$('#bgAudio').on('playing', function() {
$("#info-box").fadeIn();
});
$('#bgAudio').on('ended', function() {
$("#info-box").fadeOut();
});
});

</script>

<script>
var duration; // Duration of audio clip
var pButton = document.getElementById('pButton'); // play button

// timeline width adjusted for playhead
var timelineWidth = timeline.offsetWidth - playhead.offsetWidth;

// timeupdate event listener
bgAudio.addEventListener("timeupdate", timeUpdate, false);

// timeUpdate
// Synchronizes playhead position with current point in audio
function timeUpdate() {
var playPercent = timelineWidth * (bgAudio.currentTime / duration);
playhead.style.marginLeft = playPercent + "px";
if (bgAudio.currentTime == duration) {
}
}

//Play and Pause
function play() {
// start music
if (bgAudio.paused) {
bgAudio.play();
// remove play, add pause
pButton.className = "";
pButton.className = "pause";
} else { // pause music
bgAudio.pause();
// remove pause, add play
pButton.className = "";
pButton.className = "play";
}
}

// Gets audio file duration
bgAudio.addEventListener("canplaythrough", function () {
duration = bgAudio.duration;
}, false);

</script>

Beverleyh
01-20-2015, 10:46 AM
I'm a bit tied up at the moment but try chaining the play trigger and audio fadein;

$('#bgAudio').trigger('play').animate({volume: 1}, 6000);

And just change the class of the button from .play to .pause for it's initial state;
<button id="pButton" class="pause" onclick="play()"></button>

KennyP
01-20-2015, 10:08 PM
Thank you so much Beverley. The button now properly displays the Pause state on page load / auto play.

The audio fade-in still doesn't work with
$('#bgAudio').trigger('play').animate({volume: 1}, 6000);
It starts at full volume.

Test Page (http://www.billyjoeconor.com/)

--Thanks again

Beverleyh
01-21-2015, 06:09 AM
Alternative option - Can you apply fades to the actual track with something like Audacity or mpTrim? http://mptrim.findmysoft.com/

You don't even have to install mpTrim. And it's so easy to add fade in and fade out - see the bottom right corner of the GUI http://mptrim.findmysoft.com/screenshot/

KennyP
01-22-2015, 03:53 AM
Beverly:

I figured there had to be nothing wrong with the fade-in code or else it wouldn't have worked previously.
So I tinkered with it until I finally guessed what it needed; setting the volume at 0 initially. :)

$("#bgAudio")[0].volume = 0;
$("#bgAudio").animate({volume: 1}, 4000);

Code Working on the Live Page (http://www.billyjoeconor.com/)

Thank you so, so much for your help.