Tutorial - Background music through whole course & controls

Hello,

I've found many topics with questions about background music in Storyline. Since I had to put some background music in one of my recent projects, now I can share with you the solution.

Although some posts already gave the simple code for music, I had also to implement stop/pause button, so there's a little bonus :) note that this will only work in HTML5 output (you can do it in flash also, with a little more work, but this won't be included here).

First of all, the files you need to edit (you need to do the same adjustments in both):
story_html5.html and when you publish for lms - index_lms_html5.html

If you don't need audio controls, you just want to music play automatically through whole course, jump to point 3)

So, you need to edit these files in some text editor (I recomend notepad++).
1) Find <head> and insert after last <meta> tag following line

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

it will load jQuery library to your course, so our javascript will be more userfriendly (and I don't know pure js, to be honest, so I'm using jQuery :))
2) now, still in <head> section, you should search for <style> tag, and to be precise - the end of it, </style>. And just BEFORE </style> you should paste following code:

#audio-player {width: 32px;
height: 32px;
display: inline-block;
position: absolute;
top: 30px;
left: 30px;
cursor: pointer;
z-index:9999;}
.audio-off {background: url('music-off.png') no-repeat;}
.audio-on {background: url('music-on.png') no-repeat;}

this will style our fancy music on/off switch.
For you who're not familiar with css: position: absolute, top: 30px and left: 30px will make the button appear in top left corner of the course, 30px from top and left. You can adjust those values, if you are using bulit-in storyline player you will need to move it a little more from left corner of course, so it will be visible. The audio off and on have background property pointing to two images - so you should place music-off.png and music-on.png in the same folder where the story_html5.html is located. You can, of course, change the music-off.png to let's say moff.jpg, feel free.

3) Ok, now we are leaving the <head> and we are going to <body> - right after start you can find

<div id="preso"></div>

And just before that line, you must paste that

<audio loop id="myAudio">
<source src="bg.mp3" type='audio/mp3'>
</audio>
<span id="audio-player" class="audio-off"></span>

That's basically an <audio> tag that that will play your music (named bg.mp3, located in the same folder as story_html5.html file), looped and it will have an autoplay. If you don't need  any controls, you can skip the last line with <span>.

4) Last step, just before an end of the document, right before </body>, paste the following script:

<script>
jQuery(document).ready(function( $ ) {
var myAudio = $("#myAudio");
var audiocontrol = $("#audio-player");
audiocontrol.hide();
setTimeout(function(){
audiocontrol.show();
myAudio.trigger("play");
var presdiv = $( "#presentation" );
var position = presdiv.position();
$(audiocontrol).css({top: position.top+20, left: position.left+20});
},1000);
$(audiocontrol).click(function() {
if ($(audiocontrol).hasClass("audio-off")) {
myAudio.trigger("pause");
audiocontrol.removeClass("audio-off");
audiocontrol.addClass("audio-on");
} else if ($(audiocontrol).hasClass("audio-on")) {
myAudio.trigger("play");
audiocontrol.removeClass("audio-on");
audiocontrol.addClass("audio-off");
}
});
});
</script>

That switches the audio between pause/play and changes the icon of our controls.

And that's all! You have working background music with switch.

You can see LIVE DEMO HERE

You can save the website to see the steps above in real file.

If you have questions - feel free to ask, I'll try to answer :)

EDIT 12.02.2019
Unfortunately, due to the browsers politics change (audio/video plays only on user action) - you should put some button on the start of your course inside storyline, with execute javascript trigger. The script should be

jQuery(document).ready(function( $ ) {
myAudio.trigger("play");
});
9 Replies
Matthew Bibby

Good work Mateusz, thank you for sharing this here. 

FYI, I'm noticing some inconsistent behaviour across browsers. 

For example, when I open this in Safari (on either my iMac or iPhone), the audio won't play until I click the button twice. Here is why.

In Chrome, Firefox, IE11 and Edge, the audio plays before the slide itself loads. This is less than ideal as there is no way for the end user to stop the audio as the button hasn't yet appeared. 

