AlexDerFerri
Member
GM Version: 2.2x - 2.3x
Target Platform: HTML5
Download: N/A
Links: N/A
Summary:
Have you ever wondered why your browser won't play your HTML5 application audio?
That's because modern browsers block all the audio sources as long as you do not interact with the page.
I found people suggesting making a Play Button before the main room actually start, so that the browser receive that click event and resumes the audio, but that does not seem to always work, unfortunately.
So here's how I managed to solve it.
Hope that will be useful for all of you struggling with this awful "bug".
Tutorial:
SETTING UP A NATIVE HTML BUTTON
So, after millions of tests, I found a solution:
I created an actual native HTML button: that way we make sure that the click event is managed directly by the browser.
Here's how to do it inside the index.html output file of your exported HTML5 application.
We simply add inside the body, inside the <div class="gm4html5_div_class" id="gm4html5_div_id"> an anchor tag which will represent our button.
HTML:
<a class="play-btn" id = "btn"></a>
I took a cool button style from this link: https://codepen.io/b29/pen/jmNvJq
CSS:
.play-btn{
width: 100px;
height: 100px;
background: radial-gradient( rgba(255, 0, 128, 0.8) 60%, rgba(255, 255, 255, 1) 62%);
border-radius: 50%;
position: absolute;
left: 45%;
top: 40%;
display: block;
/*margin: 100px auto;*/
box-shadow: 0px 0px 25px 3px rgba(255, 0, 128, 0.8);
}
/* triangle */
.play-btn::after {
content: "";
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translateX(-40%) translateY(-50%);
transform: translateX(-40%) translateY(-50%);
transform-origin: center center;
width: 0;
height: 0;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
border-left: 25px solid #fff;
z-index: 100;
-webkit-transition: all 400ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
transition: all 400ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
/* pulse wave */
.play-btn:before{
content: "";
position: absolute;
width: 150%;
height: 150%;
-webkit-animation-delay: 0s;
animation-delay: 0s;
-webkit-animation: pulsate1 2s;
animation: pulsate1 2s;
-webkit-animation-direction: forwards;
animation-direction: forwards;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: steps;
animation-timing-function: steps;
opacity: 1;
border-radius: 50%;
border: 5px solid rgba(255, 255, 255, .75);
top: -30%;
left: -30%;
background: rgba(198, 16, 0, 0);
}
HTML:
<script>
var el = document.getElementById("btn")
el.onclick = function() {
GameMaker_Init();
el.remove();
}
</script>
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Generated by GameMaker:Studio http://www.yoyogames.com/gamemaker/studio -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="pragma" content="no-cache"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name ="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta charset="utf-8"/>
<!-- Set the title bar of the page -->
<title>Created with GameMaker Studio 2</title>
<!-- Set the background colour of the document -->
<style>
body {
background: #0;
color:#cccccc;
margin: 0px;
padding: 0px;
border: 0px;
}
canvas {
image-rendering: optimizeSpeed;
-webkit-interpolation-mode: nearest-neighbor;
-ms-touch-action: none;
margin: 0px;
padding: 0px;
border: 0px;
}
:-webkit-full-screen #canvas {
width: 100%;
height: 100%;
}
div.gm4html5_div_class
{
margin: 0px;
padding: 0px;
border: 0px;
}
/* START - Login Dialog Box */
div.gm4html5_login
{
padding: 20px;
position: absolute;
border: solid 2px #000000;
background-color: #404040;
color:#00ff00;
border-radius: 15px;
box-shadow: #101010 20px 20px 40px;
}
div.gm4html5_cancel_button
{
float: right;
}
div.gm4html5_login_button
{
float: left;
}
div.gm4html5_login_header
{
text-align: center;
}
/* END - Login Dialog Box */
:-webkit-full-screen {
width: 100%;
height: 100%;
}
.play-btn{
width: 100px;
height: 100px;
background: radial-gradient( rgba(255, 0, 128, 0.8) 60%, rgba(255, 255, 255, 1) 62%);
border-radius: 50%;
position: absolute;
left: 45%;
top: 40%;
display: block;
/*margin: 100px auto;*/
box-shadow: 0px 0px 25px 3px rgba(255, 0, 128, 0.8);
}
/* triangle */
.play-btn::after {
content: "";
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translateX(-40%) translateY(-50%);
transform: translateX(-40%) translateY(-50%);
transform-origin: center center;
width: 0;
height: 0;
border-top: 15px solid transparent;
border-bottom: 15px solid transparent;
border-left: 25px solid #fff;
z-index: 100;
-webkit-transition: all 400ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
transition: all 400ms cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
/* pulse wave */
.play-btn:before{
content: "";
position: absolute;
width: 150%;
height: 150%;
-webkit-animation-delay: 0s;
animation-delay: 0s;
-webkit-animation: pulsate1 2s;
animation: pulsate1 2s;
-webkit-animation-direction: forwards;
animation-direction: forwards;
-webkit-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: steps;
animation-timing-function: steps;
opacity: 1;
border-radius: 50%;
border: 5px solid rgba(255, 255, 255, .75);
top: -30%;
left: -30%;
background: rgba(198, 16, 0, 0);
}
.body {
background-color: #2068bd
}
@-webkit-keyframes pulsate1 {
0% {
-webkit-transform: scale(0.6);
transform: scale(0.6);
opacity: 1;
box-shadow: inset 0px 0px 25px 3px rgba(255, 255, 255, 0.75), 0px 0px 25px 10px rgba(255, 255, 255, 0.75);
}
100% {
-webkit-transform: scale(1);
transform: scale(1);
opacity: 0;
box-shadow: none;
}
}
@keyframes pulsate1 {
0% {
-webkit-transform: scale(0.6);
transform: scale(0.6);
opacity: 1;
box-shadow: inset 0px 0px 25px 3px rgba(255, 255, 255, 0.75), 0px 0px 25px 10px rgba(255, 255, 255, 0.75);
}
100% {
-webkit-transform: scale(1, 1);
transform: scale(1);
opacity: 0;
box-shadow: none;
}
}
</style>
</head>
<body>
<div class="gm4html5_div_class" id="gm4html5_div_id">
<!-- Create the canvas element the game draws to -->
<canvas id="canvas" width="1066" height="594" >
<p>Your browser doesn't support HTML5 canvas.</p>
</canvas>
<!--href="javascript:GameMaker_Init()"--->
<a class="play-btn" id = "btn"></a>
</div>
<script>
var el = document.getElementById("btn")
el.onclick = function() {
GameMaker_Init();
el.remove();
}
</script>
<!-- Run the game code -->
<script type="text/javascript" src="html5game/NAME_OF_YOUR_GAME"></script>
</body>
</html>
This way, our browser will not complain anymore about the audio, as we interacted with an element of the page.
This method has been tested on mobile and desktop devices with the HTML5 application being hosted on hosting sites such as itch.io and Netlify.
But it should also work elsewhere.
LOADING AUDIOGROUPS
Our final step is setting up our audiogroups so that they are effectively loaded on our webpage.
Inside the Tools > Audiogroups let's define our custom audiogroup by clicking on Add New and inserting our audio resources by clicking on the Add Resource button.
In this case I called my custom audiogroup "myAudioGroup" but you can name it the way you want.
Then we create an object (I called it oAudiogroupLoader) and we place it in a specific room that will be used to manage all the audio loading.
Basically we'll use a function called audiogroup_load() that will fire an Async Save / Load event.
Inside that event we'll check if the audiogroup is loaded, if so we'll go to the game room.
STEPS:
1. Create a new room and set it as the home room (the room that will be played first as the game starts).
2. Place the oAudiogroupLoader inside that room.
3: Inside the Create Event of the oAudiogroupLoader object let's put this code:
GML:
audio_group_load(myAudioGroup);
GML:
if (audio_group_is_loaded(myAudioGroup)) {
room_goto(rmGame);
}
Draw Event:
Code:
draw_set_halign(fa_center);
draw_set_valign(fa_middle);
draw_set_font(fntLoading);
draw_text(room_width/2, room_height/2, "Loading Resources...");
draw_set_halign(fa_left);
draw_set_valign(fa_top);
That's it guys!
That should definitely make your HTML5 game audio PLAYYYYYYYYY!!!
Let me know it if that works for you, too!
Last edited: