A Flutter plugin to play multiple audio files simultaneously (Android/iOS)

Overview

AudioPlayers

Pub Build Status Discord

A Flutter plugin to play multiple simultaneously audio files, works for Android, iOS, macOS and web.

Contributing

We now have new rules for contributing!

All help is appreciated but if you have questions, bug reports, issues, feature requests, pull requests, etc, please first refer to our Contributing Guide.

Also, as always, please give us a star to help!

Support us

You can support us by becoming a patron on Patreon, any support is much appreciated.

Patreon

Feature Parity Table

Not all features are available on all platforms. Click here to see a table relating what features can be used on each target.

Feel free to use it for ideas for possible PRs and contributions you can help with on our roadmap! If you are submiting a PR, don't forget to update the table.

Usage

An AudioPlayer instance can play a single audio at a time. To create it, simply call the constructor:

    AudioPlayer audioPlayer = AudioPlayer();

To use the low latency API, better for gaming sounds, use:

    AudioPlayer audioPlayer = AudioPlayer(mode: PlayerMode.LOW_LATENCY);

In this mode the backend won't fire any duration or position updates. Also, it is not possible to use the seek method to set the audio a specific position. This mode is also not available on web.

You can create multiple instances to play audio simultaneously.

For all methods that return a Future<int>: that's the status of the operation. If 1, the operation was successful. Otherwise, it's the platform native error code.

Logs are disable by default! To debug, run:

  AudioPlayer.logEnabled = true;

Playing Audio

There are four possible sources of audio:

  • Remote file on the Internet
  • Local file on the user's device
  • Local asset from your Flutter project
  • Audio in the form of a byte array (in Flutter, Uint8List)

Both for Remote Files or Local Files, use the play method, just setting appropriately the flag isLocal.

For Local Assets, you have to use the AudioCache class (see below).

To play a Remote File, just call play with the url (the isLocal parameter is false by default):

If you want to play audio for a long period of time, you need to set appropriately the flag stayAwake, If you pass stayAwake as true you need to add this permission to your app manifest: <uses-permission android:name="android.permission.WAKE_LOCK" />.

  play() async {
    int result = await audioPlayer.play(url);
    if (result == 1) {
      // success
    }
  }

For a Local File, add the isLocal parameter:

  playLocal() async {
    int result = await audioPlayer.play(localPath, isLocal: true);
  }

To play a file in the form of a data buffer (Uint8List), use the method playBytes. This currently only works for Android (requiring API >= 23, be sure to handle that if you use this method on your code).

  playLocal() async {
    Uint8List byteData = .. // Load audio as a byte array here.
    int result = await audioPlayer.playBytes(byteData);
  }

The isLocal flag is required only because iOS and macOS make a difference about it (Android doesn't care either way).

There is also an optional named double volume parameter, that defaults to 1.0. It can go from 0.0 (mute) to 1.0 (max), varying linearly.

The volume can also be changed at any time using the setVolume method.

Controlling

Note: these features are not implemented in web yet.

After playing, you can control the audio with pause, stop and seek commands.

Pause will pause the audio but keep the cursor where it was. Subsequently calling play will resume from this point.

  int result = await audioPlayer.pause();

Stop will stop the audio and reset the cursor. Subsequently calling play will resume from the beginning.

  int result = await audioPlayer.stop();

Finally, use seek to jump through your audio:

  int result = await audioPlayer.seek(Duration(milliseconds: 1200));

Also, you can resume (like play, but without new parameters):

  int result = await audioPlayer.resume();

Finer Control

By default, the player will be release once the playback is finished or the stop method is called.

This is because on Android, a MediaPlayer instance can be quite resource-heavy, and keep it unreleased would cause performance issues if you play lots of different audios.

On iOS and macOS this doesn't apply, so release does nothing.

You can change the Release Mode to determine the actual behavior of the MediaPlayer once finished/stopped. There are three options:

  • RELEASE: default mode, will release after stop/completed.
  • STOP: will never release; calling play should be faster.
  • LOOP: will never release; after completed, it will start playing again on loop.

If you are not on RELEASE mode, you should call the release method yourself; for example:

  await audioPlayer.setUrl('clicking.mp3'); // prepare the player with this audio but do not start playing
  await audioPlayer.setReleaseMode(ReleaseMode.STOP); // set release mode so that it never releases

  // on button click
  await audioPlayer.resume(); // quickly plays the sound, will not release

  // on exiting screen
  await audioPlayer.release(); // manually release when no longer needed

Despite the complex state diagram of Android's MediaPlayer, an AudioPlayer instance should never have an invalid state. Even if it's released, if resume is called, the data will be fetch again.

Stream routing

You can choose between speakers and earpiece. By default using speakers. Toggle between speakers and earpiece.

int result = await player.earpieceOrSpeakersToggle();

Streams

Note: streams are not available on web yet.

The AudioPlayer supports subscribing to events like so:

Duration Event

This event returns the duration of the file, when it's available (it might take a while because it's being downloaded or buffered).

  player.onDurationChanged.listen((Duration d) {
    print('Max duration: $d');
    setState(() => duration = d);
  });