I also noticed when testing on mobile, that the audio button appears as the SL player is loading (but as this was in Safari there wasn't any audio until the button was pressed twice). The fun part was, I could then listen to the audio on that screen before hitting the Play button to start the course:

Finally in IE11 and Edge, it looks like the button isn't there it all. But it turns out that it was just positioned relative to the browser window rather than the SL player (and because the default button state is white, it looked invisible against the background):

I suspect that with a bit more fiddling around you should be able to get these inconsistencies sorted. Good luck and thanks again for sharing this.

Mateusz Szuter

Hello Matthew!

Thanks for your input.

As for IE11 and Edge - I have icon in left top corner of course container, as it should be, and as it is in Chrome, Safari or Firefox. Don't know why for you it's different.

As for Safari - thanks for pointing out! I didn't know about that. I've updated first post and demo, so now there's no 'autoplay' in html, but script will hit 'play' button, and it seems to work. You can check, and give me a sign :)

As for playing after the first screen of course is loaded - there is 'timeout' function in js, set to 1s, that should be enough for course to load its first screen. But it can be done by more elegant way and I will probably try to find out in the future, how to play music after loading sign vanish (shouldn't be hard, I just don't have time now to look at it).

And as for mobile, it can be handled with some simple jquery too :)

Matthew Bibby

Hi Mateusz,

I think with IE11 and Edge, it depends when the script is loading. If I open a private window, the button will load in the place shown in the pic above. However, if I open a normal window (knowing that the files are cached) it'll appear where you intended.

Regarding Safari. No change there. Also, in my latest test on Safari I noted that the button is positioned relative to the window as in IE11 etc.

A 1s delay isn't sufficient. I have relatively slow internet here (around 15mbps dl) and it took at least 5s for the slide to load. Chrome has a lovely network feature where you can deliberately throttle your connection (and bypass caching) to test how things work for those with average internet connections. 

Anyway, I'll leave you to it, let me know if you'd like me to test in Safari again for you at a later stage.

Mateusz Szuter

Hello Nitesh,

It does, but the user must do the first step, eg. click the note button in provided example, or you should make 'play' button which will trigger the music to play. Due to the changes in browser behaviour, I think it cannot be achieved other way. Autoplays are not welcome anymore :)

Jennifer Ritter

I want to start off by thanking you, Mateusz. This post has been extremely helpful. And I appreciate that you took the time to go back and add the edit for the browser updates.

I'd like to make two observations, the second of which should hopefully resolve the problem Nitesh was having with the execute JS trigger on the button:

1) In step 2 of the main post it says, "And just after </style> you should paste following code:" It looks like the specified code should actually be pasted in BEFORE </style>

2) Try using $('audio#myAudio')[0].play() as the JS for the button

Mateusz Szuter
Jennifer Ritter

I want to start off by thanking you, Mateusz. This post has been extremely helpful. And I appreciate that you took the time to go back and add the edit for the browser updates.

I'd like to make two observations, the second of which should hopefully resolve the problem Nitesh was having with the execute JS trigger on the button:

1) In step 2 of the main post it says, "And just after </style> you should paste following code:" It looks like the specified code should actually be pasted in BEFORE </style>

2) Try using $('audio#myAudio')[0].play() as the JS for the button

Hi Jennifer,
I don't know how the 1) could happen :o Of course I've corrected that mistake, and that's probably why for some people background music may not have been working. Thank you for the keen eye.

As for the second - yes, it can help. I will add that to the post also.

Jennifer Ritter

Found another addendum. Like putting the $('audio#myAudio')[0].play() javascript in a trigger to play the music loop, it's also possible to pause/stop the music by adding a $('audio#myAudio')[0].pause() javascript trigger. Then you can add the play javascript again to resume the music. The triggers mostly rely on image states, a number variable, and triggers firing "When variable changes." The method is based off the "clickcounter_mh.story" Michael Hinze shared at the start of this thread: https://community.articulate.com/discussions/articulate-storyline/change-states-when-object-is-clicked-on-multiple-times

So, if someone needs the music to toggle on and off (and can't use the controls you've provided) that should be an option.

I may make a separate post detailing how to do this.