audioplayer2 0.5.2

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • new89

AudioPlayer2

A Flutter audio plugin (ObjC/Java) to play remote or local audio files

Features

  • [x] Android & iOS
    • [x] play (remote file)
    • [x] stop
    • [x] pause
    • [x] onComplete
    • [x] onDuration / onCurrentPosition
    • [x] seek
    • [x] mute

screenshot

Usage

Example

To use this plugin :

  dependencies:
    flutter:
      sdk: flutter
    audioplayer2:
  • Instantiate an AudioPlayer instance
//...
AudioPlayer audioPlugin = new AudioPlayer();
//...

Player Controls

Future<void> play() async {
  await audioPlayer.play(kUrl);
  setState(() => playerState = PlayerState.playing);
}

Future<void> pause() async {
  await audioPlayer.pause();
  setState(() => playerState = PlayerState.paused);
}

Future<void> stop() async {
  await audioPlayer.stop();
  setState(() {
    playerState = PlayerState.stopped;
    position = new Duration();
  });
}

Status and current position

The dart part of the plugin listen for platform calls :

//...
_positionSubscription = audioPlayer.onAudioPositionChanged.listen(
  (p) => setState(() => position = p)
);

_audioPlayerStateSubscription = audioPlayer.onPlayerStateChanged.listen((s) {
  if (s == AudioPlayerState.PLAYING) {
    setState(() => duration = audioPlayer.duration);
  } else if (s == AudioPlayerState.STOPPED) {
    onComplete();
    setState(() {
      position = duration;
    });
  }
}, onError: (msg) {
  setState(() {
    playerState = PlayerState.stopped;
    duration = new Duration(seconds: 0);
    position = new Duration(seconds: 0);
  });
});

Do not forget to cancel all the subscriptions when the widget is disposed.

iOS

⚠️ iOS App Transport Security

By default iOS forbids loading from non-https url. To cancel this restriction edit your .plist and add :

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

Troubleshooting

  • If you get a MissingPluginException, try to flutter build apk on Android, or flutter build ios
  • to use the plugin in a ObjC iOS project, add 'use_frameworks!' to your podfile cf. example

Getting Started

For help getting started with Flutter, view our online documentation.

For help on editing plugin code, view the documentation.

Note

This project has been forked from the origial AudioPlayer due to it appearing to be abandoned.

Changelog

0.5.2

  • change podspec name to audioplayer2

0.5.1

  • rename package to audioplayer2 to indicate this is a new fork
  • merge PR from dp-singh to update Android SDK version
  • merge PR from ThinkDigitalRepair to update deprecated Android code
  • merge PR form mit-mit to declare support for Dart 2.0 stable in the Dart SDK upper constraint

0.5.0

  • BREAKING Change: No more separate handlers for communicating the state of the player. Instead we rely on streams to publish state changes and position updates.
  • Code formatting and flow improvements. Preparation for testing.

0.4.0

  • Feat : merge PR from mindon with mute methods and various improvements
  • fixes Future<int> errors with --preview-dart2
  • Example : add a slider to demonstrate the seek feature

0.3.0

  • merge PR from johanhenselmans to switch iOS to ObjectiveC
  • merge PR from oaks to add the seek feature

0.2.0

  • support for local files

0.1.0

0.0.2

Separated handlers for position, duration, completion and errors

  • setDurationHandler(TimeChangeHandler handler)

  • setPositionHandler(TimeChangeHandler handler)

  • setCompletionHandler(VoidCallback callback)

  • setErrorHandler(ErrorHandler handler)

  • new typedef

typedef void TimeChangeHandler(Duration duration);
typedef void ErrorHandler(String message);

0.0.1

  • first POC :
    • methods : play, pause, stop
    • a globalHandler for position, duration, completion and errors

example/lib/main.dart

import 'dart:async';
import 'dart:io';
import 'dart:typed_data';

import 'package:audioplayer2/audioplayer2.dart';
import 'package:flutter/material.dart';

typedef void OnError(Exception exception);

const kUrl = "http://www.rxlabz.com/labz/audio2.mp3";
const kUrl2 = "http://www.rxlabz.com/labz/audio.mp3";

void main() {
  runApp(new MaterialApp(home: new Scaffold(body: new AudioApp())));
}

enum PlayerState { stopped, playing, paused }

class AudioApp extends StatefulWidget {
  @override
  _AudioAppState createState() => new _AudioAppState();
}

class _AudioAppState extends State<AudioApp> {
  Duration duration;
  Duration position;

  AudioPlayer audioPlayer;

  String localFilePath;

  PlayerState playerState = PlayerState.stopped;

  get isPlaying => playerState == PlayerState.playing;
  get isPaused => playerState == PlayerState.paused;

  get durationText =>
      duration != null ? duration.toString().split('.').first : '';
  get positionText =>
      position != null ? position.toString().split('.').first : '';

  bool isMuted = false;

  StreamSubscription _positionSubscription;
  StreamSubscription _audioPlayerStateSubscription;

  @override
  void initState() {
    super.initState();
    initAudioPlayer();
  }

  @override
  void dispose() {
    _positionSubscription.cancel();
    _audioPlayerStateSubscription.cancel();
    audioPlayer.stop();
    super.dispose();
  }

  void initAudioPlayer() {
    audioPlayer = new AudioPlayer();
    _positionSubscription = audioPlayer.onAudioPositionChanged.listen(
      (p) => setState(() => position = p)
    );
    _audioPlayerStateSubscription = audioPlayer.onPlayerStateChanged.listen((s) {
      if (s == AudioPlayerState.PLAYING) {
        setState(() => duration = audioPlayer.duration);
      } else if (s == AudioPlayerState.STOPPED) {
        onComplete();
        setState(() {
          position = duration;
        });
      }
    }, onError: (msg) {
      setState(() {
        playerState = PlayerState.stopped;
        duration = new Duration(seconds: 0);
        position = new Duration(seconds: 0);
      });
    });
  }

  Future play() async {
    await audioPlayer.play(kUrl);
    setState(() {
      playerState = PlayerState.playing;
    });
  }

  Future _playLocal() async {
    await audioPlayer.play(localFilePath, isLocal: true);
    setState(() => playerState = PlayerState.playing);
  }

  Future pause() async {
    await audioPlayer.pause();
    setState(() => playerState = PlayerState.paused);
  }

  Future stop() async {
    await audioPlayer.stop();
    setState(() {
      playerState = PlayerState.stopped;
      position = new Duration();
    });
  }

  Future mute(bool muted) async {
    await audioPlayer.mute(muted);
    setState(() {
      isMuted = muted;
    });
  }

  void onComplete() {
    setState(() => playerState = PlayerState.stopped);
  }

  Future<Uint8List> _loadFileBytes(String url, {OnError onError}) async {
    Uint8List bytes;
    try {
      bytes = await readBytes(url);
    } on ClientException {
      rethrow;
    }
    return bytes;
  }

  Future _loadFile() async {
    final bytes = await _loadFileBytes(kUrl,
        onError: (Exception exception) =>
            print('_loadFile => exception $exception'));

    final dir = await getApplicationDocumentsDirectory();
    final file = new File('${dir.path}/audio.mp3');

    await file.writeAsBytes(bytes);
    if (await file.exists())
      setState(() {
        localFilePath = file.path;
      });
  }

  @override
  Widget build(BuildContext context) {
    return new Center(
        child: new Material(
            elevation: 2.0,
            color: Colors.grey[200],
            child: new Center(
              child: new Column(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    new Material(child: _buildPlayer()),
                    localFilePath != null
                        ? new Text(localFilePath)
                        : new Container(),
                    new Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: new Row(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: [
                            new RaisedButton(
                              onPressed: () => _loadFile(),
                              child: new Text('Download'),
                            ),
                            new RaisedButton(
                              onPressed: () => _playLocal(),
                              child: new Text('play local'),
                            ),
                          ]),
                    )
                  ]),
            )));
  }

  Widget _buildPlayer() => new Container(
      padding: new EdgeInsets.all(16.0),
      child: new Column(mainAxisSize: MainAxisSize.min, children: [
        new Row(mainAxisSize: MainAxisSize.min, children: [
          new IconButton(
              onPressed: isPlaying ? null : () => play(),
              iconSize: 64.0,
              icon: new Icon(Icons.play_arrow),
              color: Colors.cyan),
          new IconButton(
              onPressed: isPlaying ? () => pause() : null,
              iconSize: 64.0,
              icon: new Icon(Icons.pause),
              color: Colors.cyan),
          new IconButton(
              onPressed: isPlaying || isPaused ? () => stop() : null,
              iconSize: 64.0,
              icon: new Icon(Icons.stop),
              color: Colors.cyan),
        ]),
        duration == null
            ? new Container()
            : new Slider(
                value: position?.inMilliseconds?.toDouble() ?? 0.0,
                onChanged: (double value) =>
                    audioPlayer.seek((value / 1000).roundToDouble()),
                min: 0.0,
                max: duration.inMilliseconds.toDouble()),
        new Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            new IconButton(
                onPressed: () => mute(true),
                icon: new Icon(Icons.headset_off),
                color: Colors.cyan),
            new IconButton(
                onPressed: () => mute(false),
                icon: new Icon(Icons.headset),
                color: Colors.cyan),
          ],
        ),
        new Row(mainAxisSize: MainAxisSize.min, children: [
          new Padding(
              padding: new EdgeInsets.all(12.0),
              child: new Stack(children: [
                new CircularProgressIndicator(
                    value: 1.0,
                    valueColor: new AlwaysStoppedAnimation(Colors.grey[300])),
                new CircularProgressIndicator(
                  value: position != null && position.inMilliseconds > 0
                      ? (position?.inMilliseconds?.toDouble() ?? 0.0) /
                          (duration?.inMilliseconds?.toDouble() ?? 0.0)
                      : 0.0,
                  valueColor: new AlwaysStoppedAnimation(Colors.cyan),
                  backgroundColor: Colors.yellow,
                ),
              ])),
          new Text(
              position != null
                  ? "${positionText ?? ''} / ${durationText ?? ''}"
                  : duration != null ? durationText : '',
              style: new TextStyle(fontSize: 24.0))
        ])
      ]));
}

Use this package as a library

1. Depend on it

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


dependencies:
  audioplayer2: ^0.5.2

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

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

3. Import it

Now in your Dart code, you can use:


import 'package:audioplayer2/audioplayer2.dart';
  
Version Uploaded Documentation Archive
0.5.2 Sep 5, 2018 Go to the documentation of audioplayer2 0.5.2 Download audioplayer2 0.5.2 archive
0.5.1 Aug 28, 2018 Go to the documentation of audioplayer2 0.5.1 Download audioplayer2 0.5.1 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
86
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
89
Learn more about scoring.

We analyzed this package on Sep 18, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.12.3
  • Flutter: 0.8.4

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Suggestions

The description is too short.

Add more detail about the package, what it does and what is its target use case. Try to write at least 60 characters.

Format lib/audioplayer2.dart.

Run flutter format to format lib/audioplayer2.dart.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=1.19.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11
meta 1.1.6
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8