feat: ProgressBar shows position in song

This commit is contained in:
Orangerot 2024-12-23 04:18:04 +01:00
parent 1415f91fa5
commit 97598c741d

View file

@ -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();
} }
} }