Open Archanciel opened 3 weeks ago
I have all versions of audioplayers working on Android Studio 2023 and Windows 10. Version 6.1.0 also works. But on Linux everything is sad. The chain of components differs in version. Replacing versions leads to Linux not loading. p.s. I found solution for Ubuntu 20.04 (Terminal, Synaptic and NO Downgrade from Secure. And all will be OK!) Also i found solution for musical application with Notaton and Key-buttons: 1) resolve Memory Leak in Windows (use Map of Audioplayers <String, AudioPlayer> , each holds it's own Note) 2) endless growing of Volume Regulators number in Linux cause sound stop (use method Release() for element of Map of 5...10 Audioplayers. Sounds the latest element. The first element will be Released. ) So we have only 4...5 Volume Regulators for 5 last sounding Notes in Ubuntu->Settings->Sound window. It's OK. NO Dispose() method AT ALL!
"The 'xyz.luan/audioplayers/events/30397293-c286-43db-8767-17482e66e6b2' channel sent a message from native to Flutter on a non-platform thread. Platform channel messages must be sent on the platform thread. Failure to do so may result in data loss or crashes, and must be fixed in the plugin or application code creating that channel" this message does not affect its operation. It continues to work properly.
This error fills all debug output, but does not affect on it's correct work.
Checklist
Current bug behaviour
The integration test tap on the play button and 10 seconds later tap on the pause button. With audioplayers 5.2.0, this works, but with audioplayers 6.1.0, after playing has started, tapping on pause button does not work.
Expected behaviour
I have many integration tests verifying the correctness of my Flutter application. But all those tests if they make audioplayers start playing must be executed with the audioplayers old version (5.2.0). This is totally uncomprehensible !
Steps to reproduce
import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:flutter/material.dart'; import 'package:audiolearn/tools/audioplayers_example.dart' as app;
void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('Audio Player Integration Test', () { testWidgets('Play and Pause Test', (WidgetTester tester) async { // Launch the app app.main(); await tester.pumpAndSettle();
}); }
Code sample
import 'dart:async'; import 'package:path/path.dart' as path;
import 'package:audioplayers/audioplayers.dart'; import 'package:flutter/material.dart';
void main() { runApp(const MaterialApp(home: _SimpleExampleApp())); }
class _SimpleExampleApp extends StatefulWidget { const _SimpleExampleApp();
@override _SimpleExampleAppState createState() => _SimpleExampleAppState(); }
class _SimpleExampleAppState extends State<_SimpleExampleApp> { late AudioPlayer player = AudioPlayer();
@override void initState() { super.initState();
}
@override void dispose() { // Release all sources and dispose the player. player.dispose();
}
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Simple Player'), ), body: PlayerWidget(player: player), ); } }
// The PlayerWidget is a copy of "/lib/components/player_widget.dart". //#region PlayerWidget
class PlayerWidget extends StatefulWidget { final AudioPlayer player;
const PlayerWidget({ required this.player, super.key, });
@override State createState() {
return _PlayerWidgetState();
}
}
class _PlayerWidgetState extends State {
PlayerState? _playerState;
Duration? _duration;
Duration? _position;
StreamSubscription? _durationSubscription; StreamSubscription? _positionSubscription; StreamSubscription? _playerCompleteSubscription; StreamSubscription? _playerStateChangeSubscription;
bool get _isPlaying => _playerState == PlayerState.playing;
bool get _isPaused => _playerState == PlayerState.paused;
String get _durationText => _duration?.toString().split('.').first ?? '';
String get _positionText => _position?.toString().split('.').first ?? '';
AudioPlayer get player => widget.player;
@override void initState() { super.initState(); // Use initial values from player _playerState = player.state; player.getDuration().then( (value) => setState(() { _duration = value; }), ); player.getCurrentPosition().then( (value) => setState(() { _position = value; }), ); _initStreams(); }
@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 dispose() { _durationSubscription?.cancel(); _positionSubscription?.cancel(); _playerCompleteSubscription?.cancel(); _playerStateChangeSubscription?.cancel(); super.dispose(); }
@override Widget build(BuildContext context) { final color = Theme.of(context).primaryColor; return Column( mainAxisSize: MainAxisSize.min, children:[
Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
key: const Key('play_button'),
onPressed: _isPlaying ? null : _play,
iconSize: 48.0,
icon: const Icon(Icons.play_arrow),
color: color,
),
IconButton(
key: const Key('pause_button'),
onPressed: _isPlaying ? _pause : null,
iconSize: 48.0,
icon: const Icon(Icons.pause),
color: color,
),
IconButton(
key: const Key('stop_button'),
onPressed: _isPlaying || _isPaused ? _stop : null,
iconSize: 48.0,
icon: const Icon(Icons.stop),
color: color,
),
],
),
Slider(
onChanged: (value) {
final duration = _duration;
if (duration == null) {
return;
}
final position = value * duration.inMilliseconds;
player.seek(Duration(milliseconds: position.round()));
},
value: (_position != null &&
_duration != null &&
_position!.inMilliseconds > 0 &&
_position!.inMilliseconds < _duration!.inMilliseconds)
? _position!.inMilliseconds / _duration!.inMilliseconds
: 0.0,
),
Text(
_position != null
? '$_positionText / $_durationText'
: _duration != null
? _durationText
: '',
style: const TextStyle(fontSize: 16.0),
),
],
);
}
void _initStreams() { _durationSubscription = player.onDurationChanged.listen((duration) { setState(() => _duration = duration); });
}
Future _play() async {
await player.resume();
setState(() => _playerState = PlayerState.playing);
}
Future _pause() async {
await player.pause();
setState(() => _playerState = PlayerState.paused);
}
Future _stop() async {
await player.stop();
setState(() {
_playerState = PlayerState.stopped;
_position = Duration.zero;
});
}
}
Affected platforms
Windows
Platform details
Windows 10, Visual Studio Code.
AudioPlayers Version
audioplayers 6.1.0
Build mode
debug
Audio Files/URLs/Sources
No response
Screenshots
Organ_Voluntary_in_G_Major,_Op._7,_No._9-_I._Largo_Staccato.zip
Logs
Full Logs
``` my full logs or a link to a gist ``` Flutter doctor: ``` Output of: flutter doctor -v ```Related issues / more information
No response
Working on PR
no way