Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HLS Looping #777

Open
webmonch opened this issue Apr 18, 2024 · 23 comments
Open

HLS Looping #777

webmonch opened this issue Apr 18, 2024 · 23 comments

Comments

@webmonch
Copy link

Hi,

is it possible to loop HLS file? Can't seem to get it working

@ivannador
Copy link
Contributor

Hello,

No, it is not possible to loop a HLS file.

@webmonch
Copy link
Author

Thanks for a quick response @ivannador !

What about progressive download?

@gaborszanto
Copy link
Member

A progressive download will have all features, including looping.

@webmonch webmonch reopened this Apr 22, 2024
@webmonch webmonch reopened this Apr 22, 2024
@webmonch
Copy link
Author

Thanks @gaborszanto!

And how does cachePosition() behave with progressive download? Can it be called right after open(...)?

@gaborszanto
Copy link
Member

It gets cached when that point is downloaded.

@webmonch
Copy link
Author

Thanks! Really appreciate quick response 🙏

One (hopefully) last question - I am trying to run ReactNative example (with progressive download) and I am getting an error:

PlayerEvent_ConnectionLost: "Network socket error. No internet?"

Both on simulator and on device.

If I change it to HLS streaming - everything works fine.

Song url is from example: https://docs.superpowered.com/audio/samples/splice/SO_PF_74_string_phrase_soaring_Gb.mp3
XCode 15.3
IOS 17.4

All settings are from example project.

@webmonch
Copy link
Author

Same on Android. HLS plays fine, progressive download doesn't work.

@webmonch
Copy link
Author

webmonch commented Apr 24, 2024

@ivannador @gaborszanto we are evaluating this SDK for our company use and are blocked by this issue. I'd really appreciate any tips 🙏

@ivannador
Copy link
Contributor

ivannador commented Apr 24, 2024

Did you try a different URL provided by you?
If not, please try with this URL: https://creativelycommon-public-assets.s3.eu-west-2.amazonaws.com/cdk.mp3

@webmonch
Copy link
Author

@ivannador Yes, this one works. But the one in the example doesn't, though it is a valid url.
Is there a way to tell why? To make sure it doesn't happen with urls provided buy us.

Also when I open working url, I get Superpowered::AdvancedAudioPlayer::PlayerEvent_Opened right before Superpowered::AdvancedAudioPlayer::PlayerEvent_ProgressiveDownloadFinished, so playback starts only after download finished.

I expected progressive download to start while the track is being downloaded, or is this not the case?

@ivannador
Copy link
Contributor

Your server has to handle Content-Range in the response header and Range in the request header. Make sure it does, then it'll work. For example S3 supports it by default.
This not working with the URL from the example is an issue on our server, we'll fix that.

Well it is ready for playback after PlayerEvent_Opened so you should listen for that. If PlayerEvent_ProgressiveDownloadFinished comes quickly it means it is downloaded or it's already downloaded and loaded from local.

@webmonch
Copy link
Author

Thank you.

I am also getting a small click when using loopBetween(3000, 5000, true, 255, false) as you can hear on the video. Is it possible to remove it completely?
Happens both on iOS (device + simulator) and MacOS.

RPReplay_Final1714057324.mov

Here is the file I am using (local playback, not download)
https://test-reports-frontend-web.s3.eu-west-2.amazonaws.com/track.mp3

@webmonch
Copy link
Author

And regarding seeking in file that is being downloaded, from what I gathered if you seek to the part that hasn't yet been downloaded, nothing plays, is that correct? If yes, is it possible to force download start from a new position?

@webmonch
Copy link
Author

@ivannador is it technically possible using buffers and advanced player to implement progressive download with seeking?

My use case is basically this:

  • there is an audio file that is split into logical sections. The start/end/length in ms of each section is known before payback starts, along with file size in bytes.
  • when user plays this file from url, file download and playback starts (like now with progressive download)
  • user can Seek() to the start of another section of this file. Playback should start from the beginning of that section. if that part of the file hasn't yet been downloaded - download must start immediately without waiting the progress to reach it (kinda like HLS player does).
  • sections can be looped seamlessly with loopBetween.

From what I gathered, I basically need an HLS player with looping or a progressive download that supports seeking to not downloaded parts.

How can I implement this?

If this is not possible with built-in features, I can implement file downloading in chunks with range header, etc.,
But how would I integrate this with audio buffers?

@ivannador
Copy link
Contributor

Progressive download works in a linear fashion. It starts to download the audio data continuously, you can only seek to what is already downloaded. I suppose making it possible on server-side to "cut" the track in specific parts and load those chunks with progressive download is possible.

That click in loopBetween seems to be a bug, good catch. It is very prominent with a pure tone you are using, not so much with a more complex waveform like an actual track, but still.
We'll provide a fix for that.

As for separately downloading chunks, you can use the AudioInMemory class with append, and openMemory in Advanced Audio Player.

@webmonch
Copy link
Author

Could you please describe very high level flow of using AudioInMemory with the mentioned use case?

e.g. when I download first 10% of the file and 10% in the middle of the file.
decodeToAudioInMemory per docs decodes entire file. How to I decode non linear chunks and play them with the option to loopBetween?

@ivannador
Copy link
Contributor

Well you can create an AudioInMemory container and append raw PCM data to it while you already opened it with openMemory of AAP.
I think you have to make sure that on the server you make downloadable chunks out of the audio track to decode it with Decoder non-linearly.

@webmonch
Copy link
Author

webmonch commented May 2, 2024

Thank you,

Do you think it will possible to add looping to HLS audio file streaming (not real-time, just aac converted to hls) after we purchase a license?

@webmonch
Copy link
Author

webmonch commented May 2, 2024

Also do I need to call any method to inform the player that new data has been appended (when appending compressed data into AiM buffers)?

@ivannador
Copy link
Contributor

We have HLS improvements planned on the longer roadmap, but I can't tell when it will come.

You don't have to inform the player that data has been appended.

@webmonch
Copy link
Author

webmonch commented May 3, 2024

For some reason player doesn't see new sections.
I download chunks of HLS every few seconds and append compressed audio to AiM, but player plays only those that were added before openMemory() was called.

What I do:

  • first two 3-second chunks (aac hls) are downloaded and appended to Audio in Memory
  • player->openMemory(compressedAudioBuffer)
  • wait for Opened event
  • continue downloading next 2 chunks and appending them
  • player->play()

The reserved field in compressed audio buffer changes so I guess player noticed the chunks but the player plays only first two chunks.
What am I missing here?

Screenshot A - when I call play() first time (plays 2 chunks, though 4 are in buffers)
Screenshot B - when I call play() again after first play (still plays only 2)

This is compressed buffer so size is in bytes.

Screenshot 2024-05-03 at 12 30 18 Screenshot 2024-05-03 at 12 30 35

@gaborszanto
Copy link
Member

Is the size argument for the AudioInMemory (main table) set to 0?

@webmonch
Copy link
Author

Yes

compressedAudioBuffer = (Superpowered::AudioInMemory*)Superpowered::AudioInMemory::create(0, 0, 0, false);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants