just_audio

repository·minor·Indexed 22 days ago

https://github.com/ryanheise/just_audio

A feature-rich audio player plugin for Flutter supporting Android, iOS, macOS, web, Linux, and Windows. It provides advanced capabilities including gapless playback, playlist management, clipping, custom stream sources, and background playback via the just_audio_background package.

Tokens
15.6K
Snippets
37
Records
60
Agent score
74%

What's inside just_audio

  1. Complementary audio plugins for just_audio

    minor

    Because just_audio focuses solely on playback, you should use these specialized plugins for other audio capabilities:

    • Background Playback: Use just_audio_background for lockscreen controls and media notifications, or audio_service for more advanced requirements.
    • Audio Session Management: Use audio_session to manage interactions with other apps (e.g., handling phone calls).
    • Waveform Extraction: Use just_waveform to extract waveforms for visual rendering.
  2. Understand the just_audio state model

    minor

    The player's state is composed of two orthogonal states: playing and processingState.

    • playing: Typically maps to the app's play/pause button. It only changes in response to direct method calls (with some exceptions like phone call interruptions or background media notifications).
    • processingState: Reflects the state of the underlying audio decoder. It changes in response to method calls AND asynchronous events in the audio pipeline (e.g., buffering, loading, or reaching the end of a stream).

    Key behaviors to note:

    • Even if playing == true, no sound is audible unless processingState == ready (buffers are filled).
    • During network buffering, playing remains true, but processingState becomes buffering.
    • When a track ends, playing remains true, but no sound is audible until a seek occurs. You can listen for processingState == completed to programmatically pause or rewind.

    To react to both states simultaneously in your UI, listen to the playerStateStream, which emits events containing the latest values for both playing and processingState.

  3. Quickstart with just_audio

    minor

    To use just_audio, create an AudioPlayer instance and load a source using setUrl. Supported schemes include https:, file:, and asset:. You can then control playback using play(), pause(), stop(), seek(), setSpeed(), and setVolume().

    import 'package:just_audio/just_audio.dart';
    
    final player = AudioPlayer();                   // Create a player
    final duration = await player.setUrl(           // Load a URL
        'https://foo.com/bar.mp3');                 // Schemes: (https: | file: | asset: )
    player.play();                                  // Play without waiting for completion
    await player.play();                            // Play while waiting for completion
    await player.pause();                           // Pause but remain ready to play
    await player.seek(Duration(seconds: 10));       // Jump to the 10 second position
    await player.setSpeed(2.0);                     // Twice as fast
    await player.setVolume(0.5);                    // Half as loud
    await player.stop();                            // Stop and free resources
  4. Install just_audio for Windows and Linux

    minor

    Windows and Linux support requires adding an additional implementation dependency to your pubspec.yaml alongside just_audio.

    Windows options:

    • just_audio_media_kit
    • just_audio_windows
    • just_audio_libwinmedia

    Linux options:

    • just_audio_media_kit
    • just_audio_libwinmedia (untested)
    # Example for Windows using media_kit
    dependencies:
      just_audio: any
      just_audio_media_kit: any
      media_kit_libs_windows_audio: any
    
    # Example for Linux using media_kit
    dependencies:
      just_audio: any
      just_audio_media_kit: any
      media_kit_libs_linux: any
  5. Customize iOS launch screen assets

    minor

    To change the launch screen image for the iOS version of your Flutter app, you can use one of two methods:

    1. Direct File Replacement: Replace the existing image files directly within the ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory with your own assets.
    2. Xcode Interface:
      • Open the iOS project in Xcode by running open ios/Runner.xcworkspace from your terminal.
      • In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
      • Drag and drop your desired images into the asset catalog.
    open ios/Runner.xcworkspace
  6. Configure Android setup for just_audio_background

    minor

    To enable background playback on Android, you must modify your AndroidManifest.xml to include specific permissions, update your main activity, and register the required service and receiver.

    Permissions:

    • android.permission.WAKE_LOCK
    • android.permission.FOREGROUND_SERVICE
    • android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK (Required if targeting SDK 34+)

    Activity: Change the android:name attribute of your existing <activity> element to com.ryanheise.audioservice.AudioServiceActivity. If your app requires a FragmentActivity, use com.ryanheise.audioservice.AudioServiceFragmentActivity instead.

    Service and Receiver: You must add the com.ryanheise.audioservice.AudioService and com.ryanheise.audioservice.MediaButtonReceiver elements within the <application> tag.

    Note: For Android 12+, you must set android:exported="true" on components with intent filters. Use tools:ignore="Instantiatable" to suppress lint warnings if necessary.

    <manifest xmlns:tools="http://schemas.android.com/tools" ...>
      <!-- ADD THESE TWO PERMISSIONS -->
      <uses-permission android:name="android.permission.WAKE_LOCK"/>
      <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
      <!-- ALSO ADD THIS PERMISSION IF TARGETING SDK 34 -->
      <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
      
      <application ...>
        
        ...
        
        <!-- EDIT THE android:name ATTRIBUTE IN YOUR EXISTING "ACTIVITY" ELEMENT -->
        <activity android:name="com.ryanheise.audioservice.AudioServiceActivity" ...>
          ...
        </activity>
        
        <!-- ADD THIS "SERVICE" element -->
        <service android:name="com.ryanheise.audioservice.AudioService"
            android:foregroundServiceType="mediaPlayback"
            android:exported="true" tools:ignore="Instantiatable">
          <intent-filter>
            <action android:name="android.media.browse.MediaBrowserService" />
          </intent-filter>
        </service>
    
        <!-- ADD THIS "RECEIVER" element -->
        <receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver"
            android:exported="true" tools:ignore="Instantiatable">
          <intent-filter>
            <action android:name="android.intent.action.MEDIA_BUTTON" />
          </intent-filter>
        </receiver> 
      </application>
    </manifest>
  7. Install and initialize just_audio_background

    minor

    To add background playback and remote control support (notifications, lock screen, headset buttons, etc.), add just_audio_background to your pubspec.yaml.

    You must initialize the package in your app's main method using JustAudioBackground.init(). This method accepts configuration for Android notification channels.

    Note: This package is designed for the simple use case of a single AudioPlayer instance. For complex requirements or multiple players, use the audio_service package directly.

    dependencies:
      just_audio: any # substitute version number
      just_audio_background: any # substitute version number
    Future<void> main() async {
      await JustAudioBackground.init(
        androidNotificationChannelId: 'com.ryanheise.bg_demo.channel.audio',
        androidNotificationChannelName: 'Audio playback',
        androidNotificationOngoing: true,
      );
      runApp(MyApp());
    }
  8. Configure the audio session for specific use cases

    minor

    By default, just_audio uses settings appropriate for a music player (e.g., ducking audio when a navigator speaks). If you are building a podcast player or audiobook reader, you should use the audio_session package to configure the session to speech mode so that other apps pause instead of ducking.

    Implementation: Use AudioSession.instance.configure() with the desired configuration. It is recommended to apply this configuration after all other audio plugins have loaded to prevent them from overriding your settings.

    final session = await AudioSession.instance;
    await session.configure(AudioSessionConfiguration.speech());
  9. Implement a new platform for just_audio

    minor
    To create a new platform-specific implementation of the just_audio plugin, you must extend the JustAudioPlatform class from lib/just_audio_platform_interface.dart. Once your implementation is ready, you must register it as the default instance by assigning it to JustAudioPlatform.instance during your plugin's registration process.
  10. Configure Android permissions and cleartext traffic

    minor

    To access audio files on the Internet, add the INTERNET permission to your AndroidManifest.xml.

    If you need to connect to non-HTTPS (HTTP) URLs, or if you use features like headers, caching, or stream audio sources (which rely on a localhost proxy), you must enable cleartext traffic. You can do this globally by adding android:usesCleartextTraffic="true" to the application element, or more securely by defining a network_security_config.xml that only permits cleartext for 127.0.0.1.

    <!-- Permission for Internet access -->
    <uses-permission android:name="android.permission.INTERNET"/>
    
    <!-- Global cleartext access (less secure) -->
    <application ... android:usesCleartextTraffic="true">
    
    <!-- Secure approach: network_security_config.xml -->
    <?xml version="1.0" encoding="utf-8"?>
    <network-security-config>
    	<domain-config cleartextTrafficPermitted="true">
    		<domain includeSubdomains="false">127.0.0.1</domain>
    	</domain-config>
    </network-security-config>
    
    <!-- Reference config in AndroidManifest.xml -->
    <application ... android:networkSecurityConfig="@xml/network_security_config">