I have a list containing music on each item. If I close the screen im changing the index
of the currently located BottomNavigationPage
and calling the stop function for stopping the audio, but exactly this doesnt work sometimes. If the song is in loading process or user is really fast, song will continue beeing played on different pages.
Im using https://pub.dev/packages/audioplayers plugin.
This is my minified code example full working demo: EDIT::
So i followed up the hint of @Ringil providing a full working example with the actual issue im facing in here. This is my code:
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int currentIndex =0;
@override
Widget build(BuildContext context) {
// Page selector for tab list
void _selectPage(int index) {
print('page index: $index');
setState(() {
currentIndex = index;
});
}
// Routes list for tab navigation Android
final List<Widget> _pages = [
ScreenA(),
ScreenB(func: _selectPage),
];
return Scaffold(
appBar: AppBar(),
body: _pages[currentIndex],
bottomNavigationBar: SafeArea(
child: BottomNavigationBar(
onTap: _selectPage,
iconSize: 22,
currentIndex: currentIndex,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
backgroundColor: Theme.of(context).primaryColor,
icon: Icon(Icons.description),
label: 'ScreenA',
),
BottomNavigationBarItem(
backgroundColor: Theme.of(context).primaryColor,
icon: Icon(Icons.ac_unit_outlined),
label: 'ScreenB'),
],
),
),
);
}
}
class ScreenA extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
child: Text('HOME'),
);
}
}
class ScreenB extends StatefulWidget {
Function func;
ScreenB({Key key, @required this.func}) : super(key: key);
@override
_ScreenBState createState() => _ScreenBState();
}
class _ScreenBState extends State<ScreenB> {
var audioPlayer = AudioPlayer(playerId: 'player');
var audioIndex = 0;
var audioFiles = [
"https://docs.google.com/uc?export=open&id=1SaJWqfQuHnFtL7uqrzfYG31hzOnqDM3r",
"https://docs.google.com/uc?export=open&id=1FZkFMjQyWguAl0RMAsYDEZ07c_Qf7gjz",
"https://docs.google.com/uc?export=open&id=1GqrwQ3eRuiil0p-Na_R1tMAvggp9YrbH",
];
var _controller = PageController();
@override
void initState() {
super.initState();
// starting player
startPlayer();
}
startPlayer() {
play();
}
// Player play class set globalindex
Future<void> play() async {
int result = await audioPlayer.play(audioFiles[audioIndex]);
if (result == 1) {
// success
}
}
// Stop song instance of player
Future<void> stop() async {
int result = await audioPlayer.stop();
if (result == 1) {
// success
}
}
// disposing listener if not needed or users navigates away from
@override
void dispose() {
super.dispose();
audioPlayer.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(Icons.access_alarm_sharp),
onPressed: () async {
await stop();
widget.func(0);
},
),
],
),
body: PageView.custom(
dragStartBehavior: DragStartBehavior.start,
controller: _controller,
physics: NeverScrollableScrollPhysics(),
scrollDirection: Axis.horizontal,
childrenDelegate: SliverChildBuilderDelegate((ctx, pageIndex) =>
GestureDetector(
onPanUpdate: (details) async {
if (details.delta.dx < 0) {
_controller.nextPage(
duration: Duration(milliseconds: 200),
curve: Curves.easeInOut);
await stop();
setState(() {
audioIndex = pageIndex;
play();
});
}
},
child: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
child: Text(audioFiles[audioIndex])))))),
);
}
}
And a short video showing the issue. If we go to the carousel screen, navigate threw songs and closing the screen before they have been loaded, they will be played on a different screen which I dont want. I also dont want to somehow "block" the user sliding threw the carousel until the song is loaded. Video: https://streamable.com/e/ycxwob
Basically I shrinked my code up to the minimum possible. I took the code of Ringil because in his demo everything works perfectly fine. Then I added more and more code from me, until I noticed the error again. Now here we are. Basically there is a difference in the example audio files from hin and mine. My files arent big from filesize aspect but they seem to be longer, which gives us the delay Im expecting all the time. It seems like if the song isnt loaded before closing or changing the index, the error occurs.