I am using Plyr audio player for my Rails app, along with Simulus.js.
I dynamically add audio source when the user clicks on different audio buttons. Then I launch the audio player with the .play() method.
However, the beginning of the track can't be heard. You can try it out on this URL, by taping the first audio player. If you put back the audio cursor to the beginning, then you can hear the very beginning of the track.
Here is my HTML:
<audio class="player" controls data-dicteeModule-target="player">
<source class="player-source" src="<%= dictee_modules.first.audio_url %>" type="audio/mp3" />
</audio>
Here is how I initialize the player:
initialize() {
const players = document.getElementsByClassName('player');
var player = [];
Array.from(players).forEach(function (ele, i) {
player[i] = new Plyr(ele, {
controls: ['progress']
});
});
}
Here is my Stimulus onclick action:
var player = this.playerTarget;
var source = audio.getAttribute("data-audio-source");
var audioSource = player.getElementsByClassName("player-source")[0];
audioSource.src = source;
player.load();
player.addEventListener('canplay', (event) => {
player.play();
});
Any idea why the very beginning of the track is not heard?
Thanks.
This happens to me too on various websites that need to use audio after no audio was used for a while, even on YouTube. I'm using Chrome 104.0.5112.81 on Windows 10.
It's likely a driver issue you can't do much about (assuming YouTube would fix it if they could). It looks like Windows or Chrome ends up dimming the sound way too quickly, and takes too long turning it back on.
Unfortunately I couldn't find anything on Google yet. It seems hard to make Google understand this query, it only returned results about audio preventing PC sleep mode (or other unrelated common issues), no matter how I phrased it. Could also indicate it's just a very obscure issue with one or a few particular drivers.
Related
I am currently making a simple music app with the Ionic framework as practice. This is my first time working with Ionic and first time working with AngularJS. Right now i want to make sure that when a song from a certain playlist is finished, the next one starts. However, the onended HTMLproperty doesn't seem to do anything.
First Try
menu.html
<audio ng-src="{{ audioSrc }}" controls class="player" id="trackPlayer" autoplay="true" onended="nextTrack()">
<source type="audio/mpeg">
Your browser does not support the audio element.
</audio>
controller.js
//check if audio is finished
$scope.nextTrack = function () {
//find the right playlist and right current song id
alert("ended");
console.log($rootScope.nowPlaying);
//set new audiosrc for audioplayer
}
I'm also trying to target the audioplayer directly by javascript, but this doesn't work either.
Second try
controller.js
document.getElementById('trackPlayer').addEventListener('onended', $scope.nextTrack());
Putting an alert('ended!') in onended in my audio tag works but anything else does not give a response when my audio is done playing.
I have looked all over but did not find a solution or an explenation yet.
Anybody knows what I am doing wrong?
Thanks in advance.
I was wondering if someone has had a similar problem:
I have defined fallback mounts in Icecast2 so that one major stream plays at all times. If another fallback mount becomes active, the latter becomes the active.
I have tested the streams (mp3 format), with ffplay and the transition happens with no problem. The problem exists when I use an html5 audio tag to listen to the audio: transition does not happen automatically and I have to reload the browser and click play in order to listen to the stream. That is, using the browser, when the fallback stream gets enabled, the sound stops and I have to reload the browser and click play in order to listen[to the other stream]. The same problems occurs in all major browsers.
Here's an excerpt from my icecast.xml:
<mount>
<public>0</public>
<mount-name>/stream</mount-name>
<hidden>0</hidden>
</mount>
<mount>
<public>0</public>
<mount-name>/stream1</mount-name>
<fallback-mount>/stream</fallback-mount>
<fallback-override>1</fallback-override>
<username>stream1</username>
<password>pass</password>
<hidden>0</hidden>
</mount>
This is what ffplay shows while connecting and disconnecting from the secondary source:
The html5 code that plays the audio is as follows:
<audio controls>
<source src="http://127.0.0.1:3333/stream1" type="audio/mpeg">
</audio>
I got this finally working by going as follows:
First I noticed that when I switched from one mount point to another by enabling the source, the audio stopped playing. I set up a timer to fire every 1 second in order to check audio.currentTime and compare to an previous value. Then when the result is true, I reset the audio source to the same stream. It's kind of a hack but it seems to solve the trick.
html code:
<audio id="audio" controls>
<source src="http://127.0.0.1:3333/stream1" type="audio/mp3">
</audio>
javascript code:
var audio = document.getElementById('audio');
var myVar = setInterval(myTimer, 1000);
var oldTime = "";
function myTimer() {
if ((audio.paused != true && (audio.currentTime - oldTime) == 0 )) {
audio.src="";
audio.src="http://127.0.0.1:3333/stream1";
audio.play();
}
oldTime = audio.currentTime;
};
I have been trying to figure out this for a week.
I have two completely different video tags with their respective audio. I also have one audio tag. At first, both muted attribute is set for both video tags. When I want to get video1 audio, I would like to get it audio source and assign it to the audio tag. Also do the same for video2.
Is this possible with Javascript? I have tried Web audio API but I'm lost. Please help.
I am not sure I get what you want.
To copy the video's audio stream to an audio element, you could simply set the src of the <audio> element to the video's src :
<audio src="http://media.w3.org/2010/05/sintel/trailer.mp4" controls autoplay></audio>
Then you could try to sync it with your video tag's currentTime, or sync the video's currentTime with the <audio>'s one and unmute the video, while the audio would be muted, but I'm not sure you'll get awesome results. Also, it won't be a surprise if some browsers will load the video twice in the same time.
Now, what can you do with the WebAudioAPI :
It would be really hard to make your audio streams into the audio tags, live and in a cross-browser way.
If you don't need this however, it's pretty easy to create some MediaSource from video elements thanks to the createMediaElementSource() method.
Once these MediaSource objects are created, your original media will be disconnected from the normal output. You need to keep their muted attribute unset or set to false in order to hear it as a MediaSource object.
Here is a simple example that will allow you to mute/unmute a video source, from the WebAudioAPI only :
var vid = document.getElementById('vid');
var audioCtx = new AudioContext();
var gainNode = audioCtx.createGain();
var v1_src = audioCtx.createMediaElementSource(vid);
gainNode.connect(audioCtx.destination);
btn_1.onclick = function() {
var playing = this.textContent.indexOf('listen') < 0;
if (playing) {
v1_src.disconnect();
this.textContent = this.textContent.replace('mute', 'listen');
} else {
v1_src.connect(gainNode);
this.textContent = this.textContent.replace('listen', 'mute');
}
}
video { height: 120px;}
<button id="btn_1">listen</button><br>
<video id="vid" crossOrigin='anonymous' src="http://vjs.zencdn.net/v/oceans.mp4" loop autoplay></video>
Note that the media passed to this method must come from a safe domain request (see CORS).
I ran into some issues regarding my small-web-game project:
I have some sound files, given in HTML like this:
<audio id="shotSound" preload="auto">
<source src="../sound/shot.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
the preload="auto" should load the content immediately on page init right?
Now I'm using javascript to trigger the sound when I need to (key press):
var audio = document.getElementById("shotSound");
audio.play();
This works, but if I try to shot continuously or just faster(one shot after another) it won't work for shots after the first one. So, what happens if I hold the "shot" button: the sound is heard like it would be on repeat - which is obviously wrong.
Any ideas/suggestions are very welcome!
If I was unclear, please do let me know.
Thank you
Don't put the audio-tag into the HTML document. Preload the sound-effect in Javascript using
shotSound = new Audio();
shotSound.src = "../sound/shot.mp3";
shotSound.load();
Keep the shotSound variable in scope, so it doesn't get garbage-collected. Then, when you need to play a sound, create a new Audio object:
new Audio("../sound/shot.mp3").play();
It will play immediately because the sound-file will already be cached. And because it's a new audio-object, it won't interrupt other instances of the same effect playing in parallel.
I am trying to figure out how to continuously play random audio sound bites, one after another without having them overlap on an HTML page using jquery. I have code that plays random sound bites on a timer, but sometimes they overlap and sometimes there is a pause in between the sounds. I had looked into ended and other EventListeners but I really have no idea what I am doing. Here is a portion my code:
<html>
<audio id="audio1">
<source src="cnn.mp3"></source>
</audio>
<audio id="audio2">
<source src="sonycrackle.mp3"></source>
</audio>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('audio').each(function(){
this.volume = 0.6;
});
var tid = setInterval(playIt, 2000);
});
function playIt() {
var n = Math.ceil(Math.random() * 2);
$("#audio"+n).trigger('play');
};
Is there a way to just continuously play these sounds bites one after another right after the previous sound plays? FWIW I have many sound bites but I am just showing two above for reference.
So I dabbled a bit, here's a full pure JavaScript solution.
Should be cross-browser, haven't tested (/lazy). Do tell me if you find bugs though
var collection=[];// final collection of sounds to play
var loadedIndex=0;// horrible way of forcing a load of audio sounds
// remap audios to a buffered collection
function init(audios) {
for(var i=0;i<audios.length;i++) {
var audio = new Audio(audios[i]);
collection.push(audio);
buffer(audio);
}
}
// did I mention it's a horrible way to buffer?
function buffer(audio) {
if(audio.readyState==4)return loaded();
setTimeout(function(){buffer(audio)},100);
}
// check if we're leady to dj this
function loaded() {
loadedIndex++;
if(collection.length==loadedIndex)playLooped();
}
// play and loop after finished
function playLooped() {
var audio=Math.floor(Math.random() * (collection.length));
audio=collection[audio];
audio.play();
setTimeout(playLooped,audio.duration*1000);
}
// the songs to be played!
init([
'http://static1.grsites.com/archive/sounds/background/background005.mp3',
'http://static1.grsites.com/archive/sounds/background/background006.mp3',
'http://static1.grsites.com/archive/sounds/background/background007.mp3'
]);
Some quick suggestions is add the attribute preload="auto" to the audio element and change the script to be $(window).onload instead of document ready. Document ready fires when html is in place but not necessarily when audio and other assets (like images) have loaded.
You could also look into using the AudioBuffer Interface in the new Web Audio API, it's described as "this interface represents a memory-resident audio asset (for one-shot sounds and other short audio clips)." which sounds like what you need. I believe part of the issues you're having (random pauses/delays/sound glitches with the audio element) are one of the reasons why it's being developed.
Read more here:
https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioBuffer
Unfortunately it's only Chrome and lastest Safari supported with Firefox support supposedly in the next 6(ish) months and no word yet on IE support.