Position Event

This Event updates the current position of the audio. You can use it to make a progress bar, for instance.

  player.onAudioPositionChanged.listen((Duration  p) => {
    print('Current position: $p');
    setState(() => position = p);
  });

State Event

This Event returns the current player state. You can use it to show if player playing, or stopped, or paused.

  player.onPlayerStateChanged.listen((PlayerState s) => {
    print('Current player state: $s');
    setState(() => playerState = s);
  });

Completion Event

This Event is called when the audio finishes playing; it's used in the loop method, for instance.

It does not fire when you interrupt the audio with pause or stop.

  player.onPlayerCompletion.listen((event) {
    onComplete();
    setState(() {
      position = duration;
    });
  });

Error Event

This is called when an unexpected error is thrown in the native code.

  player.onPlayerError.listen((msg) {
    print('audioPlayer error : $msg');
    setState(() {
      playerState = PlayerState.stopped;
      duration = Duration(seconds: 0);
      position = Duration(seconds: 0);
    });
  });

AudioCache

In order to play Local Assets, you must use the AudioCache class. AudioCache is not available for Flutter Web.

Flutter does not provide an easy way to play audio on your assets, but this class helps a lot. It actually copies the asset to a temporary folder in the device, where it is then played as a Local File.

It works as a cache because it keeps track of the copied files so that you can replay them without delay.

You can find the full documentation for this class here.

playerId

By default, each time you initialize a new instance of AudioPlayer a unique playerId is generated and assigned using uuid package, this is designed this way to play multiple audio files simultaneously, if you want to play using the same instance that was created before simply pass your playerId when creating a new AudioPlayer instance.

final audioPlayer = AudioPlayer(playerId: 'my_unique_playerId');

Supported Formats

You can check a list of supported formats below:

⚠️ iOS & macOS App Transport Security

By default iOS and macOS forbid loading from non-https url. To cancel this restriction on iOS or macOS you must edit your .plist and add:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

⚠️ macOS Outgoing Connections

By default, Flutter macOS apps don't allow outgoing connections, so playing audio files/streams from the internet won't work. To fix this, add the following to the .entitlements files for your app:

<key>com.apple.security.network.client</key>
<true/>

Note: On Android by default, there is a restriction not allowing traffic from HTTP resources. There is a fix for this and it requires adding android:usesCleartextTraffic="true" within your AndroidManifest.xml file located in android/app/src/main/AndroidManifest.xml.

Here is an example of how it should look like:

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

Android Support

Giving support to old Android devices is very hard, on this plugin we set the minSdk as 16, but we only ensure support >= 23 as that is the minimum version that the team has devices available to test changes and new features.

This mean that, Audioplayer should work on older devices, but we can't give any guarantees, we will not be able to look after issues regarding API < 23. But we would glady take any pull requests from the community that fixes or improve support on those old versions.

Background playing

To control playback from lock screen on iOS and Android you can use audio_service. Example how to implement all AudioPlayers features with and audio_service.

Credits

This was originally a fork of rxlabz's audioplayer, but since we have diverged and added more features.

Thanks for @rxlabz for the amazing work!

