just_audio 0.1.3

  • Readme
  • Changelog
  • Example
  • Installing
  • 96

just_audio #

A Flutter plugin to play audio from URLs, files, assets and DASH/HLS streams. This plugin can be used with audio_service to play audio in the background and control playback from the lock screen, Android notifications, the iOS Control Center, and headset buttons.

Features #

FeatureAndroidiOSWeb
read from URL
read from file(untested)
read from asset(untested)
DASH(untested)(untested)
HLS(untested)(untested)
play/pause/stop/seek
set volume(untested)(untested)
set speed(untested)(untested)
custom actions(untested)(untested)
clip audio
dispose

This plugin has been tested on Android and Web, and is being made available for testing on iOS. Please consider reporting any bugs you encounter here or submitting pull requests here.

Example #

Initialisation:

final player = AudioPlayer();
var duration = await player.setUrl('https://foo.com/bar.mp3');

Standard controls:

player.play();
await player.seek(Duration(seconds: 10));
await player.pause();
await player.stop();

Clipping audio:

await player.setClip(start: Duration(seconds: 10), end: Duration(seconds: 20));
await player.play(); // Waits for playback to finish

Release resources:

await player.dispose();

Todo #

  • FLAC support
  • Gapless playback

0.1.3 #

  • Fix bug in web implementation.

0.1.2 #

  • Broadcast how much audio has been buffered.

0.1.1 #

  • Web implementation.
  • iOS option to minimize stalling.
  • Fix setAsset on iOS.

0.1.0 #

  • Separate buffering state from PlaybackState.
  • More permissive state transitions.
  • Support playing local files on iOS.

0.0.6 #

  • Bug fixes.

0.0.5 #

  • API change for audio clipping.
  • Performance improvements and bug fixes on Android.

0.0.4 #

  • Remove reseeking hack.

0.0.3 #

  • Feature to change audio speed.

0.0.2 #

  • iOS implementation for testing (may not work).

0.0.1 #

  • Initial release with Android implementation.

example/lib/main.dart

import 'package:flutter/material.dart';

import 'package:just_audio/just_audio.dart';
import 'package:rxdart/rxdart.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _volumeSubject = BehaviorSubject.seeded(1.0);
  final _speedSubject = BehaviorSubject.seeded(1.0);
  AudioPlayer _player;

  @override
  void initState() {
    super.initState();
    _player = AudioPlayer();
    _player.setUrl(
        "https://s3.amazonaws.com/scifri-episodes/scifri20181123-episode.mp3");
  }

  @override
  void dispose() {
    _player.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Audio Player Demo'),
        ),
        body: Center(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text("Science Friday"),
              Text("Science Friday and WNYC Studios"),
              StreamBuilder<FullAudioPlaybackState>(
                stream: _player.fullPlaybackStateStream,
                builder: (context, snapshot) {
                  final fullState = snapshot.data;
                  final state = fullState?.state;
                  final buffering = fullState?.buffering;
                  return Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      if (state == AudioPlaybackState.connecting ||
                          buffering == true)
                        Container(
                          margin: EdgeInsets.all(8.0),
                          width: 64.0,
                          height: 64.0,
                          child: CircularProgressIndicator(),
                        )
                      else if (state == AudioPlaybackState.playing)
                        IconButton(
                          icon: Icon(Icons.pause),
                          iconSize: 64.0,
                          onPressed: _player.pause,
                        )
                      else
                        IconButton(
                          icon: Icon(Icons.play_arrow),
                          iconSize: 64.0,
                          onPressed: _player.play,
                        ),
                      IconButton(
                        icon: Icon(Icons.stop),
                        iconSize: 64.0,
                        onPressed: state == AudioPlaybackState.stopped ||
                                state == AudioPlaybackState.none
                            ? null
                            : _player.stop,
                      ),
                    ],
                  );
                },
              ),
              Text("Track position"),
              StreamBuilder<Duration>(
                stream: _player.durationStream,
                builder: (context, snapshot) {
                  final duration = snapshot.data ?? Duration.zero;
                  return StreamBuilder<Duration>(
                    stream: _player.getPositionStream(),
                    builder: (context, snapshot) {
                      var position = snapshot.data ?? Duration.zero;
                      if (position > duration) {
                        position = duration;
                      }
                      return SeekBar(
                        duration: duration,
                        position: position,
                        onChangeEnd: (newPosition) {
                          _player.seek(newPosition);
                        },
                      );
                    },
                  );
                },
              ),
              Text("Volume"),
              StreamBuilder<double>(
                stream: _volumeSubject.stream,
                builder: (context, snapshot) => Slider(
                  divisions: 20,
                  min: 0.0,
                  max: 2.0,
                  value: snapshot.data ?? 1.0,
                  onChanged: (value) {
                    _volumeSubject.add(value);
                    _player.setVolume(value);
                  },
                ),
              ),
              Text("Speed"),
              StreamBuilder<double>(
                stream: _speedSubject.stream,
                builder: (context, snapshot) => Slider(
                  divisions: 10,
                  min: 0.5,
                  max: 1.5,
                  value: snapshot.data ?? 1.0,
                  onChanged: (value) {
                    _speedSubject.add(value);
                    _player.setSpeed(value);
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class SeekBar extends StatefulWidget {
  final Duration duration;
  final Duration position;
  final ValueChanged<Duration> onChanged;
  final ValueChanged<Duration> onChangeEnd;

  SeekBar({
    @required this.duration,
    @required this.position,
    this.onChanged,
    this.onChangeEnd,
  });

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

class _SeekBarState extends State<SeekBar> {
  double _dragValue;

  @override
  Widget build(BuildContext context) {
    return Slider(
      min: 0.0,
      max: widget.duration.inMilliseconds.toDouble(),
      value: _dragValue ?? widget.position.inMilliseconds.toDouble(),
      onChanged: (value) {
        setState(() {
          _dragValue = value;
        });
        if (widget.onChanged != null) {
          widget.onChanged(Duration(milliseconds: value.round()));
        }
      },
      onChangeEnd: (value) {
        _dragValue = null;
        if (widget.onChangeEnd != null) {
          widget.onChangeEnd(Duration(milliseconds: value.round()));
        }
      },
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  just_audio: ^0.1.3

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:just_audio/just_audio.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
92
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
96
Learn more about scoring.

We analyzed this package on Mar 31, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
async ^2.4.0 2.4.1
flutter 0.0.0
flutter_web_plugins 0.0.0
path ^1.6.4 1.6.4
path_provider ^1.5.1 1.6.5
rxdart ^0.23.1 0.23.1 0.24.0-dev.1
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
path_provider_macos 0.0.4
path_provider_platform_interface 1.0.1
platform 2.2.1
plugin_platform_interface 1.0.2
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test