-
-
Notifications
You must be signed in to change notification settings - Fork 890
docs: Improve Docs #1710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
docs: Improve Docs #1710
Changes from 9 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
3528a14
docs: Fix typos from #1678
Gustl22 0cf643a
docs: Update README of example
Gustl22 d9f975f
docs: Change heading of CORS Policy in troubleshooting.md
Gustl22 dd843ae
docs: Rework AudioCache and Local Assets docs
Gustl22 ee21af6
Create example.dart
Gustl22 b882457
Add example.md
Gustl22 9052072
Clarify Low latency
Gustl22 af55d31
Clarify Low latency
Gustl22 dd4dd24
Troubleshooting: Analyze audio file format
Gustl22 96d106b
Apply suggestions from code review
Gustl22 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,243 @@ | ||
| Below example demonstrates a simple player app. | ||
|
Gustl22 marked this conversation as resolved.
Outdated
|
||
|
|
||
| A complete example showcasing all _audioplayers_ features can be found in our [repository](https://github.com/bluefireteam/audioplayers/tree/main/packages/audioplayers/example). | ||
| Also check out our live [web app](https://bluefireteam.github.io/audioplayers/). | ||
|
|
||
| ```dart | ||
| import 'dart:async'; | ||
|
|
||
| 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(); | ||
|
|
||
| // Create the audio player. | ||
| player = AudioPlayer(); | ||
|
|
||
| // Set the release mode to keep the source after playback has completed. | ||
| player.setReleaseMode(ReleaseMode.stop); | ||
|
|
||
| // Start the player as soon as the app is displayed. | ||
| WidgetsBinding.instance.addPostFrameCallback((_) async { | ||
| await player.setSource(AssetSource('ambient_c_motion.mp3')); | ||
| await player.resume(); | ||
| }); | ||
| } | ||
|
|
||
| @override | ||
| void dispose() { | ||
| // Release all sources and dispose the player. | ||
| player.dispose(); | ||
|
|
||
| super.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<StatefulWidget> createState() { | ||
| return _PlayerWidgetState(); | ||
| } | ||
| } | ||
|
|
||
| class _PlayerWidgetState extends State<PlayerWidget> { | ||
| 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: <Widget>[ | ||
| 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); | ||
| }); | ||
|
|
||
| _positionSubscription = player.onPositionChanged.listen( | ||
| (p) => setState(() => _position = p), | ||
| ); | ||
|
|
||
| _playerCompleteSubscription = player.onPlayerComplete.listen((event) { | ||
| setState(() { | ||
| _playerState = PlayerState.stopped; | ||
| _position = Duration.zero; | ||
| }); | ||
| }); | ||
|
|
||
| _playerStateChangeSubscription = | ||
| player.onPlayerStateChanged.listen((state) { | ||
| setState(() { | ||
| _playerState = state; | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| Future<void> _play() async { | ||
| final position = _position; | ||
| if (position != null && position.inMilliseconds > 0) { | ||
| await player.seek(position); | ||
| } | ||
| await player.resume(); | ||
| setState(() => _playerState = PlayerState.playing); | ||
| } | ||
|
|
||
| Future<void> _pause() async { | ||
| await player.pause(); | ||
| setState(() => _playerState = PlayerState.paused); | ||
| } | ||
|
|
||
| Future<void> _stop() async { | ||
| await player.stop(); | ||
| setState(() { | ||
| _playerState = PlayerState.stopped; | ||
| _position = Duration.zero; | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| //#endregion | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.