audioplayers icon indicating copy to clipboard operation
audioplayers copied to clipboard

[Android] lib tests fail on CI with `what:MEDIA_ERROR_UNKNOWN {what:1} extra:MEDIA_ERROR_SYSTEM`

Open Gustl22 opened this issue 2 years ago • 5 comments

Checklist

  • [x] I read the troubleshooting guide before raising this issue
  • [x] I made sure that the issue I am raising doesn't already exist

Lib tests fail with what:MEDIA_ERROR_UNKNOWN {what:1} extra:MEDIA_ERROR_SYSTEM, but only on the CI. If testing locally with several machines and emulators, everything is working fine.

Current bug behaviour

Test play multiple sources simultaneously fails with Unexpected platform error: MediaPlayer error with what:MEDIA_ERROR_UNKNOWN {what:1} extra:MEDIA_ERROR_SYSTEM.

Expected behaviour

The tests should not fail.

Steps to reproduce

Execute lib tests play multiple sources simultaneously of #1333 in the Github CI

Code sample
import 'dart:io';

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';

import 'platform_features.dart';
import 'source_test_data.dart';

void main() {
  final features = PlatformFeatures.instance();

  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),
        ),
    ];

    testWidgets(
      'play multiple sources simultaneously',
      (WidgetTester tester) async {
        final players =
            List.generate(audioTestDataList.length, (_) => AudioPlayer());

        // Start all players simultaneously
        final iterator = List<int>.generate(audioTestDataList.length, (i) => i);
        await Future.wait<void>(
          iterator.map((i) => players[i].play(audioTestDataList[i].source)),
        );
        await tester.pumpAndSettle();
        // Sources take some time to get initialized
        await tester.pump(const Duration(seconds: 8));
        for (var i = 0; i < audioTestDataList.length; i++) {
          final td = audioTestDataList[i];
          if (td.isLiveStream || td.duration > const Duration(seconds: 10)) {
            await tester.pump();
            final position = await players[i].getCurrentPosition();
            printOnFailure('Test position: $td');
            expect(position, greaterThan(Duration.zero));
          }
          await players[i].stop();
        }
      },
    );
  });
}

Logs

https://github.com/bluefireteam/audioplayers/actions/runs/3750597674/jobs/6370516969#step:11:182

Audio Files/URLs/Sources

  • Different sources of example

Screenshots

Environment information

  • audioplayers version: 1.1.1 / current master

Platform 1: android

  • OS name and version: Android API 30
  • Device: Emulator
  • build mode: debug
  • error peculiarities (optional):

Platforms tested without any issue (optional):

  • test peculiarities:

More information

Gustl22 avatar Dec 23 '22 11:12 Gustl22

I got the same error when I played the sound rapidly and simultaneously about 100ms delay with a 300ms duration sound, I use AudioPool from flame_audio btw

https://user-images.githubusercontent.com/31397565/228910533-3d35f578-a2fc-4833-a8cf-6269a0becff0.mp4

Minimal reproducible code

import 'package:flame_audio/audio_pool.dart'; 
import 'package:flame_audio/flame_audio.dart'; 
import 'package:gunslinger/utils/extensions.dart'; 

 import '../r.dart'; 

 class AudioController { 
   late AudioPool _bulletShot; 

   AudioController() { 
     _loadShootSfxAudio(); 
   } 

   void _loadShootSfxAudio() async {
     _bulletShot = await FlameAudio.createPool( 
       AssetAudio.bulletShot.fileName, 
       minPlayers: 3, 
       maxPlayers: 4, 
     ); 
   } 

   Future<void> playBulletShotSfx() { 
     return _bulletShot.start( 
       volume: 0.8, 
     ); 
   } 
 }

And this is the crash log I got from my android phone crash log dialog

E/AndroidRuntime(21426): FATAL EXCEPTION: main
E/AndroidRuntime(21426): Process: com.example.gunslinger, PID: 21426
E/AndroidRuntime(21426): java.lang.IllegalStateException
E/AndroidRuntime(21426):        at android.media.MediaPlayer._prepare(Native Method)
E/AndroidRuntime(21426):        at android.media.MediaPlayer.prepare(MediaPlayer.java:1315)
E/AndroidRuntime(21426):        at z0.i.j(Unknown Source:2)
E/AndroidRuntime(21426):        at z0.o.J(Unknown Source:52)
E/AndroidRuntime(21426):        at z0.o.v(Unknown Source:6)
E/AndroidRuntime(21426):        at z0.i.x(Unknown Source:5)
E/AndroidRuntime(21426):        at z0.i.r(Unknown Source:0)
E/AndroidRuntime(21426):        at z0.e.onCompletion(Unknown Source:2)
E/AndroidRuntime(21426):        at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:3556)
E/AndroidRuntime(21426):        at android.os.Handler.dispatchMessage(Handler.java:106)
E/AndroidRuntime(21426):        at android.os.Looper.loopOnce(Looper.java:210)
E/AndroidRuntime(21426):        at android.os.Looper.loop(Looper.java:299)
E/AndroidRuntime(21426):        at android.app.ActivityThread.main(ActivityThread.java:8116)
E/AndroidRuntime(21426):        at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(21426):        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:559)
E/AndroidRuntime(21426):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
I/flutter (21426): Unexpected platform error: MediaPlayer error with what:MEDIA_ERROR_UNKNOWN {what:1} extra:MEDIA_ERROR_UNKNOWN {extra:-19}

What I already tried :

  • Use different audio format such as like .mp3 .ogg .wav
  • Trim the duration of the audio
  • Compress the file size of the audio file (in case if it is a memory problem)
  • Add more player to AudioPool around 24 and more

yasfdany avatar Mar 30 '23 17:03 yasfdany

@yasfdany Are you sure this isn't fixed with #1425 This fix isn't released yet, but can be tried with this in pubspec file: https://github.com/bluefireteam/audioplayers/pull/1425#issuecomment-1433639294 Note the difference in the extra code: extra:MEDIA_ERROR_UNKNOWN {extra:-19} vs extra:MEDIA_ERROR_SYSTEM . Probably you use an audio file which is not supported by android, despite its file extension.

Gustl22 avatar Mar 30 '23 18:03 Gustl22

@Gustl22 i tried the above solution and change format of audio to m4a, and the crash still happen, but the difference is the audio more stable not slow down when there're so many object on the sceeen.

yasfdany avatar Mar 31 '23 05:03 yasfdany

I too am receiving this issue and the latest fixes in #1425 haven't helped. Now, I'm no expert on Kotlin or this library, however: I have been doing some digging and can see the _createNewAudioPlayer() in audioplayers/lib/src/audio_pool.dart does not specify playerMode.lowLatency which defaults the AudioPool to a standard MediaPlayerPlayer rather than a SoundPoolPlayer which would be more suited to a rapid fire sfx succession.

Adding the following to _createNewAudioPlayer() seems to solve the issue for me: await player.setPlayerMode(PlayerMode.lowLatency);

cameronbatty avatar May 07 '23 08:05 cameronbatty

@cameronbatty yes, that would be a good addition, to be also able to set the playerMode in the AudioPool. Wanna make a PR?

Gustl22 avatar May 08 '23 10:05 Gustl22