just_audio icon indicating copy to clipboard operation
just_audio copied to clipboard

Audio stream in Chrome does not return "ready" state after "stop" and "play". Bring only "buffering"

Open oseiasmribeiro opened this issue 2 years ago • 15 comments

I'm creating a new Issues because the other one ( #648 ) was automatically blocked, and I consider this bug in Chrome a big problem. I've done a lot of research on Javascript's "canplaythrough" and "waiting" events, but I couldn't understand the reason to be able to help.

Which API doesn't behave as documented, and how does it misbehave?

just_audio: ^0.9.20 audio_session: ^0.1.6+1

There is different behavior in returning state using Flutter Web in Chrome compared to Android and iOS. After initializing the audio it reaches the "ready" state. After "Play" and "Stop" it reaches the "idle" state. After "play" again, it goes through the "loading" state and stops at "buffering". It doesn't get to the "ready" state again.

Code snippet where I print the state stream:

 ...
 StreamBuilder<ja.PlayerState>(
     stream: _audioPlayer.playerStateStream,
     builder: (context, snapshot) {
       final playerState = snapshot.data;
       // print log 
      print(playerState?.processingState);
      if (playerState?.processingState != ja.ProcessingState.ready  && playerState?.processingState != ja.ProcessingState.idle){
        return Container(
          margin: const EdgeInsets.all(8.0),
          width: 64.0,
          height: 64.0,
          child: const CircularProgressIndicator(),
        );
      } else {
        return playerState?.playing == true ? 
        IconButton(
          icon: const Icon(Icons.stop),
          iconSize: 64.0,
          onPressed: stop,
        ) : 
        IconButton(
          icon: const Icon(Icons.play_arrow),
          iconSize: 64.0,
          onPressed: play,
        );
      }
    },
  ),
...

Repo https://github.com/oseiasmribeiro/webradio.git

To Reproduce (i.e. user steps, not code) Steps to reproduce the behavior:

1 - Click on button Play
2 - Click on button Stop
3 - Click on button Play Again
After that, the state is "buffering" being described on the screen by a CircularProgressIndicator();