Comments
  • AudioplayersPlugin.h file not found

    AudioplayersPlugin.h file not found

    Hello, I'm writing here after checking the following old issues & sorry for the duplicates https://github.com/luanpotter/audioplayers/issues/237 https://github.com/luanpotter/audioplayers/issues/80 https://github.com/luanpotter/audioplayers/issues/101 https://github.com/luanpotter/audioplayers/issues/92

    Still can't generate an archive for iOs. When I launch Archive, it stops with the following error: ../ios/Runner/GeneratedPluginRegistrant.m:6:9: 'audioplayers/AudioplayersPlugin.h' file not found

    //
    //  Generated file. Do not edit.
    //
    
    #import "GeneratedPluginRegistrant.h"
    #import <audioplayers/AudioplayersPlugin.h>
    #import <connectivity/ConnectivityPlugin.h>
    #import <flutter_webview_plugin/FlutterWebviewPlugin.h>
    #import <onesignal_flutter/OneSignalPlugin.h>
    #import <path_provider/PathProviderPlugin.h>
    #import <share/SharePlugin.h>
    #import <shared_preferences/SharedPreferencesPlugin.h>
    #import <url_launcher/UrlLauncherPlugin.h>
    #import <video_player/VideoPlayerPlugin.h>
    #import <ytview/WebViewFlutterPlugin.h>
    
    @implementation GeneratedPluginRegistrant
    
    + (void)registerWithRegistry:(NSObject<FlutterPluginRegistry>*)registry {
      [AudioplayersPlugin registerWithRegistrar:[registry registrarForPlugin:@"AudioplayersPlugin"]];
      [FLTConnectivityPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTConnectivityPlugin"]];
      [FlutterWebviewPlugin registerWithRegistrar:[registry registrarForPlugin:@"FlutterWebviewPlugin"]];
      [OneSignalPlugin registerWithRegistrar:[registry registrarForPlugin:@"OneSignalPlugin"]];
      [FLTPathProviderPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTPathProviderPlugin"]];
      [FLTSharePlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTSharePlugin"]];
      [FLTSharedPreferencesPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTSharedPreferencesPlugin"]];
      [FLTUrlLauncherPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTUrlLauncherPlugin"]];
      [FLTVideoPlayerPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTVideoPlayerPlugin"]];
      [FLTWebViewFlutterPlugin registerWithRegistrar:[registry registrarForPlugin:@"FLTWebViewFlutterPlugin"]];
    }
    
    @end
    
    flutter doctor -v
    [✓] Flutter (Channel master, v1.9.8-pre.108, on Mac OS X 10.14.6 18G87, locale en-LB)
        • Flutter version 1.9.8-pre.108 at /Users/macbook/flutter
        • Framework revision 95168fcc03 (17 hours ago), 2019-09-06 00:05:40 -0400
        • Engine revision f4d930581c
        • Dart version 2.5.0 (build 2.5.0-dev.4.0 be66176534)
    
     
    [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
        • Android SDK at /Users/macbook/Library/Android/sdk
        • Android NDK location not configured (optional; useful for native profiling support)
        • Platform android-29, build-tools 29.0.2
        • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 10.3)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Xcode 10.3, Build version 10G8
        • CocoaPods version 1.7.5
    
    [✓] Android Studio (version 3.5)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin version 39.0.3
        • Dart plugin version 191.8423
        • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405)
    
    [!] Connected device
        ! No devices available
    
    ! Doctor found issues in 1 category.
    

    Note that I'm using the audioplayers: ^0.13.1 in pubspec.yaml. So is recommended to clone the master branch in github and then force the package to use it audioplayers: path: ../ or it doesn't matter?

    Any Idea please would be appreciated.

    opened by rabihmb 28
  • E/MediaPlayerNative( 6767): error (1, -2147483648)

    E/MediaPlayerNative( 6767): error (1, -2147483648)

    Code

    _player.play("https://file-examples.com/wp-content/uploads/2017/11/file_example_MP3_700KB.mp3");
    

    Error

    V/MediaHTTPService( 6767): MediaHTTPService(android.media.MediaHTTPService@d3e2288): Cookies: null
    V/MediaHTTPService( 6767): makeHTTPConnection: CookieHandler (java.net.CookieManager@976f522) exists.
    V/MediaHTTPService( 6767): makeHTTPConnection(android.media.MediaHTTPService@d3e2288): cookieHandler: java.net.CookieManager@976f522 Cookies: null
    E/MediaPlayerNative( 6767): error (1, -2147483648)
    E/MediaPlayer( 6767): Error (1,-2147483648)
    E/MediaPlayerNative( 6767): stop called in state 0, mPlayer(0xcc47d040)
    E/MediaPlayerNative( 6767): error (-38, 0)
    V/MediaPlayer( 6767): resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
    V/MediaPlayer( 6767): cleanDrmObj: mDrmObj=null mDrmSessionId=null
    V/MediaPlayer( 6767): resetDrmState:  mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
    V/MediaPlayer( 6767): cleanDrmObj: mDrmObj=null mDrmSessionId=null
    

    I even added usesCleartextTraffic in android manifest file

    opened by pacifio 27
  • Notification/lockscreen area for ios, playback speed, bug fix

    Notification/lockscreen area for ios, playback speed, bug fix

    Hi, I was working on some new features for my app and I thought I will merge the changes I made. There are few major features added and one bug fix.

    1. bug fix to https://github.com/luanpotter/audioplayers/issues/267

    2. Notification area/lock screen on ios. It works both ways - so the notification area can be controlled through the plugin/app and also any changes in the notification area like play/pause, forward/backward(by custom time intervals) will also be reflected in the app. The setNotification function can be called in onDurationChange(I added in example) so that after the audio has loaded, the notification will be set. ios_notification

    3. Change playback speed. This function can be called after play() or resume() or anytime the user in your app wants to change the playback speed.

    These features are only on ios for now. I am working on android and will be up in couple of weeks. Please let me know any issue and merge this soon as this might be useful to lot of others.

    changes-requested 
    opened by subhash279 27
  • why minSdkVersion set from 16 to 23

    why minSdkVersion set from 16 to 23

    We have used this plugin for a while. Recently, we need to upgrade the version because this plugin fixed some bugs on IOS. But i found that the android's minSdkVersion was set from 16 to 23 not long ago. Our app has many users whose Android system version is still in Android 5.0. So could you please downgrade the android's minSdkVersion ?

    opened by buaashuai 26
  • can't get my app to compile when using v0.17.1 of the package

    can't get my app to compile when using v0.17.1 of the package

    When attempting to build my app I got the following error:

    Launching lib\main.dart on SM A705FN in debug mode...
    Running Gradle task 'assembleDebug'...
    E:\flutter\flutter_course\xylophone\android\app\src\debug\AndroidManifest.xml Error:
    	uses-sdk:minSdkVersion 16 cannot be smaller than version 23 declared in library [:audioplayers] E:\flutter\flutter_course\xylophone\build\audioplayers\intermediates\library_manifest\debug\AndroidManifest.xml as the library might be using APIs not available in 16
    	Suggestion: use a compatible library with a minSdk of at most 16,
    		or increase this project's minSdk version to at least 23,
    		or use tools:overrideLibrary="xyz.luan.audioplayers" to force usage (may lead to runtime failures)
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':app:processDebugMainManifest'.
    > Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 23 declared in library [:audioplayers] E:\flutter\flutter_course\xylophone\build\audioplayers\intermediates\library_manifest\debug\AndroidManifest.xml as the library might be using APIs not available in 16
      	Suggestion: use a compatible library with a minSdk of at most 16,
      		or increase this project's minSdk version to at least 23,
      		or use tools:overrideLibrary="xyz.luan.audioplayers" to force usage (may lead to runtime failures)
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 16s
    Exception: Gradle task assembleDebug failed with exit code 1
    

    So, I went into android\app\build.gradle and changed the value of minSdkVersion from 16 to 23. I then get this error instead:

    Launching lib\main.dart on SM A705FN in debug mode...
    Running Gradle task 'assembleDebug'...
    e: C:\Flutter\.pub-cache\hosted\pub.dartlang.org\audioplayers-0.17.1\android\src\main\kotlin\xyz\luan\audioplayers\AudioplayersPlugin.kt: (181, 52): Expecting a parameter declaration
    e: C:\Flutter\.pub-cache\hosted\pub.dartlang.org\audioplayers-0.17.1\android\src\main\kotlin\xyz\luan\audioplayers\AudioplayersPlugin.kt: (231, 38): Expecting an argument
    e: C:\Flutter\.pub-cache\hosted\pub.dartlang.org\audioplayers-0.17.1\android\src\main\kotlin\xyz\luan\audioplayers\ByteDataSource.kt: (8, 37): Expecting a parameter declaration
    e: C:\Flutter\.pub-cache\hosted\pub.dartlang.org\audioplayers-0.17.1\android\src\main\kotlin\xyz\luan\audioplayers\WrappedMediaPlayer.kt: (10, 39): Expecting a parameter declaration
    e: C:\Flutter\.pub-cache\hosted\pub.dartlang.org\audioplayers-0.17.1\android\src\main\kotlin\xyz\luan\audioplayers\WrappedSoundPool.kt: (168, 32): Expecting a parameter declaration
    e: C:\Flutter\.pub-cache\hosted\pub.dartlang.org\audioplayers-0.17.1\android\src\main\kotlin\xyz\luan\audioplayers\WrappedSoundPool.kt: (205, 26): Expecting an argument
    e: C:\Flutter\.pub-cache\hosted\pub.dartlang.org\audioplayers-0.17.1\android\src\main\kotlin\xyz\luan\audioplayers\WrappedSoundPool.kt: (46, 77): Type inference failed. Expected type mismatch: inferred type is List<???> but MutableList<WrappedSoundPool> was expected
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Execution failed for task ':audioplayers:compileDebugKotlin'.
    > Compilation error. See log for more details
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 18s
    Exception: Gradle task assembleDebug failed with exit code 1
    
    bug 
    opened by darre1 26
  • Does not play with asset source and lowLatency mode (BUG)

    Does not play with asset source and lowLatency mode (BUG)

    Low Latency mode does not work on Android

    Full Description

    Using sound player with AssetSource and lowLatency mode does not work. No sound is played. No error either, it just doesn't do anything.

    Code to Reproduce

     await _soundPlayer.play(
              AssetSource('sounds/long_beep.mp3'),
              mode: PlayerMode.lowLatency,
            );
    

    Log Errors No errors, just does not play sound

    Files/URLs/Sources N/A

    Screenshots N/A

    Platforms Android

    • OS: android
    • OS version: android version 11 on physical device. Also emulator Pixel 4 API 31 Android 12
    • Device: Samsung Galaxy A20
    • flutter version: 3.0.2
    • audioplayers version: 1.0.1
    • release or not release: debug mode
    • does the error occur and does it have any peculiarities: easy to reproduce

    ** workaround** Commenting out PlayerMode resolves the issue.

    opened by under3415 24
  • windows platform support

    windows platform support

    flutter desktop is not stable, but we all know it’s future of desktop app development. audioplayer works fine on android ios web and macos but only windows does not have support for it. thous it is experimental i think we should support windows platform in early stage

    help wanted feature-request platform-windows 
    opened by softmarshmallow 24
  • AVPlayerItemStatus.failed

    AVPlayerItemStatus.failed

    Much like this issue: https://github.com/luanpotter/audioplayers/issues/62

    Playing audio files from a remote URL on iOS (Simulator and device) fails with the error: AVPlayerItemStatus.failed

    opened by ghost 22
  • Audioplayers maybe using an old Gradle?

    Audioplayers maybe using an old Gradle?

    I was excited about returning my old Flutter project that uses AudioPlayers. I have waited the 3.0.0 version to start using null safety. Then, when I updated my project to:

    environment:
      sdk: ">=2.12.0 <3.0.0"
      flutter: ">=2.0.3"
    
    dependencies:
    (... )
      audioplayers: ^0.18.3
    (...)
    

    I have met the following error:

    Project evaluation failed including an error in afterEvaluate {}. Run with --stacktrace for details of the afterEvaluate {} error.
    
    FAILURE: Build failed with an exception.
    
    * Where:
    Build file '/usr/flutter/.pub-cache/hosted/pub.dartlang.org/audioplayers-0.18.3/android/build.gradle' line: 25
    
    * What went wrong:
    A problem occurred evaluating root project 'audioplayers'.
    > Failed to apply plugin [id 'kotlin-android']
       > The current Gradle version 4.10.2 is not compatible with the Kotlin Gradle plugin. Please use Gradle 5.3 or newer, or the previous version of the Kotlin plugin.
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 1s
    
    
    Exception: The plugin audioplayers could not be built due to the issue above.
    

    Have I missed something? Or maybe audioplayers needs some little adjustments?

    Regards,

    -- André

    PS.: All I need in my project is to play some mp3 files. The library used to work like a charm (even on WEB). So, I think I may be missing something...

    bug 
    opened by andreclinio 20
  • Android notification area with consistent dart code used for iOS notification area.

    Android notification area with consistent dart code used for iOS notification area.

    _currentPlayerId should be assigned in setUrl function along with in resume() function. This prevents an edge case crash while setting notification controls.

    opened by subhash279 20
  • Add MPNowPlayingInfoCenter and MPRemoteCommandCenter capabilities

    Add MPNowPlayingInfoCenter and MPRemoteCommandCenter capabilities

    When playing audio with this plugin, iOS does not offer any control with the command center remote control buttons and doesn't show which track is currently playing.

    I found this stackoverflow question that describes how to do it.

    I reckon that this is something that would make sense to add to this library.

    Do you agree, and if so, do you think you might have the time to look into it, or should I try to get it to work?

    enhancement help wanted good first issue 
    opened by enyo 20
  • fix: [Discussion] Add try-catch to avoid IllegalStateException when calling player.isPlaying on Android media player

    fix: [Discussion] Add try-catch to avoid IllegalStateException when calling player.isPlaying on Android media player

    Description

    Add try-catch to avoid IllegalStateException when calling player.isPlaying on Android media player

    See issues like #1150 and #1331 for some examples.

    For examples of this issue. Though sometimes the exception is thrown on other methods used on the wrong time.

    This is definitely a band-aid solution. The goal of WrappedPlayer is to abstract away all the insane fragility of android's default media player by doing its own state control.

    This could help reduce some errors, but might as well be hinding some async/thread/racing conditions and such.

    Checklist

    • [x] The title of my PR starts with a Conventional Commit prefix (fix:, feat:, docs:, chore: etc).
    • [X] I have read the Contributor Guide and followed the process outlined for submitting PRs.
    • [x] I have updated/added tests for ALL new/updated/fixed functionality.
    • [X] I have updated/added relevant documentation and added dartdoc comments with ///, where necessary.
    • [x] I have updated/added relevant examples in example.

    Breaking Change

    • [ ] Yes, this is a breaking change.
    • [x] No, this is not a breaking change.
    opened by luanpotter 2
  • chore: [WIP] Update gradle?

    chore: [WIP] Update gradle?

    This is a draft and WIP.

    IJ and android studio are both complaining about our outdated gradle version.

    This is an exploration to see about changing it.

    opened by luanpotter 0
  • fix!: Change the default value of iOS audio context to force speakers

    fix!: Change the default value of iOS audio context to force speakers

    Description

    There has been a high number of issues being opened around the fact that on 1.0.0, forceSpeaker on iOS (and android) was set to false by default, requiring most users to explicitly setup the global audio context.

    This change the default value of iOS audio context to force speakers to be inline with what users seem to expect.

    Follow this thread for details.

    Since I only test iOS on emulators, where this setting doesn't make any difference, I hadn't realized this issue.

    Note: this changes the default for android as well, which is in line with the unified audio context philosophy.

    Checklist

    • [x] The title of my PR starts with a Conventional Commit prefix (fix:, feat:, docs:, chore: etc).
    • [x] I have read the Contributor Guide and followed the process outlined for submitting PRs.
    • [x] I have updated/added tests for ALL new/updated/fixed functionality.
    • [x] I have updated/added relevant documentation and added dartdoc comments with ///, where necessary.
    • [x] I have updated/added relevant examples in example.

    Breaking Change

    • [x] Yes, this is a breaking change.
    • [ ] No, this is not a breaking change.

    Migration instructions

    If you wanted to have it set to false, you can just set it so:

          final AudioContext audioContext = AudioContext(
            iOS: AudioContextIOS(
              defaultToSpeaker: false,
             // ...
            ),
            // ...
          );
          AudioPlayer.global.setGlobalAudioContext(audioContext);
    

    If not, you can remove all the ad-hoc code you had to set this up.

    Related Issues

    opened by luanpotter 4
  • Audio has a delay after resume to start to play

    Audio has a delay after resume to start to play

    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

    Sometimes, when I press to play the audio, it has a big delay to start to play. The PlayerState it's playing right after press play, the file it's already downloaded.

    Current bug behaviour

    1. Set source from deviceFile.
    2. audioPlayer.onPlayerStateChanged dispatch isReady state.
    3. Press play button, that calls audioPlayer.resume() method.
    4. audioPlayer.onPlayerStateChanged dispatch playing state.
    5. Wait until the audio starts to play, sometimes wait more then 1 minute.

    Expected behaviour

    1. Set source from deviceFile.
    2. audioPlayer.onPlayerStateChanged dispatch isReady state.
    3. Press play button, that calls audioPlayer.resume() method.
    4. audioPlayer.onPlayerStateChanged dispatch playing state.
    5. Play right after press the button since the state it's ready.

    Reproducing

    https://user-images.githubusercontent.com/50436424/209859752-e24fda51-eaee-4547-ab29-0614e38b4229.mp4

    Environment information

    • audioplayers version: 1.1.1

    Platform 1: Ubuntu 22.10, Ubuntu 22.04 LTS, Ubuntu 18.04 LTS

    • build mode: debug and release mode

    Platforms tested without any issue: Windows 10

    bug 
    opened by gustoliveira 0
  • [Android] lib tests fail on CI with `what:MEDIA_ERROR_UNKNOWN {what:1} extra:MEDIA_ERROR_SYSTEM`

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

    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

    bug platform-android 
    opened by Gustl22 0
  • feat: error stream (#1266)

    feat: error stream (#1266)

    Description

    Customizable error stream. Fixes #1260

    Checklist

    • [x] The title of my PR starts with a Conventional Commit prefix (fix:, feat:, docs:, chore: etc).
    • [x] I have read the Contributor Guide and followed the process outlined for submitting PRs.
    • [ ] I have updated/added tests for ALL new/updated/fixed functionality.
    • [x] I have updated/added relevant documentation and added dartdoc comments with ///, where necessary.
    • [ ] I have updated/added relevant examples in example.

    Breaking Change

    • [ ] Yes, this is a breaking change.
    • [x] No, this is not a breaking change.

    Related Issues

    opened by Gustl22 0
Releases(0.7.0)
  • 0.7.0(Jul 14, 2018)

    • Improved lifecycle handling for android
    • Big performance boots
    • Allows for finer control of releasing (with setReleaseMode, setUrl, resume, release)
    • Allows for setting the volume at any time (with setVolume)
    • Added LOOP as a ReleaseMode options, making it significantly faster
    • Some other refactorings
    Source code(tar.gz)
    Source code(zip)
Owner
Blue Fire
Team working on open source packages and plugins for Flutter, including Flame, Audioplayers, Photo View, and more.
Blue Fire
An Online multiplayer Tictactoe game where two player can play simultaneously

This is an Online multiplayer Tictactoe game where two player can play simultaneously. Whoever gets 6 points of score first wins the game. one player have to create a room and others have to join the room my inputing rooms ID number given by the player1(Who has created the room). The Project in coded in flutter language and javacsript and nodejs is used for backend/server. and mongoDB is used for Database to store the player's details.

Tirthak 2 Sep 5, 2022
M.U.D. Role-playing text-based game. A multiple-choice multiplayer interactive game developed on Flutter (Android, iOS, Windows, Web)

Teia M.U.D. Role-playing text-based game. A multiple-choice multiplayer interactive game developed on Flutter (Android, iOS, Windows, Web). The main f

Pedro Gonçalves 3 Feb 17, 2022
A Flutter plugin to support game center and google play games services.

A Flutter plugin to support game center and google play games services. Screenshot iOS Android Tutorials Written tutorial Video tutorial Will be added

Abedalkareem Omreyh 76 Jan 6, 2023
Snake-Game - A flutter based classic snake game with nothing just and just a feel to have play

snake_game This is a simple snake Game under development made with the help of y

Shubham Kumar 2 Mar 22, 2022
Flutter Switch Game: Get Fun With Play This Game

switch_game A new Flutter project. Getting Started Try Swap red circle to green

Sermed Berwari 1 Jun 17, 2022
A simple wrapper on top of Google Play Games Services (GPGS), including auth, achievement, and more.

play_games Use Google Play Games Services on your Flutter app; this allows for signin and achievements so far, but more additions are very welcome. If

Flame Engine 59 Sep 10, 2022
A slide puzzle game you can play with your friend on cross-platform.

slideparty Inspiration I want to make a puzzle game that runs on all platforms: Web, Android, iOS, Linux, Windows and MacOS. You can play with your fr

Duong Bui Dai 29 Nov 23, 2022
A Dart Tiled library. Parse your TMX files into useful representations. Compatible with Flame.

Tiled Dart A Dart Tiled library. Install from Dart Pub Repository Include the following in your pubspec.yaml: dependencies: tiled: 0.8.1 Usa

Flame Engine 44 Oct 31, 2022
A starter game in Flutter with all the bells and whistles of a mobile (iOS & Android) game

A starter game in Flutter with all the bells and whistles of a mobile (iOS & Android) game including the following features: sound music main menu scr

Samuel Abada 14 Dec 22, 2022
A word game for iOS and Android

Bnoggles A word game for iOS and Android. Swipe through letters to find all words hidden in a grid. This project is based on the Flutter application d

Benno Richters 35 Feb 25, 2022
Neuss - A very simple guessing game created for iOS and Android devices

Neuss - A very simple guessing game created for iOS and Android devices

AmirHossein Mohammadi 8 Jul 25, 2022
🎮 Tic Tac Toe Local Multiplayer Game for Android

#game, #app, #android #tictactoe Tic Tac Toe A Open Source Tic Tac Toe Game with Local Multiplayer Play It NSD Package This project was built on top o

lask 12 Nov 21, 2022
🎮 Tic Tac Toe Local Multiplayer Game for Android.

#game, #app, #android #tictactoe Tic Tac Toe A Open Source Tic Tac Toe Game with Local Multiplayer Play It NSD Package This project was built on top o

Alex Rintt 9 Jul 23, 2022
Wordle-flutter - A Wordle Game Made With Flutter

wordle with flutter A small wordle made with flutter Getting Started Just a 4 ho

Fernando Souto Gonzalez 9 Dec 11, 2022
Tic-tac-toe-flutter - Multi player TIC-TAC-TOE game made using flutter

tic_tac_toe Multi player TIC-TAC-TOE game made using flutter State Management li

Aakash Pamnani 3 Feb 22, 2022
A minimalist Flutter game engine

A minimalistic Flutter game engine. English | 简体中文 | Polski | Русский About 1.0.0 Our goal is to release v1 soon. We are periodically launching RCs (r

Flame Engine 7.3k Jan 8, 2023
Public repo for flutterflip, a reversi clone built with Flutter.

flutterflip A single-player reversi clone built with Flutter, which compiles for both Android and iOS. The user plays as black, and the CPU will make

Andrew Brogdon 247 Dec 28, 2022
How to build a Match-3 game, like Candy Crush, Bejeweled, FishDom… in Flutter.

flutter_crush How to build a Math-3 game, like Candy Crush, Bejeweled, FishDom… in Flutter. Source code of the article available on didierboelens.com

Didier Boelens 477 Nov 28, 2022
a tetris game powered by flutter. 使用flutter开发俄罗斯方块。

English introduction Please view README_EN Flutter俄罗斯方块 使用Flutter开发的俄罗斯方块游戏。支持 Android, iOS, Windows, mac, Linux 以及 web. 参考来源于 vue-tetris 。 如何开始 自行编译

Bin Yang 1.4k Dec 23, 2022