museeks icon indicating copy to clipboard operation
museeks copied to clipboard

Gapless playback

Open martpie opened this issue 8 years ago • 18 comments

What

  • [ ] Reduce sound interuption between two songs

Currently, when a song is over, the src of the audio tag is changed, but the tag has to preload the file a bit. So there is a micro interruption of a few miliseconds.

  • [ ] Crossfading option between song ?

How

~Instead of having a single Audio object, need to have an array of 3: [previous, current, next]. Then when playing next or previous, it should be faster, cause tracks will already be loaded + Pop/Shift audio when needed.~ not working :[

martpie avatar Sep 11 '15 22:09 martpie

This could be done by using an array of Audio objects, less dirty than only two audio tags

martpie avatar Jul 06 '16 08:07 martpie

I might consider a switch to Web Audio API instead of the current Audio element implementation. Might be a first step to #114

martpie avatar Aug 02 '16 12:08 martpie

I wonder if it is enough to have 2 elements - current + next. We can start playing audio on next element, and when current track is over, we just swap pointers, to next becomes new current and we allocate a new next.

YurySolovyov avatar Aug 03 '16 19:08 YurySolovyov

The problem is the next sont can be the previous one. I've done some test, and there's still a microcut between the ended event and the next track play start. As mentioned, I think I'll switch to the Web Audio API with an AudioContext, but it's a huge work, and I don't know well this API.

martpie avatar Aug 03 '16 23:08 martpie

The problem is the next song can be the previous one.

I still don't quite get why this is a problem.

there's still a microcut between the ended event and the next track play start

As I understand, if we have say 1000ms overlap/crossfading duration, we should not worry about these conks of microcuts, because transition period is still much longer.

YurySolovyov avatar Aug 04 '16 08:08 YurySolovyov

I still don't quite get why this is a problem

You need to preload three songs: the current one, the next one, and the previous one. If they are preloaded, then the microcute should be smaller.

As I understand, if we have say 1000ms overlap/crossfading duration, we should not worry about these conks of microcuts, because transition period is still much longer.

Yes sure, but what if there is a 0ms crossfade (the user will be able to choose a value), there would still be one ;)

martpie avatar Aug 04 '16 09:08 martpie

https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/audioTracks

Trough an experimental flag though :/

martpie avatar Mar 03 '19 13:03 martpie

Could you not have an array var nowPlaying = ['previous','current','next'] of which you can nowPlaying.shift() the first element out, once the current song has finished playing. nowPlaying.push(nextTrack) the next song to play onto the end of the array.

This should always leave the previous track as nowPlaying[0], Current playing as nowPlaying[1] and next track nowPlaying[2].

probably won't work knowing me :D

DrEVILish avatar May 30 '19 09:05 DrEVILish

I tried it, the result is unfortunately the same, there's still a mini-gap :(

martpie avatar May 30 '19 10:05 martpie

I tried it, the result is unfortunately the same, there's still a mini-gap :(

I'd not realised the mini-gap before :( just played War of the Worlds and there it was...

DrEVILish avatar May 30 '19 13:05 DrEVILish

A gapless JavaScript/CSS audio player for HTML5

PROBLEM: There are 2 modern APIs for playing audio through the web, and both of them have problems:

  • HTML5 Audio: the last chunk of audio gets cut off, making gapless transitions impossible
  • WebAudio: can't play a file until it's fully loaded

SOLUTION: Use both!

  • If WebAudio hasn't fully loaded yet, it begins playback with HTML5 Audio, then seamlessly switches to WebAudio once loaded.
  • NOTE: Most mobile browsers don't fully support HTML5 Audio objects in js, so we're stuck with only WebAudio in that case.

http://github.com/regosen/Gapless-5 Might be able to replace the whole player engine with a single JS app. Designed for browser-based usage.

DrEVILish avatar May 30 '19 13:05 DrEVILish

Just tested this in chrome and the gap is still there but it's a lot lot smaller. It still does this weird click.

DrEVILish avatar May 30 '19 13:05 DrEVILish

This project looks interesting: https://github.com/astoeckel/opus_gapless/ which is bundled into https://github.com/astoeckel/http_audio_server

It currently triggers an FFmpeg process upon a single audio file and streams it into OPUS blocks.

https://somweyr.de/opus/demo.html -> Demo of actual different tracks being played back gaplessly.

Using the Electron client purely as an Open stream connected to an application that pulls each file and blockifys each file into a folder, this means the process can become multithreaded transcoding the previous. Each block can be continually streamed out to the client one after the other. As each block would have a crossfade between it and the previous one, we can have that as a client setting that would set the size of the overlap of each block.

If each block contains only 2seconds worth of data could a crossfade be longer than the length of a block?

DrEVILish avatar Jun 20 '19 00:06 DrEVILish

https://lists.w3.org/Archives/Public/www-archive/2014Oct/0007.html http://www.htmlfivewow.com/slide58

martpie avatar Sep 05 '19 11:09 martpie

I've been playing around with the WebAudio API in Musseks for a slightly different reason (accurate timestamps for synchronizing audio with lighting with my synesthesia project), which it turned out the HTML <audio> tag was insufficient for (see https://github.com/synesthesia-project/synesthesia/tree/master/precise-audio). I'd be willing to attempt implementing gapless playback in Museeks using web audio, though I cannot provide a timescale.

s0 avatar Feb 24 '20 12:02 s0

This is also a useful article: http://dalecurtis.github.io/llama-demo/index.html

s0 avatar Feb 24 '20 12:02 s0

@s0 great to hear! #128 is a blocker for that though. I really want to solve this so I will try to find myself some time to work on AudioContext.

I would also like to try https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/audioTracks as maybe Gapless playback comes baked in.

martpie avatar Feb 24 '20 13:02 martpie

Made progress with updating my precise-audio library for gapless playback with a small POC in the browser. Seems to work relatively well in chrome when playing LAME encoded MP3 files:

  • Library: https://github.com/synesthesia-project/synesthesia/tree/gapless/precise-audio
  • Example: https://github.com/synesthesia-project/synesthesia/tree/gapless/core/examples/playlist-controller

After I've tightened up the library a bit more, I'll work on pulling the functionality into museeks, and hopefully open a PR soon.

s0 avatar Mar 13 '20 18:03 s0