Error messages In Chrome browser after "Play" and "Stop" and "Play" again, the state is only in "buffering":

 I[/flutter]() ( 2554): ProcessingState.loading
 I[/flutter]() ( 2554): ProcessingState.buffering
 I[/flutter]() ( 2554): ProcessingState.ready
 ------------------------------------------------- clicked on play -----
 I[/flutter]() ( 2554): ProcessingState.buffering
 I[/flutter]() ( 2554): ProcessingState.ready
 ------------------------------------------------- clicked on stop -----
 I[/flutter]() ( 2554): ProcessingState.idle
 ------------------------------------------------- clicked on play -----
 I[/flutter]() ( 2554): ProcessingState.loading
 I[/flutter]() ( 2554): ProcessingState.buffering
 I[/flutter]() ( 2554): ProcessingState.buffering`

Expected behavior On Android and iOS it is behaving as expected:

 ------------------------------------------------- clicked on play -----
 I[/flutter]() ( 2554): ProcessingState.idle
 I[/flutter]() ( 2554): ProcessingState.loading
 I[/flutter]() ( 2554): ProcessingState.ready
 ------------------------------------------------- clicked on stop -----
 I[/flutter]() ( 2554): ProcessingState.ready
 I[/flutter]() ( 2554): ProcessingState.idle
------------------------------------------------- clicked on play -----
 I[/flutter]() ( 2554): ProcessingState.idle
 I[/flutter]() ( 2554): ProcessingState.loading
 I[/flutter]() ( 2554): ProcessingState.ready

What is desired is that the state does not stop "buffering" because in this way it is not possible to show the buttons correctly.

Screenshots https://user-images.githubusercontent.com/36827173/152571940-95cb270c-4364-45c7-a379-bb800747d19e.png

Desktop (please complete the following information):

 - macOS Monterey Version 12.1
 - Google Chrome: Versão 99.0.4844.83 (Versão oficial) (x86_64)

Smartphone (please complete the following information):

 - Iphone 12 and Redmi Note 10
 - iOS 15.3.1 and Android 12

Flutter SDK version

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 2.10.1, on macOS 12.2.1 21D62 darwin-x64, locale pt-BR)
[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 13.3)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.1)
[!] Android Studio
    ✗ Android Studio not found at /path/to/android-studio/Contents
[✓] VS Code (version 1.65.2)
[✓] Connected device (1 available)
[✓] HTTP Host Availability

Additional context There is not.

oseiasmribeiro avatar Mar 23 '22 14:03 oseiasmribeiro

Oops, it appears that your issue did not follow the template and is missing one or more required sections. Please open a new issue, and provide all required sections and information.

FAQ:

  1. Do I really need to submit a minimal reproduction project for a bug? A: Yes. I prioritise bugs secondarily on how many people are affected, and primarily on whether the bug report is complete, in the sense that it enables me to immediately reproduce it and start working on a fix. If a bug is important to you, the best thing you can do is to provide all requested information ASAP so that I can start looking into it ASAP.

  2. I think I supplied all required information, so did the bot make a mistake? A: The bot only checks the section headings, so when you post a new issue, make sure you leave the section headings intact. (Note that because of this, it is even possible to trick the bot by including only the section headings, and then not providing the requested information under each heading. This is frowned upon, and the issue will be closed manually.)

github-actions[bot] avatar Mar 23 '22 14:03 github-actions[bot]

Can you update your issue with the correct link to the previous issue?

ryanheise avatar Mar 23 '22 14:03 ryanheise

Just post the Issue link? if it is the Issue #648

oseiasmribeiro avatar Mar 23 '22 15:03 oseiasmribeiro

Ah sorry the link was already correct! My mistake.

As for the issue, I'm afraid I still don't have any further leads, though. I have also only tested Chrome. Have you tested other browsers to see if this is unique to Chrome?

ryanheise avatar Mar 23 '22 15:03 ryanheise

I did it now. Safari: Versão 15.3 (17612.4.9.1.8) ---------------------------- is working Edge 99.0.1150.46 (Compilação oficial) (x86_64) ------------- not working

In Edge, although the bug is the same, the behavior is different from Chrome. After Play it no longer returns "Ready'.

oseiasmribeiro avatar Mar 23 '22 16:03 oseiasmribeiro

Hello! I'm having the same issue in Safari, first the state is Ready, and then changes to Buffering, and it doesn't goes back to ready. Safari version: 15.4 (17613.1.17.1.13)

anfernandezz avatar Apr 22 '22 21:04 anfernandezz

That looks very helpful! Basically the first link suggests it's a timing issue. However, you can see in the code that this plugin does register the callbacks.

The second link suggests you actually need to poll ready state since canplaythrough is only going to get called once after the entire audio is loaded...

I guess the second approach, while inelegant, is the only way to get it to work on firefox.

ryanheise avatar May 17 '22 03:05 ryanheise

So, as I understand it, the only way is to check if "Playing" is False or True and disregard the player's status. I tested it on the latest version of Edge and Chrome, it doesn't work. @anfernandezz also tested it on Safari, it gives the same problem.

oseiasmribeiro avatar May 18 '22 13:05 oseiasmribeiro

It wasn't clear to me that @anfernandezz tested the workaround in the second stackoverflow link before you shared that link. But just to be clear, that is what is being tested here? e.g. you have modified just_audio_web to periodically query _audioElement.readyState?

ryanheise avatar May 18 '22 16:05 ryanheise

Sorry, I didn't explain correctly. The tests I mentioned were done a few months ago with Just_Audio version 0.9.20 on Chrome. With the current version of Just_Audio 0.9.21, I tested it in Chrome, Edge and Safari, all give the same problem. These tests were done without changing the source code (I don't really understand how to modifier the Just_Audio_Web package). It's weird that "canplaythrough" doesn't work on the web, I always get a return of "ProcessingState.ready" after Stop and Play on Android and iOS. @anfernandezz also tested this before the links.

oseiasmribeiro avatar May 18 '22 18:05 oseiasmribeiro

OK, then my previous response still applies, and the second link, while inelegant, seems like the only way to get it to work.

ryanheise avatar May 19 '22 02:05 ryanheise

@ryanheise Could you give me some help with a code example of how to use the "second link" with Just_Audio?

oseiasmribeiro avatar May 22 '22 13:05 oseiasmribeiro

To be clear, the solution requires modifying just_audio_web.

ryanheise avatar May 22 '22 13:05 ryanheise

Ok. I'm waiting. Thanks!

oseiasmribeiro avatar May 22 '22 13:05 oseiasmribeiro

May I ask if there is a solution to this problem? I also encountered this problem when I used just_audio: ^0.9.30

FLEasy avatar Nov 09 '22 09:11 FLEasy

There is a solution approach discussed above, but someone needs to tackle that and implement it into just_audio_web (and it doesn't have to be me - contributors are welcome if you'd like to help make it happen sooner.)

ryanheise avatar Nov 09 '22 11:11 ryanheise