regosen / gapless-5 Goto Github PK
View Code? Open in Web Editor NEWGapless JavaScript audio player using HTML5 and WebAudio
License: MIT License
Gapless JavaScript audio player using HTML5 and WebAudio
License: MIT License
It'd be useful if the library had a muted
property like the HTML5 Audio Element does, since setting the volume to 0 doesn't accommodate to this feature in its entirety. Being able to mute implies having the volume property untouched, but still having no sound coming out. This is especially reflected in most player UIs, where the user is able to toggle and untoggle the mute button, and the volume is still preserved when unmuted.
Judging from the style of the library, this would probably mean having getMuted
and setMuted
methods defined in the Gapless5
object
But I did! http://relisten.net/gapless
Thanks for an awesome proof-of-concept.
Describe the bug
The song starts first with the HTML5 Audio, and restarts a second time (no seamless transition) when the WebAudio API has finished decoding the file.
Steps to reproduce
I've created an HTML file with the following code
<script src="gapless5.js" language="JavaScript" type="text/javascript"></script>
<script>
var player = new Gapless5({logLevel: 1});
window.addEventListener('click', () => {
player.addTrack('audio/song.mp3');
player.play();
})
</script>
Gapless5 version
Version 1.3.6
Demo
You can check a demo of the problem I'm getting here: https://gapless5-test.surge.sh/
私は此のプロジェクトがめっちゃくっちゃすごい思いますね!
Describe the bug
A bug in the code does not use the startingTrack value when the player is initialized with an array of file URLs. It is honored when the player is initialized with an array of objects. This can be easily fixed by adding startingTrack = this.startingTrack || 0;
in the code below. I will submit a PR for this later.
// set up tracks into a FileList object
if ('tracks' in options) {
let items = [];
let startingTrack = 0;
if (Array.isArray(options.tracks)) {
if (typeof options.tracks[0] === 'string') {
items = options.tracks;
for (let i = 0; i < options.tracks.length; i++) {
items[i] = options.tracks[i];
}
------------------------------------------------
NO CODE FOR STARTING TRACK HERE!!!!!!!!!!!!
------------------------------------------------
} else if (typeof options.tracks[0] === 'object') {
// convert JSON items into array
for (let i = 0; i < options.tracks.length; i++) {
items[i] = options.tracks[i].file;
}
startingTrack = this.startingTrack || 0;
}
} else if (typeof options.tracks === 'string') {
items[0] = options.tracks;
}
for (let i = 0; i < items.length; i++) {
this.addTrack(items[i]);
}
this.playlist.setStartingTrack(startingTrack);
}
Greetings,
I was wondering if it's possible to return a boolean (or object with the full error) when adding a track was successful or not. I'm adding tracks with the addTrack()
function.
Kind regards,
Bernardo
I have begun using Gapless-5 with my web audio player. Before using Gapless-5, I used a single HTML5 audio element and used the Web Audio API to create a MediaSource object from it, so that I could implement a waveform visualization. Example/pseudocode:
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
var myAudio = document.querySelector('audio.player');
var source = audioCtx.createMediaElementSource(myAudio);
analyser = audioCtx.createAnalyser();
analyser.fftSize = 2048;
bufferLength = analyser.frequencyBinCount;
dataArray = new Uint8Array(bufferLength);
source.connect(analyser);
analyser.connect(audioCtx.destination);
drawWaveform();
Would it be possible for you to create and expose the AudioContext and MediaSource objects, so that they could be used for visualization purposes? I would also need a callback for when the MediaSource object was changed, given that your library switches between multiple HTML5 audio elements and/or Web Audio API buffers.
I believe that reasonably modern browsers (the ones that support HTML5 Audio) also support the standard APIs for the functionality that Gapless 5 needs from jQuery.
Would you consider accepting a pull request that replaces jQuery with native browser APIs?
Describe the bug
Calling playpause()
does not pause the player. In order to workaround this, I had to implement my own logic. Note that I have disabled Web Audio.
var playerPaused = true;
player.onplay = function () {
playerPaused = false;
}
player.onpause = function () {
playerPaused = true;
}
function audioPause() {
if (playerPaused) {
player.play();
} else {
player.pause();
}
}
Debug output
There was no console output when enabling debugging and calling playpause().
When I load tracks that are between about 10 and 15 minutes long, the player fails on these tracks. (These times are not exact. Problems start for tracks a little longer than 10 minutes, and tracks a bit longer than 15 seem to work.) This only happens on Safari on my Mac and on Safari on iOS. It also only happens for mp3 and m4a files -- wavs work fine.
It is easy to reproduce. For example, upload a 12-or-so minute track to the demonstration page here:
https://ccrma.stanford.edu/~regosen/gapless5
On Safari on a Mac, the time shown is truncated to 2 minutes.
I have one iPhone running iOS 15, and it is the same as on my Mac.
On another iPhone still running iOS 14, then the time shown is not truncated but the player stops playing after two minutes.
(Actually Brave browser, Firefox, and Chrome also show this same problem on iOS, but I think they are just using Safari's innards.)
This is with gapless 5 version 1.3.4.
Any ideas for fix or workaround would really be appreciated.
Describe the bug
I'm creating something which, as an alternative to an online server, I want to be able to run offline simply by downloading the site and opening the HTML file locally. If I run it in a server, Gapless5 has no issues. However, opening the file directly, it is unable to work unless you disable useWebAudio
. This sets me back to square one with Chrome's incredible incapability to loop audio gapless after a decade and a half.
Debug output
I created a minimal example to test this, which I've attached here: localsite.zip
Here is the console output from Firefox:
21:40:02.335 Loading track 0: trivia-timer.ogg [gapless5.js:764:11](file:///home/c/Projects/localsite/gapless5.js)
21:40:02.341 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at file:///home/c/Projects/localsite/trivia-timer.ogg. (Reason: CORS request not http). [Learn More]
21:40:02.350 Failed to load audio track [gapless5.js:160:9](file:///home/c/Projects/localsite/gapless5.js)
21:40:02.352 Stopping: trivia-timer.ogg [gapless5.js:217:9](file:///home/c/Projects/localsite/gapless5.js)
The [Learn More]
directs you to this page: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSRequestNotHttp
Potential solution
The problem has nothing to do with the Web Audio API itself, but rather, that XMLHttpRequest can't be used for local files. So if window.location.protocol === "file:"
, a different method must be used. I believe a solution may lie in MediaElementAudioSourceNode, which lets you control a pre-existing <audio>
element with the Web Audio API. One of the MDN guides on the API shows it being used here.
However, my current understanding of the API, and of Gapless5's internal workings, is insufficient to go further from here. Ironically, I jumped onto using Gapless5 specifically because the API was confusing and daunting and I don't have time to understand how it works. But at least for now, it works in Chrome when online, and I can tell offline users to install Firefox, like they should be doing anyway :P
The gapless library doesn't return any promise object.
It's impossible to know when the sound is actually playing.
It would be very useful if it could return any information.
Describe the bug
Hi folks, just plugged this library in on an ES6 React environment being served up with npm start
.
Data is being received and I've followed it all the way to line 433: player.context.decodeAudioData(data)
.
This always fails.
I took a look at the docs for audio contexts and it looks like this is expected with partial content.
I'll need to adapt something to load the entire file before passing it to your library - my goal is to loop audio without missing a beat as it's a looping game soundtrack.
Debug output
Instructions for setting log level didn't work.
Describe the bug
When calling stop()
, playback stops, but it does not reset the position to the start of the track. Calling playpause()
afterward resumes playback from the same position. In order to get the desired behavior, I have to call setPosition(0)
after calling stop()
.
Note: The player is configured to only use HTML 5 audio.
player = new Gapless5({ logLevel: LogLevel.Debug, useWebAudio: false, loop: true, loadLimit: 2, tracks: tracks, startingTrack: position });
Debug output
Setting starting track to 0
gapless5.js:619 Loadable indices: [0,1]
gapless5.js:631 Loading track 0: /play?path=%2Fmovie%20ost%2FAmerican%20Psycho%20(London%20Musical)%2F01%20Opening%20(Morning%20Routine).mp3&duration=212.950204&track_index=0
gapless5.js:631 Loading track 1: /play?path=%2Fmovie%20ost%2FAmerican%20Psycho%20(London%20Musical)%2F02%20Cards%20%5BExplicit%5D.mp3&duration=196.414694&track_index=0
gapless5.js:260 Loading /play?path=%2Fmovie%20ost%2FAmerican%20Psycho%20(London%20Musical)%2F01%20Opening%20(Morning%20Routine).mp3&duration=212.950204&track_index=0
gapless5.js:233 Playing HTML5 Audio: /play?path=%2Fmovie%20ost%2FAmerican%20Psycho%20(London%20Musical)%2F01%20Opening%20(Morning%20Routine).mp3&duration=212.950204&track_index=0
gapless5.js:185 onEnded() will be called in 212.95 sec
gapless5.js:158 Stopping: /play?path=%2Fmovie%20ost%2FAmerican%20Psycho%20(London%20Musical)%2F01%20Opening%20(Morning%20Routine).mp3&duration=212.950204&track_index=0
gapless5.js:233 Playing HTML5 Audio: /play?path=%2Fmovie%20ost%2FAmerican%20Psycho%20(London%20Musical)%2F01%20Opening%20(Morning%20Routine).mp3&duration=212.950204&track_index=0
gapless5.js:185 onEnded() will be called in 205.97 sec
I was wondering if we could consider adding npm or yarn compatible package.json
to allow people to use yarn or npm to manage the module.
This is more of a subjective issue than an actual bug. It appears the button functions mimic those of an old tape player, rather than those of virtually any digital audio player. In effect, this means that pause()
and stop()
do the exact same thing: pause playback without changing the position. When paused, next()
and previous()
do not automatically start playback. There also appears to be no way to repeat a single track after the player has been initialized.
I am not sure if the current behavior of these functions should be changed, as it might break existing clients of the library. It might be better to just add some more information to the README about the exact behavior.
For your reference, here are what the buttons in Foobar2000 do:
play -> starts playing the track from the beginning, even if it is already playing or paused
pause -> pauses the track is playing, resumes if paused
stop -> stops playback and resets the position to the beginning of the song
prev -> goes to the previous track in the playlist and starts playing from the beginning
next -> goes to the next track in the playlist and starts playing from the beginning
For your reference, this is how I mimiced the Foobar2000 behavior using Gapless-5:
const player = new Gapless5({ useWebAudio: false, loop: true, loadLimit: 2 });
var playerPaused = true;
var repeat = false;
// setup player callbacks
player.onplay = function () {
playerPaused = false;
}
player.onpause = function () {
playerPaused = true;
}
player.onstop = function () {
playerPaused = true;
}
player.onnext = function (from_track, to_track) {
if (repeat) {
player.gotoTrack(from_track);
player.cue();
}
}
function audioStop() {
player.stop();
player.setPosition(0);
}
function audioPlay() {
player.cue();
}
function audioPause() {
if (playerPaused) {
player.play();
} else {
player.pause();
}
}
function audioSeekBackwards(seconds) {
if (!playerPaused) {
var position = player.getPosition();
position -= 1000 * seconds;
player.setPosition(position);
}
}
function audioSeekForwards(seconds) {
if (!playerPaused) {
var position = player.getPosition();
position += 1000 * seconds;
player.setPosition(position);
}
}
function audioPrevious() {
player.prevtrack();
player.cue();
}
function audioNext() {
player.next();
player.cue();
}
function audioRepeat() {
if (repeat) {
repeat = false;
} else {
repeat = true;
}
}
Describe the bug
When the player uses HTML5 audio, the MediaSession API works properly in Chrome. This includes setting metadata, such as track title, artist, artwork etc. in the media controls, as well as setting the callbacks for each player event. However, when the libray switches to WebAudio, some of these callbacks stop working (such as pausing, for some reason), and eventually, the MediaSession controls disappear after some time of WebAudio playback (especially when a track is played from WebAudio from the start).
I did some research and stumbled upon this StackOverflow post, where a user needs to show MediaSession controls although there's no audio playing. The docs mention the following:
Note that: Notifications are only shown for media over five seconds in length. There is no notification for audio from the Web Audio API unless it is played back via an audio element. With the Media Session API, you can customize media notifications by providing metadata for the media your web app is playing. This API also allows you to handle media related events such as seeking or track changing which may come from notifications or media keys.
In the end, the author of the post allegedly managed to fix it by using an HTML5 <audio/>
element with an audio file that's completely silent and looping it.
Now, I'm not sure if this is a bug in the library that can be easily fixed, or if this was never considered in the first place. In any case, maybe that post could help you achieve it, or maybe you can think of another, more elegant solution. I'll be forever grateful if a solution can be found!
Hi there!
I had absolutely no idea until today about gapless problem / solutions and found this little gem 💎. Amazing work!
I have a small issue that I can't seem to fix
ReferenceError: gapless5Players is not defined at HTMLInputElement.onmousedown
This is my code (it's liquid)
<div id="gapless5-player-id" />
<script type="text/javascript">
window.onload = function() {
const player = new Gapless5({ guiId: 'gapless5-player-id' });
{% for file in folder.files %}
{% if file.content_type == 'audio/mpeg' %}
player.addTrack('{{ file.viewing_url }}');
{% endif %}
{% endfor %}
}
</script>
When clicking on any point in the bar to go to minute X, this is the error shown in console. I'm probably missing something stupid, thanks in advance for the help - tried to google and chatgpt, but no results. Is it related to the onload?
Second question. Are you aware of any custom pre-built CSS players to plug-and-play?
Third question. Is this library able to read ID3 tags? I had no idea they existed until today, apologies in advance if this a stupid question!
Not sure how, but happy to contribute! Thank you! 👏
Greetings,
I'm currently having trouble with connecting the gapless player with the media session API. It has a strange behavior.
What I also noticed is that as soon as the next part is played, the notification also disappears. (I coded a "buffering" system)
I've sent you my website to your Email, where you can test this behavior.
If you need any further information or access to the source code, I'll give it to you through Email.
Kind regards,
Bernardo
Describe the bug
There is an audible gap when transitioning between 2 tracks on firefox. The same gap isn't audible on latest chromium browsers. I used .flac files while encountering this bug.
Firefox version: Linux 104.0.2 64bit
Chromium browser version: Linux 104.0.5112.102 64bit (Brave version 1.42.97)
In my testing, I started the playback of track 1 and seeked near to the end of it. I then waited for the next track to start to hear the transition between the tracks. Here's my sample code I was using:
const player = new Gapless5({
tracks: [
// gives a .flac file as a response
`http://localhost:7777/musicfile?id=17179869343`,
`http://localhost:7777/musicfile?id=17179869344`,
],
loadLimit: 2,
volume: 0.3,
logLevel: LogLevel.Debug,
});
player.play();
// seek near the end of the first track so that I can hear the transition quicker
setTimeout(() => {
player.setPosition(120 * 1000);
}, 1000);
Debug output
Setting starting track to 0 [gapless5.js:441:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Loadable indices: [0,1] [gapless5.js:619:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Loading track 0: http://localhost:7777/musicfile?id=17179869343 [gapless5.js:631:14](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Loading track 1: http://localhost:7777/musicfile?id=17179869344 [gapless5.js:631:14](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Loading http://localhost:7777/musicfile?id=17179869343 [gapless5.js:260:10](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Playing HTML5 Audio: http://localhost:7777/musicfile?id=17179869343 [gapless5.js:233:14](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
onEnded() will be called in 128.29 sec [gapless5.js:185:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Switching from HTML5 to WebAudio: http://localhost:7777/musicfile?id=17179869343 [gapless5.js:128:10](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Playing WebAudio: http://localhost:7777/musicfile?id=17179869343 [gapless5.js:203:14](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
onEnded() will be called in 127.82 sec [gapless5.js:185:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Stopping: http://localhost:7777/musicfile?id=17179869343 [gapless5.js:158:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Playing WebAudio: http://localhost:7777/musicfile?id=17179869343 [gapless5.js:203:14](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
onEnded() will be called in 8.27 sec [gapless5.js:185:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
onEnded() will be called in 128.27 sec [gapless5.js:185:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Stopping: http://localhost:7777/musicfile?id=17179869343 [gapless5.js:158:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Setting track number to 1 [gapless5.js:463:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Loadable indices: [1,2] [gapless5.js:619:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Stopping: http://localhost:7777/musicfile?id=17179869343 [gapless5.js:158:8](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Unloaded track 0: http://localhost:7777/musicfile?id=17179869343 [gapless5.js:635:14](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
Playing WebAudio: http://localhost:7777/musicfile?id=17179869344 [gapless5.js:203:14](http://localhost:5173/node_modules/.pnpm/@[email protected]/node_modules/@regosen/gapless-5/gapless5.js)
onEnded() will be called in 201.27 sec
I noticed that one of the biggest callbacks that's missing in this API is the onTimeUpdate callback, similar to the one that the HTML5 Audio Element has.
Personally, I'd like to use it in order to update state variables used for displaying the player's current position in real time. For the mean time, is there any other alternative that could help me achieve this?
Thanks!
Whenever the play arrives to a limit where the current loaded file has not finished loading, it stops and doesn't resume. I tried tweaking with this:
if(!player.isPlaying()) player.play();
when the loading has finished, but it seems to repeat some tracks and even merge two playings
Describe the bug
When using the currentLength
method in the Gapless5
object, the value returned is 0 during the first seconds of playback. I assume this has something to do with the duration not being available while the full audio is not yet available?
Debug output
Here, I ran a test using the new ontimeupdate
feature, where the current position is printed followed by the return value of the currentLength()
call. The test implies calling the play
method, while HTML5 audio is being used (i.e. hit play quickly before the full audio is downloaded).
player.ontimeupdate = currentPosition =>
console.log("ontimeupdate", currentPosition, player.currentLength());
ontimeupdate 3650 0
ontimeupdate 3987 0
Loadable indices: [0,1,2]
Switching from HTML5 to WebAudio: <url>
Loadable indices: [0,1,2]
ontimeupdate 3987 404950.20408163266
Trying out the new ontimeupdate
callback feature, which is great. However, since it fires so quickly, it ends up leading to excessive amounts of re-renders in React when calling state setters from the callback. I was able to verify this by setting 3 different functions to the ontimeupdate
callback:
Function 2 is the only one that causes the entire UI to act very choppy and laggy, and the other ones do not cause any performance issues. Being able to set a custom value for the callback frequency would definitely help anyone who experiences poor performance from using the ontimeupdate
feature.
Thank you!
Hi there !
I'm doing some tests with your player. So far it's working well! :)
However, I noticed that the gapless won't work when my browser is displaying another tab.
I tested this on both Google Chrome and Firefox.
Is there a way to prevent this?
Thanks !
It worked a couple of weeks ago, did google plug it?
And to add to the pain even if you click the page the playback now has a gap.
Edit: "The AudioContext was not allowed to start. It must be resumed (or created) after a user gesture on the page."
This "do no evil" plan has gone too far, natural selection is not a bad thing.
Console log shows this:
TypeError: context.createGainNode is not a function. (In 'context.createGainNode()', 'context.createGainNode' is undefined)
in Gapless5.js, line 806
Have been trying out using this to play short (~:60 second) white noise clips and I'm hearing a slight click at the loop point, more noticable with .mp3, however still noticable even using .wav original. The only way I've resolved it was to switch over to doing a pure, no frills JS crossfade which negates all the other cool features of gapless-5, plus I can't do instancing. Is it possible to add a crossfade feature to gapless-5? Just on/off and var for # of seconds of crossfade
Here are some white noise clips to test with: https://viewescape.com/audio/
(please note these are for testing only by author and are not for private/public use)
If you wear over-the-ear headphones, you'll hear the slight click at the loop point. A crossfade resolves the issue, hence my suggested solution. The white noise tracks in that link are perfectly seamless right down to the start/end sample and I was using FFmpeg concat to create long videos using them, however looking for a web based player solution for a new site - I could live with a second or 2 crossfade. Gapless-5 is the closest solution yet ;D Thanks!
Is there a way to:
I've tried gapless-5 on windows using chrome and it works ... gapless :-).
However when I try the same on my iphone 4, after some loading time, the page abort with 'problems'.
I see memory usage of the google chrome when loading tracks increase to about 800Mb for a full CD, which is quite a lot. Also I see in my apache logs that music songs are loaded at about the same speed, the memory usage is increasing.
Is this a feature or a bug?
Hey, the gapless audio has been awesome!
I'm mostly looking for a way to change the position of the song while it is paused. I want to use gapless-5 in a rhythm game so that whenever the user pauses to a menu and then resumes, it would rewind to start back on the beat. I have the rewinding amount, just need to know how to set the time on the song.
Thanks for any advice on this!
Firefox supports perfect seamless looping, as shown here:
https://www.dropbox.com/s/buetaa1taw0ia2o/loop-firefox-example.7z?dl=1
(modified from https://bugzilla.mozilla.org/show_bug.cgi?id=654787 )
However, Gapless-5, contrary to its name, is not gapless on Firefox. The functionality not working is a bug.
Here are the logs I obtained by uncommenting some debug statements:
loading track 0: sounds/sine.wav
playing WebAudio
If I disable playAudioFile
->
if (buffer != null)
with && false
, then the second if statement falls through (because audio == null).
with a for loop iterating through an array of objects, I managed to stop all instances of a gapless player with the onplay callback.
mygapless.onplay=function () {stopAll(mygapless.id)};
It's janky but it works, would you consider an option state that would allow an instance to stop all others if it is played?
I just noticed the following issue that seems to be specific to Safari: both the demonstration page and the ZFP page are silent on Safari until I reload the pages.
I also noticed that if I play right away on the first load of the demo page, I hear audio and then it abruptly stops. I see nothing in JS console, but I suspect this is happening when it crossfades from HTML5 Audio to WebAudio.
This issue was present before my recent merge from wwoast/playlist-object: ac2348f
It would be nice if this was typescript-ready. Either by being rewritten in typescript or simply having a types.d file in the module.
Hi there,
On ios: player stops playing when navigating away from the browser and comes alive again when going back to the page.
There are other sites like soundcloud where the playing keeps playing in the background.
Is there a way to keep the audio alive when navigating away? Maybe a setting I have overlooked?
Thanks,
Moz
Hello! Gapless5 is awesome! Thank you so much for building this.
When I loop a WAV file, it indeed seems gapless.
However, mp3 files are often created with a little bit of silence at the end, due to the nature of the encoding.
Could you imagine implementing a feature to trim that last bit of silence, ensuring true gapless playback of music in MO3 format?
Describe the bug
Regardless of whether the audio player is initialized with tracks
and a startingTrack
or if tracks are added and a starting track is set dynamically, it appears that the first few tracks are always loaded (based on the loadLimit
. In my application, I use a single instance of the Gapless-5 audio player and then dynamically change playlists using a custom browser. As an example, if I use a loadLimit of 3, load a playlist, and then start playing track 10, tracks 1, 2, 3, 10, 11, and 12 will load. Here is some pseudo-code as an example.
Note: This is also occurs when initializing the audio player with tracks
and a startingTrack
in the constructor. The first tracks are always loaded, based on the loadLimit
.
const player = new Gapless5({ useWebAudio: false, loop: true, loadLimit: 3 });
// user clicks a button to load a playlist and start at song 10.
player.removeAllTracks();
for (track in playlist){
player.addTrack(track);
}
player.gotoTrack(9);
player.cue();
I have also tried calling player.gotoTrack()
before adding tracks to the player, but this results in a error. The only workaround is to create a new Gapless-5 audio player every time I load a new playlist.
Debug output
Setting starting track to -1 [gapless5.js:441:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loadable indices: [0,1] [gapless5.js:619:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loading track 0: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F01%20-%20Prologue_%20Beauty%20And%20The%20Beast%20(Soundtrack).mp3&duration=146.938776&track_index=0 [gapless5.js:631:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loadable indices: [0,1,2] [gapless5.js:619:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loading track 1: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F02%20-%20Belle.mp3&duration=309.185306&track_index=0 [gapless5.js:631:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loadable indices: [0,1,2] [gapless5.js:619:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loading track 2: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F03%20-%20Belle%20Reprise%20(Soundtrack).mp3&duration=64.966531&track_index=0 [gapless5.js:631:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loadable indices: [0,1,2] 13 [gapless5.js:619:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Setting track number to 9 [gapless5.js:463:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loadable indices: [8,9,10,11] [gapless5.js:619:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Stopping: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F01%20-%20Prologue_%20Beauty%20And%20The%20Beast%20(Soundtrack).mp3&duration=146.938776&track_index=0 [gapless5.js:158:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Unloaded track 0: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F01%20-%20Prologue_%20Beauty%20And%20The%20Beast%20(Soundtrack).mp3&duration=146.938776&track_index=0 [gapless5.js:635:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Stopping: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F02%20-%20Belle.mp3&duration=309.185306&track_index=0 [gapless5.js:158:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Unloaded track 1: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F02%20-%20Belle.mp3&duration=309.185306&track_index=0 [gapless5.js:635:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Stopping: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F03%20-%20Belle%20Reprise%20(Soundtrack).mp3&duration=64.966531&track_index=0 [gapless5.js:158:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Unloaded track 2: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F03%20-%20Belle%20Reprise%20(Soundtrack).mp3&duration=64.966531&track_index=0 [gapless5.js:635:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loading track 8: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F09%20-%20Beauty%20and%20the%20Beast%20(From%20_Beauty%20and%20the%20Beast__Soundtrack%20Version).mp3&duration=166.347755&track_index=0 [gapless5.js:631:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loading track 9: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F10%20-%20To%20The%20Fair.mp3&duration=117.942857&track_index=0 [gapless5.js:631:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loading track 10: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F11%20-%20West%20Wing.mp3&duration=265.038367&track_index=0 [gapless5.js:631:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loading track 11: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F12%20-%20The%20Beast%20Lets%20Belle%20Go.mp3&duration=142.027755&track_index=0 [gapless5.js:631:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Loading /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F10%20-%20To%20The%20Fair.mp3&duration=117.942857&track_index=0 [gapless5.js:260:11](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
Playing HTML5 Audio: /play?path=%2Fmovie%2FBeauty%20and%20the%20Beast%2F10%20-%20To%20The%20Fair.mp3&duration=117.942857&track_index=0 [gapless5.js:233:15](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
onEnded() will be called in 117.97 sec [gapless5.js:185:9](https://localhost:8443/node_modules/@regosen/gapless-5/gapless5.js)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.