feat: ProgressBar shows position in song
This commit is contained in:
parent
1415f91fa5
commit
97598c741d
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -12,44 +13,98 @@ class Level extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _LevelState extends State<Level> {
|
class _LevelState extends State<Level> {
|
||||||
final _player = AudioPlayer();
|
final player = AudioPlayer();
|
||||||
bool _isPlaying = true;
|
bool _isPlaying = true;
|
||||||
|
Duration? _duration;
|
||||||
|
Duration? _position;
|
||||||
|
|
||||||
|
StreamSubscription? _durationSubscription;
|
||||||
|
StreamSubscription? _positionSubscription;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void setState(VoidCallback fn) {
|
||||||
|
// Subscriptions only can be closed asynchronously,
|
||||||
|
// therefore events can occur after widget has been disposed.
|
||||||
|
if (mounted) {
|
||||||
|
super.setState(fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
// Use initial values from player
|
||||||
|
player.getDuration().then(
|
||||||
|
(value) => setState(() {
|
||||||
|
_duration = value;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
player.getCurrentPosition().then(
|
||||||
|
(value) => setState(() {
|
||||||
|
_position = value;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
_durationSubscription = player.onDurationChanged.listen((duration) {
|
||||||
|
setState(() => _duration = duration);
|
||||||
|
});
|
||||||
|
|
||||||
|
_positionSubscription = player.onPositionChanged.listen(
|
||||||
|
(p) => setState(() => _position = p),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
player.onDurationChanged.listen((Duration d) {
|
||||||
|
// print('Max duration: $d');
|
||||||
|
setState(() => _duration = d);
|
||||||
|
});
|
||||||
|
|
||||||
|
player.onPositionChanged.listen((Duration p) {
|
||||||
|
// print('Current position: $p');
|
||||||
|
setState(() => _position = p);
|
||||||
|
});
|
||||||
|
|
||||||
String audioPath = Directory(widget.stepmaniaFolderPath)
|
String audioPath = Directory(widget.stepmaniaFolderPath)
|
||||||
.listSync()
|
.listSync()
|
||||||
.firstWhere((entity) => entity.path.endsWith('.ogg'),
|
.firstWhere((entity) => entity.path.endsWith('.ogg'),
|
||||||
orElse: () => File(''))
|
orElse: () => File(''))
|
||||||
.path;
|
.path;
|
||||||
_player.play(DeviceFileSource(audioPath));
|
player.play(DeviceFileSource(audioPath));
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: Icon(_isPlaying ? Icons.pause : Icons.play_arrow),
|
icon: Icon(_isPlaying ? Icons.pause : Icons.play_arrow),
|
||||||
onPressed: () => {
|
onPressed: () {
|
||||||
if (_isPlaying)
|
if (_isPlaying) {
|
||||||
{
|
player.pause();
|
||||||
_player.pause(),
|
setState(() {
|
||||||
setState(() {
|
_isPlaying = false;
|
||||||
_isPlaying = false;
|
});
|
||||||
})
|
} else {
|
||||||
}
|
player.resume();
|
||||||
else
|
setState(() {
|
||||||
{
|
_isPlaying = true;
|
||||||
_player.resume(),
|
});
|
||||||
setState(() {
|
}
|
||||||
_isPlaying = true;
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
title: Text('Level 1'),
|
title: Text(widget.stepmaniaFolderPath.split('/').last),
|
||||||
actions: [
|
actions: [
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.close),
|
icon: Icon(Icons.close),
|
||||||
onPressed: () => Navigator.pop(context))
|
onPressed: () => Navigator.pop(context))
|
||||||
],
|
],
|
||||||
|
bottom: PreferredSize(
|
||||||
|
preferredSize: Size(double.infinity, 1.0),
|
||||||
|
child: LinearProgressIndicator(
|
||||||
|
value: (_duration != null &&
|
||||||
|
_position != null &&
|
||||||
|
_position!.inMilliseconds > 0 &&
|
||||||
|
_position!.inMilliseconds < _duration!.inMilliseconds)
|
||||||
|
? _position!.inMilliseconds / _duration!.inMilliseconds
|
||||||
|
: 0.0,
|
||||||
|
)),
|
||||||
),
|
),
|
||||||
body: Stack(children: [
|
body: Stack(children: [
|
||||||
Arrow(
|
Arrow(
|
||||||
|
@ -91,7 +146,9 @@ class _LevelState extends State<Level> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_player.dispose();
|
_durationSubscription?.cancel();
|
||||||
|
_positionSubscription?.cancel();
|
||||||
|
player.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue