bluefireteam / audioplayers

A Flutter package to play multiple audio files simultaneously (Android/iOS/web/Linux/Windows/macOS)
https://pub.dartlang.org/packages/audioplayers
MIT License
2.02k stars 847 forks source link

Duration stream working only sometimes #1552

Open TimeLord2010 opened 1 year ago

TimeLord2010 commented 1 year ago

Checklist

Current bug behaviour

I'm using the UrlSource to play the files. It plays them as expected and I noticed that on macos and windows I can use the seek method even then the onduration stream emits only zeros, but on android, if the duration stream fails, then It cannot seek to a forward position or backward position.

Expected behaviour

No response

Steps to reproduce

  1. Set the url source;
  2. Call "resume()";
  3. Try to seek at a position;

Code sample

Code sample ```dart import 'dart:async'; import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/widgets.dart'; import 'package:music_player/models/music.dart'; import 'package:music_player/usecases/music/get_music_download_url.dart'; class PlayerProvider extends ChangeNotifier { final AudioPlayer _player = AudioPlayer(); PlayerProvider() { _player.onPositionChanged.listen((duration) { var seconds = duration.inSeconds; debugPrint('seconds: $seconds'); playPosition = seconds; }); _player.onDurationChanged.listen((duration) { var seconds = duration.inSeconds; debugPrint('duration: $seconds'); if (seconds != 0) { songDuration = seconds; } }); _player.onPlayerComplete.listen((_) { isPlaying = false; }); _player.setAudioContext(const AudioContext( android: AudioContextAndroid( audioMode: AndroidAudioMode.normal, contentType: AndroidContentType.music, isSpeakerphoneOn: true, usageType: AndroidUsageType.media, ), )); } @override void dispose() { _player.dispose(); super.dispose(); } Music? currentSong; bool _isPlaying = false; bool get isPlaying => _isPlaying; set isPlaying(bool value) { _isPlaying = value; notifyListeners(); } int _songDuration = 0; int get songDuration => _songDuration; set songDuration(int value) { if (value == songDuration) { return; } _songDuration = value; notifyListeners(); } int _playPosition = 0; int get playPosition => _playPosition; set playPosition(int value) { _playPosition = value; notifyListeners(); } double get progress { if (songDuration == 0) return 0; var value = playPosition / songDuration; return value; } void start(Music music) async { isPlaying = false; _songDuration = 0; debugPrint("state: ${_player.state.name}"); if (_player.state != PlayerState.completed && _player.state != PlayerState.stopped) { debugPrint('Stopping old song'); try { await _player.stop().timeout(const Duration( seconds: 2, )); debugPrint('Stoped old song'); } on TimeoutException { debugPrint('Failed to stop song due to timeout'); } } var id = music.id; if (id == null) { return; } var name = music.title; debugPrint('Starting song: $name'); currentSong = music; var url = getMusicDownloadUrl(id); await _player.setSource(UrlSource(url)); togglePlay(); } void togglePlay() { if (isPlaying) { debugPrint('Pausing'); _player.pause(); } else { debugPrint('Resuming'); _player.resume(); } isPlaying = !isPlaying; } void seekByOffset(int offset) async { var position = playPosition + offset; debugPrint('Seeking: $position/$playPosition'); await _player.seek(Duration( seconds: playPosition + offset, )); } } ```

Affected platforms

Android

Platform details

Android 11 (API 30), Real device

AudioPlayers Version

4.1.0

Build mode

No response

Audio Files/URLs/Sources

Screenshots

No response

Logs

No response

Related issues / more information

No response

Working on PR

no way

TimeLord2010 commented 1 year ago

I could work on a PR, but I checked the android code and it is really straightforward. I don't see nothing I could do there.

This seems to be related to something somefiles have that others don't. But I don't know what.

Gustl22 commented 1 year ago

Usually there should be no files, which don't emit a non zero duration, unless it's a live stream. On a live stream one should not be able to seek, at least some of our native players (on certain platforms) don't support that (like in Android).