Web Audio API - Can't get simple audio to play - javascript

I'm trying to learn the Web Audio API from the MDN tutorial but even the most basic example — no modular synthesis, just playing a simple mp3 file — doesn't seem to work on my end.
I can see the dataset value being switched in the console, the play/pause on the controls change state, and in Firefox and Safari (but not in Chrome) the track locator even advances and the "playing" icon displayed on the browser tab.
(I've added the controls attribute to the audio tag just to have a progress indicator visible).
I can also download the file from the DOM controls and play it using the OS, and I've tried it with three different MP3 files. The computer's speakers are obviously working.
BTW, creating audio with oscillators and the AudioContext object works fine.
I'm out of ideas.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<audio controls src="song.mp3"></audio>
<button data-playing="false" role="switch" aria-checked="false">
<span>Play/Pause</span>
</button>
<script src="audio.js"></script>
</body>
</html>
JS
'use-strict'
const aCtx = new AudioContext();
const el = document.querySelector('audio');
const track = aCtx.createMediaElementSource(el);
const button = document.querySelector('button');
button.addEventListener('click', function() {
console.log(this);
if (aCtx.state === 'suspended') {
aCtx.resume();
}
if (this.dataset.playing === 'false') {
el.play();
this.dataset.playing = 'true';
} else {
el.pause();
this.dataset.playing = 'false';
}
}, false);

Related

Twilio voice SDK javascript not working in mobile browser: AcquisitionFailedError (31402)

I have a very simple HTML page that connects the page to my Twilio backend:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/#twilio/voice-sdk#2.0.1/dist/twilio.min.js"></script>
<script>
connection = null;
call = async () => {
const response = await fetch(
"https://my.token.endpoint/token"
);
const data = await response.json();
const device = new Twilio.Device(data.token);
connection = await device.connect();
connection.on(
"error",
(err) =>
(document.getElementById("error-display").innerHTML = err.message)
);
};
stop = () => {
connection?.disconnect();
connection = null;
};
</script>
</head>
<body>
<button onclick="call()">call</button>
<button onclick="stop()">stop</button>
<p id="error-display"></p>
</body>
</html>
When I open the HTML page from my Windows 10 machine using Chrome 102.0.5005.115, clicking the call button successfully connects to my Twilio backend.
However when I open the HTML page from my Android 12 mobile device using Chrome 102.0.5005.125, clicking the call button triggered the following error:
AcquisitionFailedError (31402): The browser and end-user allowed permissions, however getting the media failed. Usually this is due to bad constraints, but can sometimes fail due to browser, OS or hardware issues.
I was getting this issue beforehand when trying to register the device before setting the current devices. However, since you're only seeing this on mobile, my guess is it's a permissions issue preventing the audio devices to be set. On your phone, can you try removing all permissions for your browser? Then in the code, print out the devices available input and output devices by console logging these:
device.audio.availableInputDevices
device.audio.availableOutputDevices
After refreshing the page, your phone should prompt you to allow audio permissions. If not, may need to take a gander through your settings.

How to avoid chrome autoplay policy on JS code?

I'm building a game to help kids to learn alphabets, the game is simple it will pronounce the letter and the user should choose the right letter between 3 different choices
the problem is that I can't autoplay the letter's audio file because of chrome autoplay policy which blocks autoplayed audio/video to avoid adds
one of the ways I found on google is inserting an audio/video tag on the HTML with fixed src, but that didn't work for me because audio's path would change with each new round
the other way is to set chrome flag autoplay to enable which affects my browser only but not the other users
is there a way on JS to avoid chrome's autoplay polices and make the audio file play automatically or I have to inject the audio's path into the audio tag with each new round?
<html lang='ar' dir="rtl">
<head>
<meta charset='UTF-8'>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<link rel='stylesheet' href='choose the right styles/style.css'>
<link rel='stylesheet' href='choose the right styles/queries.css'>
<link href="https://fonts.googleapis.com/css2?family=Amiri:wght#400;700&display=swap" rel="stylesheet">
<title></title>
</head>
<body>
<nav class="choose-the-right">
<div class="score-container">
<span class="score score-line"> score: <span class="score score-value"></span></span>
</div>
</nav>
<main class="container">
<div class="items-menu-div container">
<div class="bird-image">
<img id="bird" src="../resources/images/undraw_happy_music_g6wc.svg" alt="a bird wearing a headphone hearing alphabets">
</div>
<ul class="items-menu">
<li class="alpha-item">A</a></li>
<li class="alpha-item">B</a></li>
<li class="alpha-item">C</a></li>
</ul>
</div>
</main>
<script src="choose the right scripts/choose-game.js"></script>
</body>
</html>
window.addEventListener("load", init())
// DOM VARIABLES
const letterChoices = document.querySelectorAll(".alpha-item");
const bird = document.querySelector("#bird");
const path = document.querySelector("#src-path");
// PRIMITIVES VARIABLES
// const alphabets = ["أ","ب","ت","ث","ج","ح","خ","د","ذ","ر","ز","س","ش","ص",
// "ض","ط","ظ","ع","غ","ف","ق","ك","ل","م","ن","ه","و","ي"];
const alphabets = ["A","B",'C','D','E','F','G','H','I','J','K','L','M',
'N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
function init(){
let randomNum = Math.floor(Math.random()*alphabets.length);
let audio = new Audio(`../../resources/AR-alphabets/${randomNum}.mp3`);
audio.play();
}
You just cant play sound in browser unless user has interacted with it. I would suggest to add a start button which user can click thus satisfying the chrome security condition and it will play sound.
Also you should set audio.autoplay property to true

Adjust this code so the video only plays once on the website

I am helping a friend make a website and am a novice with javascript so could do with a little help. I have researched on here and see that some similar questions have been asked before but would like to know exactly how to relate this back to my code. So far this code works well, when you load up the homepage, the video clip runs IF the window is wider than 600px, but the video clip doesn't run if the window is less than 600 pixels. Also the other javascript makes the video disappear once it's played. However the problem I have is if you go to another page on the site, and then back to the home page, the video plays again and again, but I want the video to play only once when the visitor arrives to the site. Could anyone advise how I would edit the code so that the video only runs once per visit? All relevant code is below:
<script type="text/javascript">
window.addEventListener('load', function() {
if (window.innerWidth >= 600) {
var vid = document.getElementById('video');
var wrap = document.getElementById('videowrapper');
wrap.classList.toggle('hide');
vid.play();
vid.addEventListener('ended',function(e) {
wrap.classList.toggle('hide');
});
}
})
</script>
<div id="videowrapper" class="hide">
<video id="video" controls>
<source src="clip.mp4" type="video/mp4">
Your browser does not support HTML5 video.
</video>
<div id="videoEnd" style="display:block">Chris Presents</div>
</div>
<script>
document.getElementById('video').addEventListener('ended',myHandler,false);
function myHandler(e) {
if(!e) { e = window.event; }
// What you want to do after the event
document.getElementById('video').style.display="none";
document.getElementById('videoEnd').style.display="none";
}
</script>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="oldhomestyle.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="soundmouseover.js"></script>
</head>
Not sure what is this code doing in your tag! (the divs)
Other than that, as mentioned, you could definitely use cookies for what you need.
You can set localStorage to store value representing if video has been played at ended event, read localStorage at load event of window
window.addEventListener('load', function() {
if (window.innerWidth >= 600 && localStorage.getItem("played") === null) {
var vid = document.getElementById('video');
var wrap = document.getElementById('videowrapper');
wrap.classList.toggle('hide');
vid.play();
vid.addEventListener('ended', function(e) {
wrap.classList.toggle('hide');
localStorage.setItem("played", true)
});
}
})

HTML5 audio element doen't work on mobile

I have a sample with HTML5 element. I need dynamically create audio element after ajax request and play it. But it doesn't work on mobile! Android 4.1 and IOS7. It works perfect on desktop!
It doesn't work after page load. But it works after press buttom and after press button play on control. Why?
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<script>
function play() {
var audio = document.createElement('audio');
audio.autoplay = true;
audio.controls = true;
audio.src='http://s3.amazonaws.com/audiojs/02-juicy-r.mp3';
document.body.appendChild(audio);
audio.play();
}
setTimeout(play, 1000);
</script>
</head>
<body>
<h1>test</h1>
<input type='button' value='Press Me' onclick='play()' />
</body>
</html>
I had the same experience where audio wouldn't play after an AJAX call. I guess it has to do with security settings on mobile. Mobile browsers behave differently. The same happens when trying to call up the keyboard on mobile. It is only possible after a keypress or a click event but not automatically on page load or after an Ajax call.
One solution that I used might be to trigger the sound outside of the Ajax call, in the event that triggered the Ajax call in the first place.

firefox not playing sound

hello i am abit new in client side programming and html,
i am trying to excute the following line in firefox and other browsers , the code should
play a sound, problem is that the code works and play the sound on IE and Chrome but not on firefox here is my code:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<title>Untitled 1</title>
<script type="text/javascript">
function playsound()
{
var sound= document.getElementById("check");
sound.play();
}
</script>
</head>
<body>
<audio id = "check" preload = "auto">
<source src = "check.mp3" type = "audio/mpeg"></audio>
<input type="button" onclick="playsound()" value="play">
Firefox doesn't support the MP3 format as audio source. If you add a second source file in OGG format, the script should work in Firefox too. See this Link for more info
The fact is that firefox and opera do not support mp3 files in html5 audio tag. You can check supported browser in w3schools. Its work around is that you need a fallback flash audio player.

Categories