The behavior seeking in expo audio and html5 audio is different

My problem is I have a mp3 file on the internet that file just a conversation of english
and i have all sentence of that conversation and also have a millisecond of each sentence.
example:
sentence 1(start: 400)
sentence 2(start: 2000)
sentence 3(start: 3000)
When i click on sentence 1
on Html5 Audio: i play mp3 at 400 millisecond it completely fine and perfect,
on Expo Audio: it may a little delay about 450 millisecond.

More information that if a file mp3 length less than 5mins it work perfectly in html5 and Expo audio
With the longer mp3 (arround 15mins or more) it complety incorrect.
Do you have any idea or suggestion about this? I’m totally lost

Hey @maidanhcongtu,

Could you provide a minimal, reproducible example of this behavior in a Snack https://snack.expo.io/?

It sounds like this may be a bug, and it would really help us debug it if we had some form of a reproduction case.

Cheers,

Adam

Hi @adamjnav
I have just created the snack for that problem

and also html file and audio

And I mark a difference color that in expo it not work correct
Can you please check it out and tell me what to do next?

Hi @maidanhcongtu - I’m not sure what the problem is in the snack you’ve provided. It seems to work fine for me on Android (though it errors on my iOS device). Could you clarify which platform you’re seeing the issue on, and what we should be expecting to see vs. what is wrong in your example?

Hi @esamelson
My problem is that when I click in a certain sentence in mobile and in html5 and there some delay time in mobile side. And I also mark a background difference color for you to check it easily.
You can open a html file that I put in a previous comment and run that file.
You click several times in sentence(background red) in html and do the same in mobile side you will see that in mobile side there are some delay time.
I use Samsumg A5 to run that snack

1 Like

Hmm okay. @sjchmiela do you have any ideas?

There are a couple of things one has to take into consideration when using seeking heavily:

  • React Native bridge over which commands are sent from/to native is asynchronous, i. e. playFromPositionAsync may be delivered to the native code with some small, insignificant delay; we could make it a synchronous method, but…

  • …it wouldn’t make much sense, as seeking media files is typically an asynchronous operation natively too (see eg. AVPlayer’s seekToTime:completionHandler:, I don’t remember whether ExoPlayer’s seekTo() are sync or async).

  • Native API is designed this way because when the player receives a seek request it has to either fetch a decoded buffer from memory or decode part of the file on-the-fly. This operation also introduces some, this time more significant delay.

  • Another thing is access time to the media source—when streaming a file over the network it will be significantly higher than when reading the file from the local filesystem.

  • All this makes native players use multiple optimization techniques, one of which is inexact seeking (both platforms do that, both Android and iOS). Inexact seeking means that if you request the player to seek to eg. position 352 ms and it already has a decoded, buffered fragment of 418—…, it will seek to 418 ms not to make you wait for decoding of that 66 ms of difference.

    Fortunately, this is something we can configure with function arguments. For this we’ve created playbackObject.playFromPositionAsync(millis, { toleranceMillisBefore, toleranceMillisAfter }). At the moment setting toleranceMillis has an effect only on iOS, but if you submit an issue on GitHub - expo/expo: An open-source platform for making universal native apps with React. Expo runs on Android, iOS, and the web. we could track this inconsistency more easily and, hopefully, implement it for the next release. :slightly_smiling_face:

What I would encourage you to do is to:

  1. instead of using required file directly as the source provided do AV API, I would wrap it with Asset.fromModule() and download it prior to playing the file (or showing the app’s interface, depends on your UX decisions) — this way the file will be available for the decoder right away,
  2. if keeping the difference between requested and the real seeked position is crucial, provide tolerance milliseconds to playFromPositionAsync — this way we’ll favor accuracy of the seek over seeking quickly,
  3. post an issue on GitHub - expo/expo: An open-source platform for making universal native apps with React. Expo runs on Android, iOS, and the web. about tolleranceMillis being taken into consideration only on iOS and assign it to me. :slightly_smiling_face:
1 Like

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.