Audio player on mobile - javascript

I'm a total beginner and I try to use this to make an audio player
<audio id="music" controls>
<source src="sample.mp3" type="audio/mp3">
</audio>
but on mobile websites only a play button is showed (I can't insert a picture but on desktop we will see a normal player which consists of slider).
So how can I make the player appear on mobile just like its appearance on desktop?

It won't work. In plain HTML Simulated user interactions doesn't work in mobile.
Add a little javascript
window.addEventListener('load', function () {
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var source = audioCtx.createBufferSource();
var xhr = new XMLHttpRequest();
xhr.open('GET', 'audio-autoplay.wav');
xhr.responseType = 'arraybuffer';
xhr.addEventListener('load', function (r) {
audioCtx.decodeAudioData(
xhr.response,
function (buffer) {
source.buffer = buffer;
source.connect(audioCtx.destination);
source.loop = false;
});
source.start(0);
});
xhr.send();
});

Related

How to know if HLS video streaming it is started?

If I load the player before I have started live streaming and then start streaming after sometime it doesn't play the video, how i manage this issue?
There is my code i call for run html5 video with hls
playVideo(videoLink:string){
console.log("video link", videoLink);
const video = document.getElementsByTagName('video')[0];
if (Hls.isSupported()) {
/*var hls = new Hls({
debug: true,
});*/
var hls = new Hls();
hls.loadSource(videoLink);
hls.attachMedia(video);
hls.on(Hls.Events.MEDIA_ATTACHED, function () {
video.play();
});
}
// hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.
// When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element through the `src` property.
// This is using the built-in support of the plain video element, without using hls.js.
else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = videoLink;
video.addEventListener('canplay', function () {
video.play();
});
}
}
<div class="container-video" *ngIf="videoFinish == false; else videoStopped">
<video id="video"
width="700"
height="400"
preload="auto" controls>
</video>
</div>

Javascript to stop playing sound when another starts

So, I'm a complete amateur when it comes to coding, but I still like to fiddle around with it.
I'm currently working on a html/jS/PHP based soundboard and I can't figure out how to stop sound from playing when pressing a button to play another one.
<script type="text/javascript" charset="utf-8">
$(function() {
$("audio").removeAttr("controls").each(function(i, audioElement) {
var audio = $(this);
var that = this; //closure to keep reference to current audio tag
$("#doc").append($('<button>'+audio.attr("title")+'</button>').click(function() {
that.play();
}));
});
});
</script>
I hope someone understands that. Thanks in advance.
There is also a PHP code to fetch the audio file automatically from the folder to the front end, probably unnecessary info for this problem.
This is not very difficult to do if you use HTML5 which introduced the HTMLAudioElement.
Here is the minimal code for what you are trying to do:
// Let's create a soundboard module ("sb")
var sb = {
song: null,
init: function () {
sb.song = new Audio();
sb.listeners();
},
listeners: function () {
$("button").click(sb.play);
},
play: function (e) {
sb.song.src = e.target.value;
sb.song.play();
}
};
$(document).ready(sb.init);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Audio</title>
</head>
<body>
<button value="https://www.gnu.org/music/FreeSWSong.ogg">Song #1</button>
<button value="https://www.gnu.org/music/free-software-song-herzog.ogg">Song #2</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</body>
</html>
You may also consider libraries like howler.js to help you in the development process.
What you could do, is before start playing a new audio pause all available audio on the page. Something like this.
var audioOne = document.querySelector('#audio-1');
var audioTwo = document.querySelector('#audio-2');
var allAudios = document.querySelectorAll('audio');
function stopAllAudio(){
allAudios.forEach(function(audio){
audio.pause();
});
}
document.querySelector('#play-1').addEventListener('click', function(){
stopAllAudio();
audioOne.play();
})
document.querySelector('#play-2').addEventListener('click', function(){
stopAllAudio();
audioTwo.play();
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<audio id="audio-1"
src="http://developer.mozilla.org/#api/deki/files/2926/=AudioTest_(1).ogg">
</audio>
<audio id="audio-2"
src="http://www.w3schools.com/html/horse.mp3">
</audio>
<button id="play-1">
play audio 1
</button>
<button id="play-2">
play audio 2
</button>
</body>
</html>
Instead of adding audio using <audio> tag you could use HTMLAudioElement.
You can stop and reset an audio element by pausing it and setting its current time to 0. You would need to do this whenever a button is clicked. Example:
// Available sounds:
const sounds = {
"Bottle": "http://freewavesamples.com/files/Bottle.wav",
"Bamboo": "http://freewavesamples.com/files/Bamboo.wav"
}
// Load audio elements:
let audios = {};
for (let [title, url] of Object.entries(sounds)) {
audios[title] = new Audio(url);
}
// Create board buttons:
let board = document.getElementById("board");
for (let title of Object.keys(audios)) {
let button = document.createElement("button");
button.textContent = title;
button.dataset["audio"] = title;
board.appendChild(button);
}
// Handle board button clicks:
board.addEventListener("click", function(event) {
let audio = audios[event.target.dataset["audio"]];
if (audio) {
// Pause and reset all audio elements:
for (let audio of Object.values(audios)) {
audio.pause();
audio.currentTime = 0;
}
// Play this audio element:
audio.play();
}
});
<div id="board"></div>
In case you want to leverage the full power of the Web Audio API, you would probably start building your soundboard similar to this:
// Load buffer from 'url' calling 'cb' on complete:
function loadBuffer(url, cb) {
var request = new XMLHttpRequest();
request.open('GET', url);
request.responseType = 'arraybuffer';
request.onload = () => context.decodeAudioData(request.response, cb);
request.send();
}
// Available sounds:
const sounds = {
"Bottle": "url/to/bottle.wav",
"Bamboo": "url/to/bamboo.wav"
};
let audioCtx = new (AudioContext || webkitAudioContext)(),
board = document.getElementById("soundboard"),
buffers = {},
source;
// Load buffers:
for (let [title, url] of Object.entries(sounds)) {
loadBuffer(url, buffer => buffers[title] = buffer);
}
// Create board buttons:
for (let title of Object.keys(sounds)) {
let button = document.createElement("button");
button.textContent = title;
button.dataset["buffer"] = title;
board.appendChild(button);
}
// Handle board button clicks:
board.addEventListener("click", function(event) {
let buffer = buffers[event.target.dataset["buffer"]];
if (buffer) {
if (source) source.stop();
source = audioCtx.createBufferSource();
source.buffer = buffer;
source.connect(audioCtx.destination);
source.start();
}
});
<div id="soundboard"></div>
Please note that the sound URLs given above must either be on the same domain or available under the same origin policy (see CORS headers).
Below code may help others:
var audioMap = new Map();
var rappers = document.querySelectorAll('.rapper');
rappers.forEach(function(rapper){
audioMap.set(rapper, new Audio());
rapper.addEventListener('click', function(){
var audio = new Audio($(this).data('audio'));
audio.play();
audioMap.set(this, audio);
var current = audioMap.get(this);
// console.log('get', current);
audioMap.forEach(function(audio){
if( audio != current ){
audio.pause();
audio.currentTime = 0;
}
});
});
});
For the ones that don't use the audioTag in HTML5 and want to use only vanilla js this may help ya
var songplaying = null; //This is where we will store the current playing song
function playsong(song_name){
//settings
var playing = null;
if(songplaying==null){ //If a song isn't stored that means that it's not playing and vice versa
playing = false;
}else{
playing = true;
}
var dir = "./songs/"+song_name+".mp3"; //Here we get the directory of the song
var song = new Audio(dir); //Making a new audio element
if(!playing){ //This runs when no song is playing
song.play();
songplaying=song; //We save the current playing song
}else{ //This runs when another song is already playing
var song_alredyplaying = songplaying; //We get the audio element (song)
song_alredyplaying.pause(); //Pause the song
song.play(); //Then we play the new song
songplaying=song; //Save the current playing song
}
}
//Example
var playbtn = document.querySelector(".play");
playbtn.addEventListener('click', function(){
playsong("the song name");
};

Web audio API sound works on desktop and Android, but doesn't on iPhone

I've read a lot of topics and questions on this matter, but I can't find a solution. I can play sound on every Android browser, on every desktop browser, but not on Safari on iPhone 5c.
I'm trying to do it with Web Audio API (I'm definitly not an expert), here's my code:
window.addEventListener ('load', loadSound);
canvas.addEventListener ('touchend', loadSound);
canvas.addEventListener ('mouseup', loadSound);
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = new window.AudioContext();
var playSoundBuffer;
var source;
function loadSound() {
setTimeout(function() {
var request = new XMLHttpRequest();
var audioURL = "media/sound/WW_start.wav";
request.open("GET", audioURL, true);
request.responseType = "arraybuffer";
request.onload = function() {
audioContext.decodeAudioData(request.response, function(buffer) {
playSoundBuffer = buffer;
playSound();
}, function(error) {
console.error("Error in sound", error);
});
request.send();
}
}, 50);
}
function playSound() {
source = audioContext.createBufferSource();
source.buffer = playSoundBuffer;
source.connect(audioContext.destination);
source.start(0);
}
I also tried with source.noteOn(), source.noteOn(0), webkitAudioContext...
Howler is the solution:
<script src="lib/howler.js-master/howler.js-master/dist/howler.js"></script>
...
var sound = new Howl({
src: ['file.wav', 'file.mp3', 'file.ogg'],
volume: 1,
buffer: false
});
window.addEventListener('mousedown', function() {
sound.play();
}, false);

JavaScript + HTML5 Audio Player - Stop Buffering, EventHandler Issues

I've written some javascript so that the player will stop buffering once its paused so it will stop buffering. The code basically destroys the player, creates a new one, every time either play or pause is pressed. My only problem is it seems that it only listens for the play or pause event once. If I do them again, the code no longer runs. Can someone PLEASE take a look at this and let me know what I did wrong? Before you ask, the reason I'm recreating the player is because I hear this is necessary to do for ios to actually stop buffering.. Is this true? If there is a better way please let me know, as any help would be appreciated.
Thanks! (Code Below)
<audio id="myaudio" controls>
<source id="sourceMp3" src="" autoplay type="audio/mp3" preload="none"/>
Your browser does not support the audio element.
</audio>
<script type="text/javascript">
var sourceMp3=document.getElementById('myaudio');
sourceMp3.src="url of mp3 stream";
function playfunc(){
var audio = document.getElementById('myaudio');
//audio.pause(0);
audio.src = "http://";
audio.load();
audio.remove();
var x = document.createElement("AUDIO");
x.setAttribute("id","myaudio");
x.setAttribute("controls", "controls");
x.setAttribute("src","http://");
x.load();
document.body.appendChild(x);
var audio = document.getElementById('myaudio');
audio.src = "http://";
audio.load();
audio.src = "url of mp3 stream";
audio.load();
audio.play();
console.log('play pressed')
}
function pausefunc(){
//var tmp = sourceMp3.src;
var audio = document.getElementById('myaudio');
audio.pause(0);
audio.src = "http://";
audio.load();
audio.remove();
var x = document.createElement("AUDIO");
x.setAttribute("id","myaudio");
x.setAttribute("controls", "controls");
x.setAttribute("src","http://");
x.load();
document.body.appendChild(x);
var audio = document.getElementById('myaudio');
audio.src = "http://";
audio.load();
audio.src = "url of mp3 stream";
audio.load();
audio.pause();
console.log('pause pressed');
}
document.getElementById('myaudio').addEventListener('pause', pausefunc, false);
document.getElementById('myaudio').addEventListener('play', playfunc, false);
</script>
Comment out your code and just log the click. Something is triggering an exception killing the event. You'll see it the event fires reliably without your code.

Getting rid of lag time when playing sound with jQuery

I am trying to play sounds with a .keydown() event in jQuery. I would like the sounds to play quickly, but there seems to be a lag time when I perform the keydown event faster than about 3 times per second.
Here is a jsFiddle of my sample code: http://jsfiddle.net/pfrater/FRudg/3/
I am using the audio html tags for the sound and playing:
<audio controls id="sound" preload="auto">
<source src="http://www.wavlist.com/soundfx/011/duck-baby.wav" type="audio/wav"/>
</audio>
<audio controls id="sound2" preload="auto">
<source src="http://rezound.sourceforge.net/examples/chirp.wav" type="audio/wav"/>
</audio>
<audio controls id="sound3" preload="auto">
<source src="http://www.all-birds.com/Sound/downychirp.wav" type="audio/wav"/>
</audio>
and here's my jQuery:
$(document).ready( function() {
var playing;
$(document).bind("keydown", function(key) {
playing = undefined;
switch(parseInt(key.which, 10)) {
case 65:
playing = $("#sound").get(0);
break;
case 83:
playing = $("#sound2").get(0);
break;
case 68:
playing = $("#sound3").get(0);
break;
};
if (playing) {
playing.play();
}
}).on("keyup", function() {
if(playing){
playing.pause();
playing.currentTime=50;
playing = undefined;
}
});
});
Does anyone know of a way to get rid of this lag? Also, the actual files that I'll be playing are mpegs. The ones above are just an example.
Thanks for any help,
Paul
You won't be able to do this with the audio element. This is because the cost setting up and filling the buffers will take too much time.
The good news though is that you can do it using the Web Audio API instead.
I made you an example based on this code from HTML5 rocks (which you should check out for more details) and your original fiddle.
Currently this API is supported in Chrome, Firefox, Safari and Opera will be able to use this:
Fiddle demo
window.AudioContext = window.AudioContext || window.webkitAudioContext;
/// custom buffer loader
/// see http://www.html5rocks.com/en/tutorials/webaudio/intro/
function BufferLoader(context, urlList, callback) {
this.context = context;
this.urlList = urlList;
this.onload = callback;
this.bufferList = new Array();
this.loadCount = 0;
}
BufferLoader.prototype.loadBuffer = function (url, index) {
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";
var loader = this;
request.onload = function () {
// Asynchronously decode the audio file data in request.response
loader.context.decodeAudioData(
request.response,
function (buffer) {
if (!buffer) {
alert('error decoding file data: ' + url);
return;
}
loader.bufferList[index] = buffer;
if (++loader.loadCount == loader.urlList.length)
loader.onload(loader.bufferList);
},
function (error) {
console.error('decodeAudioData error', error);
});
}
request.onerror = function (e) {
alert('BufferLoader: XHR error');
}
request.send();
}
BufferLoader.prototype.load = function () {
for (var i = 0; i < this.urlList.length; ++i)
this.loadBuffer(this.urlList[i], i);
}
The main code:
/// setup audio context and start loading samples
var actx = new AudioContext(),
blst,
bLoader = new BufferLoader(
actx, [
'duck-baby.wav', 'chirp.wav', 'downychirp.wav'],
done),
isReady = false;
/// start loading the samples
bLoader.load();
function done(bl) {
blst = bl; /// buffer list
isReady = true; /// enable keys
$('#status').html('Ready!'); /// update statusw
}
/// this sets up chain so we can play audio
function play(i) {
var src = actx.createBufferSource(); /// prepare sample
src.buffer = blst[i]; /// set buffer from loader
src.connect(actx.destination); /// connect to speakers
src.start(0); /// play sample now
}
/// check keys
$(window).bind("keydown", function (key) {
if (!isReady) return;
switch (parseInt(key.which, 10)) {
case 65:
play(0);
return;
case 83:
play(1);
return;
case 68:
play(2);
return;
}
})
NOTE: When using external samples you must make sure they can be used cross-origin or else loading will fail (I used my DropBox to enable the samples to be loaded with fiddle).

Categories

Resources