Flutter-AssetsAudioPlayer icon indicating copy to clipboard operation
Flutter-AssetsAudioPlayer copied to clipboard

2 instances of the player start at the same time

Open pelguetat opened this issue 3 years ago • 2 comments

Flutter Version

My version : 3.7

Lib Version

My version :

Platform (Android / iOS / web) + version

Platform : android 12

Describe the bug

When I press the play button to transition to the player screen, it starts playing the same mp3 at the same time, and sometimes after a few seconds. If I press the pause button, one of the songs stops playing and the other continues.

Here's the class where I implemented assets audio player: `import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:assets_audio_player/assets_audio_player.dart'; import 'package:podfic_app/providers/podfic_data_provider.dart'; import 'package:provider/provider.dart'; import 'package:podfic_app/main.dart';

class PageManager { String? url; late AssetsAudioPlayer _audioPlayer;

//ValueNotifier to notify of the current state of the progress bar final progressNotifier = ValueNotifier<ProgressBarState>( ProgressBarState( current: Duration.zero, total: Duration.zero, ), );

//ValueNotifier to notify of the current state of the button final buttonNotifier = ValueNotifier<ButtonState>(ButtonState.paused); PageManager({this.url}) { _init(); } //Initialization function void _init() async { _audioPlayer = AssetsAudioPlayer(); // esta funcion es la que entrega la info para controlar los botones //Open the audio file from the given url await _audioPlayer.open(Audio.network(url!)); // Listen for changes in the isPlaying status

//Listen for changes in the current position of the audio
_audioPlayer.currentPosition.listen((position) {
  final oldState = progressNotifier.value;
  progressNotifier.value = ProgressBarState(
    current: position,
    total: oldState.total,
  );
});
//Listen to the current playing song
_audioPlayer.current.listen((playingAudio) {
  final songDuration = playingAudio?.audio.duration;
  final oldState = progressNotifier.value;
  progressNotifier.value = ProgressBarState(
    current: oldState.current,
    total: songDuration ?? Duration.zero,
  );
  print('hola');

  _audioPlayer.isPlaying.listen((isPlaying) {
    buttonNotifier.value =
        isPlaying ? ButtonState.playing : ButtonState.paused;
  });
});

}

//Function to play the audio void play() { _audioPlayer.play(); }

//Function to pause the audio void pause() { _audioPlayer.pause(); }

//Function to free the player's resources after use void dispose() { _audioPlayer.dispose(); }

//Function to seek audio to a specific position in the bar void seek(Duration position) { _audioPlayer.seek(position); }

//Function to go to the next audio next() { _audioPlayer.next(); }

//Function to go the previous audio prev() { _audioPlayer.previous(); }

// changeUrl(newUrl) { // url = newUrl; // _audioPlayer.open(Audio.network(url)); // } }

//Class for the progress bar state class ProgressBarState { ProgressBarState({ required this.current, required this.total, }); final Duration current; final Duration total; }

Enum for the button state enum ButtonState { paused, playing }

/

` And here's the code for the Player UI that calls the PageManager class:

`import 'package:flutter/material.dart'; import 'page_manager.dart'; import 'package:audio_video_progress_bar/audio_video_progress_bar.dart'; import 'package:podfic_app/providers/podfic_data_provider.dart'; import 'package:provider/provider.dart'; import 'dart:developer';

class Player extends StatefulWidget { final String? audio_url_passed; Player({super.key, this.audio_url_passed});

@override State<Player> createState() => _PlayerState(); }

class _PlayerState extends State<Player> { late PageManager _pageManager = PageManager();

@override initState() { super.initState(); _pageManager = PageManager(); }

@override void dispose() { _pageManager.dispose(); super.dispose(); }

@override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 25.0), child: Column( children: [ const SizedBox(height: 10),

          // back button and menu button
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              SizedBox(
                height: 60,
                width: 60,
                child: IconButton(
                    icon: const Icon(Icons.arrow_back), onPressed: () {}),
              ),
              Text('Playing Now'),
              SizedBox(
                height: 60,
                width: 60,
                child: IconButton(
                    icon: const Icon(Icons.menu), onPressed: () {}),
              ),
            ],
          ),

          const SizedBox(height: 25),

          // cover art, artist name, song name
          Column(
            children: [
              ClipRRect(
                borderRadius: BorderRadius.circular(8),
                child: Image.asset(
                    'https://i.ibb.co/Yts3QGd/assassin.jpg'), //cambiar por coverUrl
              ),
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          'Kota The Friend',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 18,
                            color: Colors.grey.shade700,
                          ),
                        ),
                        const SizedBox(height: 6),
                        const Text(
                          'Birdie',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 22,
                          ),
                        ),
                      ],
                    ),
                    IconButton(
                        icon: const Icon(Icons.favorite),
                        color: Colors.red,
                        onPressed: () {}),
                  ],
                ),
              )
            ],
          ),

          const SizedBox(height: 30),

          // start time, shuffle button, repeat button, end time
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Text('0:00'),
              IconButton(icon: Icon(Icons.shuffle), onPressed: () {}),
              IconButton(icon: Icon(Icons.repeat), onPressed: () {}),
              Text('4:22')
            ],
          ),

          const SizedBox(height: 20),

          // linear bar
          ValueListenableBuilder<ProgressBarState>(
            valueListenable: _pageManager.progressNotifier,
            builder: (_, value, __) {
              return ProgressBar(
                progressBarColor: Colors.black12,
                progress: value.current,
                total: value.total,
                onSeek: _pageManager.seek,
              );
            },
          ),

          const SizedBox(height: 30),

          // previous song, pause play, skip next song
          SizedBox(
            height: 80,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                IconButton(
                  onPressed: _pageManager.prev(),
                  icon: const Icon(Icons.skip_previous),
                  iconSize: 32.0,
                ),
                ValueListenableBuilder<ButtonState>(
                  valueListenable: _pageManager.buttonNotifier,
                  builder: (_, value, __) {
                    switch (value) {
                      case ButtonState.paused:
                        return IconButton(
                          icon: const Icon(Icons.play_arrow),
                          iconSize: 32.0,
                          onPressed: _pageManager.play,
                        );
                      case ButtonState.playing:
                        return IconButton(
                          icon: const Icon(Icons.pause),
                          iconSize: 32.0,
                          onPressed: _pageManager.pause,
                        );
                    }
                  },
                ),
                IconButton(
                  onPressed: _pageManager.next(),
                  icon: const Icon(Icons.skip_next),
                  iconSize: 32.0,
                ),
              ],
            ),
          )
        ],
      ),
    ),
  ),
);

} } `

pelguetat avatar Feb 03 '23 18:02 pelguetat

@pelguetat It might work with turning autoStart property to false in AssetsAudioPlayer.open(). Like this:

await _audioPlayer.open(Audio.network(url!), 
autoStart: false,
);

masa-tokyo avatar Feb 26 '23 03:02 masa-tokyo

A similar problem happened to my Android device too. In my case, I pass Playlist instead of Audio.network() when opening the player. And somehow the behavior differed on whether to turn it to false or not.

masa-tokyo avatar Feb 26 '23 03:02 masa-tokyo