Skip to content
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

feat!: event channel #1352

Merged
merged 227 commits into from
Apr 4, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
227 commits
Select commit Hold shift + click to select a range
4a1380a
feat: error stream (#1266)
Gustl22 Dec 20, 2022
e5e1a1c
Merge branch 'main' into gustl22/1266-error-stream
Gustl22 Dec 25, 2022
f7efbc8
fix(android): forward errors from event stream to avoid crashing (#1260)
Gustl22 Dec 25, 2022
63126f0
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Dec 25, 2022
2252dbc
tests(android): add simultaneously lib tests (#1353)
Gustl22 Dec 26, 2022
4cd51f0
feat(android): print stacktrace
Gustl22 Jan 1, 2023
ea3ecfc
Merge branch 'main' into gustl22/1266-error-stream
Gustl22 Jan 1, 2023
d1b71c7
feat: add mp2 record
Gustl22 Jan 1, 2023
d553054
feat: logs as stream
Gustl22 Jan 2, 2023
a63407b
feat: hashMapOf
Gustl22 Jan 5, 2023
b95728c
feat: global log
Gustl22 Jan 6, 2023
71a4597
feat: global log
Gustl22 Jan 6, 2023
f19b7fa
feat: SoundPoolWrapper
Gustl22 Jan 7, 2023
0c41e60
feat: colorized logs
Gustl22 Jan 7, 2023
061b5f8
test: onResume log test
Gustl22 Jan 7, 2023
3a5dbeb
docs: edit docs for log
Gustl22 Jan 7, 2023
821a669
fix: optional playerId
Gustl22 Jan 8, 2023
67ca076
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Jan 16, 2023
40b38ca
feat: mutable soundPoolWrapper
Gustl22 Jan 16, 2023
294e0ba
feat(android): configurable AudioContext in LOW_LATENCY mode
Gustl22 Jan 16, 2023
297906e
feat(android): some improvements
Gustl22 Jan 16, 2023
92049b7
fix(android): initializing soundPools
Gustl22 Jan 16, 2023
7e27714
fix(android): initializing soundPools
Gustl22 Jan 17, 2023
9a75da6
example: ios audio context
Gustl22 Jan 17, 2023
64fb6e2
example: dropdowns
Gustl22 Jan 17, 2023
d40aa11
feat(android): SoundPoolManager
Gustl22 Jan 17, 2023
a106889
fix
Gustl22 Jan 17, 2023
ddd8197
fix
Gustl22 Jan 17, 2023
c61571b
fix
Gustl22 Jan 17, 2023
2760c99
fix
Gustl22 Jan 17, 2023
90949ae
fix
Gustl22 Jan 18, 2023
8778103
generate ios options
Gustl22 Jan 18, 2023
c4cb0df
renaming
Gustl22 Jan 18, 2023
6a86d8d
fix initialization
Gustl22 Jan 18, 2023
16a9771
Tests for AudioContextConfig
Gustl22 Jan 18, 2023
db0d830
Flutter analyze
Gustl22 Jan 18, 2023
ecb89a7
suppress warning about unused parameter
Gustl22 Jan 18, 2023
d252b02
change todo
Gustl22 Jan 18, 2023
ad0c4fc
revert EnumTgl
Gustl22 Jan 18, 2023
ba4865f
no need for initial sound pool
Gustl22 Jan 18, 2023
ef643f7
audioMode
Gustl22 Jan 18, 2023
d5d4434
audioMode
Gustl22 Jan 18, 2023
9091d28
Adapt example
Gustl22 Jan 18, 2023
f444e62
finish audioContext
Gustl22 Jan 18, 2023
5093637
example: improved layout
Gustl22 Jan 19, 2023
ce9e3eb
example: preserve state across different players
Gustl22 Jan 19, 2023
1ec8bc1
example: better layout
Gustl22 Jan 19, 2023
7865abe
example: better layout
Gustl22 Jan 19, 2023
348b511
example: extract widgets
Gustl22 Jan 19, 2023
fa8e98a
example: style toggles
Gustl22 Jan 19, 2023
7ec8ad8
example: more styling
Gustl22 Jan 19, 2023
7a99aa9
example: format
Gustl22 Jan 19, 2023
d96df31
example: more states
Gustl22 Jan 19, 2023
6de057b
example: polish
Gustl22 Jan 19, 2023
c70e2eb
tests: fix check
Gustl22 Jan 19, 2023
4c3d33d
Merge branch 'gustl22/example-layout' into gustl22/android-soundpool
Gustl22 Jan 19, 2023
31b5828
feat: replace PlayerUiState with IndexedStack
Gustl22 Jan 19, 2023
b79b082
feat: minor layout improvements
Gustl22 Jan 20, 2023
db475be
example: fix dialog update
Gustl22 Jan 20, 2023
0cf17d2
example: fix onstage children for IndexedStack for tests
Gustl22 Jan 20, 2023
ba2e07d
example: fix small screensize for controls
Gustl22 Jan 20, 2023
c18e6c1
Merge branch 'gustl22/example-layout' into gustl22/android-soundpool
Gustl22 Jan 20, 2023
7eacaa4
Merge remote-tracking branch 'upstream/main' into gustl22/android-sou…
Gustl22 Jan 20, 2023
511dd77
feat(android): use getters for SoundPoolPlayer properties
Gustl22 Jan 20, 2023
1100f5f
feat(example): add and remove players
Gustl22 Jan 20, 2023
d0ed89d
feat: example scroll players
Gustl22 Jan 20, 2023
105a2e3
Merge branch 'gustl22/example-add-player' into gustl22/android-soundpool
Gustl22 Jan 20, 2023
129b4c0
fix: index outside of players range
Gustl22 Jan 20, 2023
80143be
Merge branch 'gustl22/example-add-player' into gustl22/android-soundpool
Gustl22 Jan 20, 2023
7dd7c94
docs: AudioContext
Gustl22 Jan 21, 2023
050ec00
docs: AudioContext
Gustl22 Jan 21, 2023
34a55a9
docs: AudioContext
Gustl22 Jan 21, 2023
10b2e01
docs: AudioContext
Gustl22 Jan 21, 2023
ebcce4e
make MAX_STREAMS private
Gustl22 Jan 21, 2023
1cbb6bf
Merge remote-tracking branch 'upstream/main' into gustl22/android-sou…
Gustl22 Jan 21, 2023
a87d90b
feat: only create soundPool on different AudioAttributes
Gustl22 Jan 21, 2023
866eed2
docs: some docs for SoundPool
Gustl22 Jan 21, 2023
18381a3
flutter format
Gustl22 Jan 21, 2023
44c8e18
more docs and more meaningful tests
Gustl22 Jan 21, 2023
3dc3e42
flutter format
Gustl22 Jan 21, 2023
ebf8adf
Merge branch 'gustl22/android-soundpool' into gustl22/1266-error-stream
Gustl22 Jan 21, 2023
8f65642
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Jan 21, 2023
6e26bee
feat: logs via EventChannel
Gustl22 Jan 22, 2023
e1ebc46
feat: differentiate Log and Error
Gustl22 Jan 23, 2023
fd54ef4
feat: single event channels
Gustl22 Jan 23, 2023
58f4dc2
feat: apply event channel to all callback events
Gustl22 Jan 24, 2023
5bdfbf8
feat: format, some doc
Gustl22 Jan 24, 2023
4e2c312
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Jan 29, 2023
6d4108c
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Feb 11, 2023
24628a7
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Feb 25, 2023
3ce0722
feat(android): clean up
Gustl22 Feb 25, 2023
bb457ca
feat(web): eventStream
Gustl22 Feb 25, 2023
9dd2b62
feat(web): make properties private
Gustl22 Feb 25, 2023
9de9425
feat(windows): event stream channel
Gustl22 Feb 26, 2023
ce652d6
feat(windows): createPlayer
Gustl22 Feb 26, 2023
f3cf552
feat(windows): format
Gustl22 Feb 26, 2023
8da0153
feat(windows): player event channels
Gustl22 Feb 26, 2023
7d629b0
feat(windows): rename channel to methodChannel, format
Gustl22 Feb 27, 2023
7fa05a5
feat(android): differentiate method and event channel
Gustl22 Feb 27, 2023
736023c
feat(windows): format
Gustl22 Feb 27, 2023
48c4555
feat(windows): format + refactor
Gustl22 Feb 27, 2023
40b78bd
feat(windows): extract event_stream_handler
Gustl22 Feb 28, 2023
38863e5
feat(windows): small refactor
Gustl22 Feb 28, 2023
3a676df
fix(windows): handle success
Gustl22 Feb 28, 2023
723e398
fix(windows): handle success
Gustl22 Feb 28, 2023
7378693
feat(windows): logs
Gustl22 Feb 28, 2023
f91d821
feat: handle stackTrace and error
Gustl22 Mar 1, 2023
750f119
feat: track down error handling
Gustl22 Mar 2, 2023
e617855
feat: track down error handling
Gustl22 Mar 2, 2023
3948273
feat(windows): improve messages for caching nuget
Gustl22 Mar 2, 2023
8ca64e3
feat(windows): improve messages for caching nuget
Gustl22 Mar 2, 2023
5bf0aab
fix: tests for error stream
Gustl22 Mar 2, 2023
461e559
fix: tests for error stream
Gustl22 Mar 2, 2023
3cac3ba
fix(web): call resume asynchronously
Gustl22 Mar 2, 2023
0ade4b2
test(web): test for error during method call
Gustl22 Mar 2, 2023
4dd6b40
feat(linux): convert log to error response
Gustl22 Mar 10, 2023
43dd295
feat(linux): refactor channel to methods
Gustl22 Mar 10, 2023
899b810
feat(linux): save binaryMessenger statically
Gustl22 Mar 10, 2023
9e0c778
feat(linux): global: remove changeLogLevel, add setGlobalAudioContext
Gustl22 Mar 10, 2023
a8b96f6
feat(linux): initialize globalEvents
Gustl22 Mar 10, 2023
3d59aa7
feat(linux): event channel for player instances
Gustl22 Mar 10, 2023
72268d7
feat(linux): fix signatur
Gustl22 Mar 11, 2023
591f993
feat(windows): make _eventHandler private
Gustl22 Mar 11, 2023
fa0d257
feat(linux): apply event channel to player
Gustl22 Mar 11, 2023
65508e9
feat(linux): format
Gustl22 Mar 11, 2023
142eaf6
feat(windows): readd methodChannel, format
Gustl22 Mar 11, 2023
2d0b5cd
feat(darwin): WIP add event channel
Gustl22 Mar 11, 2023
5d26f16
feat(android): log, globalLog, debugError, debugGlobalError
Gustl22 Mar 11, 2023
a996f29
feat: log, globalLog, debugError, debugGlobalError
Gustl22 Mar 11, 2023
8f4a166
feat: separate global channel from player
Gustl22 Mar 12, 2023
ab1bed5
mock dom exception, fix global stream
Gustl22 Mar 12, 2023
e9e53b4
test: emitLog, emitError
Gustl22 Mar 13, 2023
0c53be9
fix(web): emitLog, emitError
Gustl22 Mar 13, 2023
70dd33a
adapt example
Gustl22 Mar 14, 2023
b8634de
make GlobalAudioPlayer public
Gustl22 Mar 14, 2023
7d21fe9
feat(linux): emitLog, emitError
Gustl22 Mar 14, 2023
a122a9e
feat(linux): throw errors
Gustl22 Mar 14, 2023
659b434
feat(linux): update initialization
Gustl22 Mar 14, 2023
8b982b6
feat(linux): set to GstState_Paused on initialization
Gustl22 Mar 14, 2023
8a49ec6
fix(linux): playback end
Gustl22 Mar 14, 2023
d7bf4e9
fix(linux): playback end
Gustl22 Mar 14, 2023
59ee793
fix(linux): playback end
Gustl22 Mar 14, 2023
ac4ef8d
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Mar 14, 2023
ae274e2
fix tests
Gustl22 Mar 14, 2023
f844b94
feat(android): emitError, emitLog
Gustl22 Mar 14, 2023
caad137
try catch errors on creation
Gustl22 Mar 14, 2023
496a0f9
refactor: currentPosition to position
Gustl22 Mar 15, 2023
1766c65
test: emitLog, emitError via Platform
Gustl22 Mar 15, 2023
980ce0e
test: emitLog, emitError via Platform
Gustl22 Mar 15, 2023
f3667e9
Revert "refactor: currentPosition to position"
Gustl22 Mar 16, 2023
537283e
fix revert 496a0f9deceb4e66bd63285c5b321ba2dfb16460
Gustl22 Mar 16, 2023
ef7dea8
feat: improve log handling
Gustl22 Mar 16, 2023
9e2d0fc
feat: always print log events unless setting `Logger.logLevel = LogLe…
Gustl22 Mar 16, 2023
4112d6a
fix tests
Gustl22 Mar 16, 2023
0b0d7d8
feat: readd deprected `changeLogLevel`
Gustl22 Mar 16, 2023
dac66b6
feat: use defaultTargetPlatform to determine platform
Gustl22 Mar 16, 2023
447062d
test: Logger, MethodChannel for AudioContext
Gustl22 Mar 16, 2023
daddc08
test: replace deprecated functions
Gustl22 Mar 16, 2023
686a0d9
feat: move tests to audioplayers package
Gustl22 Mar 16, 2023
5d0af09
feat: test method and event channels
Gustl22 Mar 17, 2023
01f8c5a
remove hasMp2SourceType
Gustl22 Mar 17, 2023
116d1ff
test: improve platform test strategy
Gustl22 Mar 17, 2023
295042a
test: add test util
Gustl22 Mar 17, 2023
6afd424
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Mar 17, 2023
6914f4d
Merge branch 'main' into gustl22/1266-error-stream
Gustl22 Mar 17, 2023
e584728
Merge branch 'main' into gustl22/1266-error-stream
Gustl22 Mar 17, 2023
9d40c8d
chore(ios): update generated files
Gustl22 Mar 17, 2023
627e309
feat(ios): update binaryMessenger
Gustl22 Mar 17, 2023
ec6feca
feat(ios): update binaryMessenger
Gustl22 Mar 17, 2023
b1e5246
chore(ios): fix some errors
Gustl22 Mar 17, 2023
dbdb126
feat(ios): update
Gustl22 Mar 17, 2023
43fd9a1
chore(ios): separate global method channel
Gustl22 Mar 17, 2023
bb1dd73
chore(ios): implement event stream
Gustl22 Mar 17, 2023
e333509
feat(ios): attempt to handle parsing AudioContext
Gustl22 Mar 17, 2023
17d480b
chore(ios): fix error handling
Gustl22 Mar 18, 2023
3fdd982
rename audio.onGlobalLog to audio.onLog in global event channel
Gustl22 Mar 18, 2023
71600eb
flutter format
Gustl22 Mar 18, 2023
081d159
flutter analyze
Gustl22 Mar 18, 2023
a526539
fix(ios): try in AudioContext
Gustl22 Mar 18, 2023
ace8747
test: disable test again
Gustl22 Mar 18, 2023
4db8d2c
add FakeGlobalAudioplayersPlatform
Gustl22 Mar 18, 2023
106e63b
feat: reorganizing, refactor platform interface
Gustl22 Mar 18, 2023
9c30239
feat: reorganizing packages
Gustl22 Mar 18, 2023
3338806
feat: split audio_context from audio_context_config
Gustl22 Mar 18, 2023
9f2a231
feat: move audio_context_config to audioplayers
Gustl22 Mar 18, 2023
c4e2ee7
fix(web): adapt to reorganizing imports
Gustl22 Mar 18, 2023
6d626cb
flutter analyze + flutter format
Gustl22 Mar 18, 2023
eefd028
feat: move audio_context_config back
Gustl22 Mar 18, 2023
9c67c33
merge with main
Gustl22 Mar 18, 2023
9e08495
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Mar 20, 2023
83d2456
refactor!: rename GlobalAudioPlayer to GlobalAudioScope
Gustl22 Mar 20, 2023
5f8965b
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Mar 20, 2023
229a124
revert linking AudioPlayers class without importing it
Gustl22 Mar 20, 2023
3043cf1
test: replace MethodChannel mock with FakeAudioPlayersPlatform, globa…
Gustl22 Mar 20, 2023
f4d3ee4
feat: replace `Platform.isX` with `defaultTargetPlatform`
Gustl22 Mar 20, 2023
3888b0b
Merge branch 'gustl22/defaultTargetPlatform' into gustl22/fake-platform
Gustl22 Mar 20, 2023
2b3b529
fix tests
Gustl22 Mar 20, 2023
2c66248
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Mar 20, 2023
2dbac65
fix merge
Gustl22 Mar 20, 2023
24cca72
Merge branch 'main' into gustl22/fake-platform
Gustl22 Mar 20, 2023
87546b5
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Mar 20, 2023
3f56f36
feat: split platform tests from audioplayers tests
Gustl22 Mar 21, 2023
2a4d009
test: move to platform interface
Gustl22 Mar 21, 2023
8b5aa2c
fix: always take actual platform instance
Gustl22 Mar 21, 2023
0a2190e
fix: separate platform calls from `audioplayers` package
Gustl22 Mar 21, 2023
0699b45
flutter analyze + flutter format
Gustl22 Mar 21, 2023
6ba5060
test for default values in AudioContext
Gustl22 Mar 21, 2023
d8af21e
Merge branch 'gustl22/fake-platform' into gustl22/1266-error-stream
Gustl22 Mar 21, 2023
0ae00a4
test: fix for platform interface
Gustl22 Mar 21, 2023
5182c29
test platform event channels
Gustl22 Mar 21, 2023
f6781b7
test: split tests, add missing tests
Gustl22 Mar 21, 2023
9e06d23
test: handle global scope
Gustl22 Mar 21, 2023
44c6578
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Mar 21, 2023
af16d09
feat(windows): error message on windows
Gustl22 Mar 22, 2023
0ca3c4a
Merge remote-tracking branch 'upstream/main' into gustl22/1266-error-…
Gustl22 Mar 23, 2023
ad93ccb
feat: readd deprecated logLevel to GlobalAudioScope
Gustl22 Mar 24, 2023
2235d89
feat: adapt Platform error codes
Gustl22 Mar 24, 2023
a2d5418
fix: remove unsed MethodArguments
Gustl22 Mar 24, 2023
b1a717a
fix(web): hand over position value on position event
Gustl22 Mar 24, 2023
f400625
Merge branch 'gustl22/1266-error-stream' of https://github.com/bluefi…
Gustl22 Mar 24, 2023
b97bf5e
chore: make audioplayers_platform_interface a dev dependency
Gustl22 Apr 3, 2023
56bde56
feat: make create method private
Gustl22 Apr 3, 2023
6e436ec
feat: throw on invalid lovLevel value in fromInt
Gustl22 Apr 3, 2023
12241dc
docs: adapt wrong logMessage docs
Gustl22 Apr 3, 2023
c632015
chore: add deprecation notice vor v5.0.0
Gustl22 Apr 3, 2023
c9d8609
dart format .
Gustl22 Apr 3, 2023
1b34fb0
feat: improve deprecation line breaking
Gustl22 Apr 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions getting_started.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ Normally you want to use `.mediaPlayer` unless you care about performance and yo
You can globally control the amount of log messages that are emitted by this package:

```dart
await AudioPlayer.global.changeLogLevel(LogLevel.info);
AudioPlayer.logger.logLevel = LogLevel.info;
```

You can pick one of 3 options:
Expand All @@ -173,6 +173,25 @@ You can pick one of 3 options:

**Note**: despite our best efforts, some native SDK implementations that we use spam a lot of log messages that we currently haven't figured out how to conform to this configuration (specially noticeable on Android). If you would like to contribute with a PR, they are more than welcome!

### Log handler

The log events are handled by default via `AudioPlayer.logger.log()`.
Gustl22 marked this conversation as resolved.
Show resolved Hide resolved
You can customize the behavior of player log events.
Gustl22 marked this conversation as resolved.
Show resolved Hide resolved

```dart
player.setLogHandler((log) {
AudioPlayer.logger.log(log.level, log.message);
});
```

Or change the behavior of global log events.

```dart
AudioPlayer.setGlobalLogHandler((log) {
AudioPlayer.logger.log(log.level, log.message);
});
```

## Audio Context

An Audio Context is a (mostly mobile-specific) set of secondary, platform-specific aspects of audio playback, typically related to how the act of playing audio interacts with other features of the device. In most cases, you do not need to change this.
Expand Down Expand Up @@ -241,7 +260,7 @@ This Event is called when the audio finishes playing; it's used in the loop meth
It does not fire when you interrupt the audio with pause or stop.

```dart
player.onPlayerComplete.listen((event) {
player.onPlayerComplete.listen((_) {
onComplete();
setState(() {
position = duration;
Expand Down
Binary file not shown.
107 changes: 59 additions & 48 deletions packages/audioplayers/example/integration_test/lib_test.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'dart:io';
import 'dart:async';

import 'package:audioplayers/audioplayers.dart';
import 'package:audioplayers_example/tabs/sources.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';

Expand All @@ -14,52 +13,52 @@ void main() {

IntegrationTestWidgetsFlutterBinding.ensureInitialized();

group('play multiple sources', () {
final audioTestDataList = [
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(wavUrl1),
duration: const Duration(milliseconds: 451),
),
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(wavUrl2),
duration: const Duration(seconds: 1, milliseconds: 068),
),
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(mp3Url1),
duration: const Duration(minutes: 3, seconds: 30, milliseconds: 77),
),
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(mp3Url2),
duration: const Duration(minutes: 1, seconds: 34, milliseconds: 119),
),
if (features.hasUrlSource && features.hasPlaylistSourceType)
LibSourceTestData(
source: UrlSource(m3u8StreamUrl),
duration: Duration.zero,
isLiveStream: true,
),
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(mpgaStreamUrl),
duration: Duration.zero,
isLiveStream: true,
),
if (features.hasAssetSource)
LibSourceTestData(
source: AssetSource(asset1),
duration: const Duration(seconds: 1, milliseconds: 068),
),
if (features.hasAssetSource)
LibSourceTestData(
source: AssetSource(asset2),
duration: const Duration(minutes: 1, seconds: 34, milliseconds: 119),
),
];
final audioTestDataList = [
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(wavUrl1),
duration: const Duration(milliseconds: 451),
),
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(wavUrl2),
duration: const Duration(seconds: 1, milliseconds: 068),
),
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(mp3Url1),
duration: const Duration(minutes: 3, seconds: 30, milliseconds: 77),
),
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(mp3Url2),
duration: const Duration(minutes: 1, seconds: 34, milliseconds: 119),
),
if (features.hasUrlSource && features.hasPlaylistSourceType)
LibSourceTestData(
source: UrlSource(m3u8StreamUrl),
duration: Duration.zero,
isLiveStream: true,
),
if (features.hasUrlSource)
LibSourceTestData(
source: UrlSource(mpgaStreamUrl),
duration: Duration.zero,
isLiveStream: true,
),
if (features.hasAssetSource)
LibSourceTestData(
source: AssetSource(asset1),
duration: const Duration(seconds: 1, milliseconds: 068),
),
if (features.hasAssetSource)
LibSourceTestData(
source: AssetSource(asset2),
duration: const Duration(minutes: 1, seconds: 34, milliseconds: 119),
),
];

group('play multiple sources', () {
testWidgets(
'play multiple sources simultaneously',
(WidgetTester tester) async {
Expand Down Expand Up @@ -88,7 +87,7 @@ void main() {
// FIXME: Causes media error on Android (see #1333, #1353)
// Unexpected platform error: MediaPlayer error with
// what:MEDIA_ERROR_UNKNOWN {what:1} extra:MEDIA_ERROR_SYSTEM
skip: !kIsWeb && Platform.isAndroid,
// skip: !kIsWeb && Platform.isAndroid,
);

testWidgets('play multiple sources consecutively',
Expand All @@ -111,4 +110,16 @@ void main() {
}
});
});

group('Logging', () {
testWidgets('Platforms show INFO log, when start playing', (tester) async {
final completer = Completer<Log>();
final player = AudioPlayer();
player.setLogHandler(completer.complete);
await player.play(audioTestDataList[0].source);
final log = await completer.future;
expect(log.level, LogLevel.info);
expect(log.message, 'RESUME');
});
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class PlatformFeatures {
static const androidPlatformFeatures = PlatformFeatures(
hasRecordingActive: false,
hasBalance: false,
hasMp2SourceType: false,
);

static const iosPlatformFeatures = PlatformFeatures(
Expand Down Expand Up @@ -75,6 +76,7 @@ class PlatformFeatures {
final bool hasBytesSource;

final bool hasPlaylistSourceType;
final bool hasMp2SourceType;

final bool hasLowLatency;
final bool hasReleaseModeRelease;
Expand All @@ -101,6 +103,7 @@ class PlatformFeatures {
this.hasAssetSource = true,
this.hasBytesSource = true,
this.hasPlaylistSourceType = true,
this.hasMp2SourceType = true,
this.hasLowLatency = true,
this.hasReleaseModeRelease = true,
this.hasReleaseModeLoop = true,
Expand Down
2 changes: 1 addition & 1 deletion packages/audioplayers/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class _ExampleAppState extends State<ExampleApp> {
TabData(
key: 'loggerTab',
label: 'Log',
content: const LoggerTab(),
content: LoggerTab(player: selectedPlayer),
),
],
),
Expand Down
140 changes: 121 additions & 19 deletions packages/audioplayers/example/lib/tabs/logger.dart
Original file line number Diff line number Diff line change
@@ -1,38 +1,140 @@
import 'package:audioplayers/audioplayers.dart';
import 'package:audioplayers_example/components/btn.dart';
import 'package:audioplayers_example/components/tab_wrapper.dart';
import 'package:flutter/material.dart';

class LoggerTab extends StatefulWidget {
const LoggerTab({super.key});
final AudioPlayer player;

const LoggerTab({super.key, required this.player});

@override
_LoggerTabState createState() => _LoggerTabState();
}

class _LoggerTabState extends State<LoggerTab> {
static GlobalPlatformInterface get _logger => AudioPlayer.global;
class _LoggerTabState extends State<LoggerTab>
with AutomaticKeepAliveClientMixin<LoggerTab> {
static Logger get _logger => AudioPlayer.logger;

LogLevel currentLogLevel = LogLevel.info;

List<Log> logs = [];
List<Log> globalLogs = [];

@override
void initState() {
super.initState();
_logger.logLevel = currentLogLevel;
AudioPlayer.setGlobalLogHandler((log) {
if (log.level.toInt() <= currentLogLevel.toInt()) {
_logger.log(log.level, log.message);
setState(() {
globalLogs.add(log);
});
}
});
widget.player.setLogHandler((log) {
if (log.level.toInt() <= currentLogLevel.toInt()) {
final msg = '${log.message}\nSource: ${widget.player.source}';
_logger.log(log.level, msg);
setState(() {
logs.add(Log(msg, level: log.level));
});
}
});
}

@override
Widget build(BuildContext context) {
super.build(context);
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
Text('Log Level: $currentLogLevel'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: LogLevel.values
.map(
(level) => Btn(
txt: level.toString().replaceAll('LogLevel.', ''),
onPressed: () {
_logger.logLevel = level;
setState(() => currentLogLevel = _logger.logLevel);
},
),
)
.toList(),
),
const Divider(color: Colors.black),
Expanded(
child: LogView(
title: 'Player Logs:',
logs: logs,
onDelete: () => setState(() {
logs.clear();
}),
),
),
const Divider(color: Colors.black),
Expanded(
child: LogView(
title: 'Global Logs:',
logs: globalLogs,
onDelete: () => setState(() {
globalLogs.clear();
}),
),
),
],
),
);
}

@override
bool get wantKeepAlive => true;
}

class LogView extends StatelessWidget {
final String title;
final List<Log> logs;
final VoidCallback onDelete;

LogLevel currentLogLevel = _logger.logLevel;
const LogView({
super.key,
required this.logs,
required this.title,
required this.onDelete,
});

@override
Widget build(BuildContext context) {
return TabWrapper(
return Column(
children: [
Text('Log Level: $currentLogLevel'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: LogLevel.values
.map(
(e) => Btn(
txt: e.toString().replaceAll('LogLevel.', ''),
onPressed: () async {
await _logger.changeLogLevel(e);
setState(() => currentLogLevel = _logger.logLevel);
},
),
)
.toList(),
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title),
IconButton(onPressed: onDelete, icon: const Icon(Icons.delete))
],
),
Expanded(
child: ListView(
children: logs
.map(
(log) => Column(
children: [
SelectableText(
'${log.level.toString()}: ${log.message}',
style: log.level == LogLevel.error
? const TextStyle(color: Colors.red)
: null,
),
Divider(color: Colors.grey.shade400)
],
),
)
.toList(),
),
),
],
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import 'dart:async';

import 'package:audioplayers_platform_interface/api/log_level.dart';
import 'package:audioplayers_platform_interface/logger_platform_interface.dart';
import 'package:audioplayers_platform_interface/api/log.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

Expand All @@ -16,7 +15,6 @@ void main() {
});

final _print = OverridePrint();
final _logger = GlobalPlatformInterface.instance;

group('Logger', () {
setUp(_print.clear);
Expand Down
Loading