florent37 / Flutter-AssetsAudioPlayer

Play simultaneously music/audio from assets/network/file directly from Flutter, compatible with android / ios / web / macos, displays notifications
https://pub.dartlang.org/packages/assets_audio_player
Apache License 2.0
757 stars 367 forks source link

Seek disrupts current position. #387

Open leidig54 opened 4 years ago

leidig54 commented 4 years ago

Doctor summary (to see all details, run
flutter doctor -v):

[✓] Flutter (Channel beta, 1.23.0-18.1.pre,
    on Mac OS X 10.15.7 19H2 x86_64, locale
    en-GB)
[✓] Android toolchain - develop for Android
    devices (Android SDK version 29.0.3)
[✓] Xcode - develop for iOS and macOS (Xcode
    12.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 3.6)
[✓] VS Code (version 1.50.1)
[✓] Connected device (3 available)

• No issues found!

Hi Florent37. I'm making an app that delivers audio tracks with subtitles for deaf people. Using seek() or seekBy() throws off the currentPosition stream and thus throws the subtitles out of sync. It's not a huge amount but enough that my subtitles are two or three "slides" behind or ahead of the actual audio (and therefore useless).

I'm using a PlayerBuilder to create a seekBar, although this issue persists even when I use a button to skip forward or back by any amount. To confirm its affecting the current position you can skip forward and back a few times and keep an eye on the finish time in the current position - its different depending on how many times you use seek.

 PlayerBuilder.currentPosition(
                              player: therapyPlayer.audioPlayer,
                              builder: (context, duration) {
                                Duration totalDuration;

                                if (therapyPlayer.audioPlayer.current.value !=
                                    null) {
                                  totalDuration = therapyPlayer
                                      .audioPlayer.current.value.audio.duration;
                                }

                                double currentPositionAsDouble =
                                    duration.inSeconds /
                                        totalDuration.inSeconds;

                                return Slider(
                                  onChanged: (value) async {
                                    await therapyPlayer.audioPlayer.seek(
                                        Duration(
                                            seconds: (value *
                                                    totalDuration.inSeconds)
                                                .toInt()));
                                  },
                                  value: currentPositionAsDouble,
                                );
                              }),

And srt-parser to match up the subtitles to the current position.

StreamBuilder<Duration>(
                              stream: therapyPlayer.audioPlayer.currentPosition,
                              builder: (context, snapshot) {
                                int currentPosition = 0;
                                String subtitleText = "";
                                if (snapshot.hasData) {
                                  currentPosition =
                                      snapshot.data.inMilliseconds;
                                  subtitleText = subtitles
                                      .lastWhere(
                                          (element) =>
                                              element.range.begin <=
                                              currentPosition,
                                          orElse: () => Subtitle())
                                      .rawLines
                                      .join(" ");
                                }
                                return Center(
                                  child: AutoSizeText(
                                    subtitleText,
                                    textAlign: TextAlign.center,
                                    style: Theme.of(context)
                                        .textTheme
                                        .bodyText2
                                        .copyWith(fontSize: 26),
                                  ),
                                );
                              })
leidig54 commented 4 years ago

FYI this is only on iOS. No issues with android.

murilosamuel commented 3 years ago

@leidig54, I had the same problem in iOS. To solve, in my case, I took out the header.


audio = Audio.network(urlAudio,
      //headers: headers,
      metas: Metas(
        id: "${widget.publicacao.id}",
        title: "${widget.publicacao.descricao}",
        artist: "${widget.publicacao.titulo}",
        album: "PodCast",
        image: capa
      ),
    );
`
leidig54 commented 3 years ago

@murilosamuel thanks for the reply. Unfortunately I'm not using headers at all so that won't work for me.

AlexandroKurchenko commented 3 years ago

Hi all, have similar behavior for android only(and for some audio on the web). If I start playing a file from the path on android and trying to seek in some other position, audio starting from the beginning. I the above case I also have a subscription for "assetsAudioPlayer.currentPosition.listen((duration) {}" and saw that position starting from the beginning. Also, check assetsAudioPlayer.currentPosition.value before assetsAudioPlayer.seek() and after seek, and receive a correct position. But right after that, I receive a position starting from 00:00.

This behavior i saw only for android, in Ios everything is seeking without any problem. On the web, similar behavior with seeking happens with some audio tracks, but on the web, I trying to play from URL. Version assets_audio_player: ^2.0.13+1 Flutter web version: [✓] Flutter (Channel beta, 1.24.0-10.2.pre, on macOS 11.1 20C69 darwin-x64, locale ru-UA) • Flutter version 1.24.0-10.2.pre at ...../Library/Android/flutter • Framework revision 022b333a08 (8 weeks ago), 2020-11-18 11:35:09 -0800 • Engine revision 07c1eed46b • Dart version 2.12.0 (build 2.12.0-29.10.beta) Flutter Android and Ios version: [✓] Flutter (Channel stable, 1.22.5, on macOS 11.1 20C69 darwin-x64, locale ru-UA) • Flutter version 1.22.5 at ...../Library/Android/flutter • Framework revision 7891006299 (5 weeks ago), 2020-12-10 11:54:40 -0800 • Engine revision ae90085a84 • Dart version 2.10.4

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3) • Android SDK at ....../Library/Android/sdk • Platform android-30, build-tools 30.0.3 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495) • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.3) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 12.3, Build version 12C33 • CocoaPods version 1.10.0 [✓] Connected device (2 available)
• SM J330F (mobile) • android-arm • Android 9 (API 28) • iPhone (Александр) (mobile) • ios • iOS 14.2

Probably this is a separate bug but looks like similar behavior.