Skip to content
This repository has been archived by the owner on May 18, 2022. It is now read-only.
/ flutter_sound Public archive
forked from Canardoux/flutter_sound

Flutter plugin for sound. Audio recorder and player.

License

Notifications You must be signed in to change notification settings

nikiJava/flutter_sound

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

flutter_sound

pub version

This plugin provides simple recorder and player functionalities for both `android` and `ios` platforms. This only supports default file extension for each platform. This plugin handles file from remote url. This plugin can handle playback stream from native (To sync exact time with bridging).

Free Read

Medium Blog

Getting Started

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

Install

Add flutter_sound as a dependency in pubspec.yaml For help on adding as a dependency, view the documentation.

Post Installation

On iOS you need to add a usage description to info.plist:

<key>NSMicrophoneUsageDescription</key>
<string>This sample uses the microphone to record your speech and convert it to text.</string>
<key>UIBackgroundModes</key>
<array>
	<string>audio</string>
</array>

On Android you need to add a permission to AndroidManifest.xml:

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Methods

Func Param Return Description
setSubscriptionDuration double sec String message Set subscription timer in seconds. Default is 0.01 if not using this method.
startRecorder String uri, int sampleRate, int numChannels, t_CODEC codec String uri Start recording. This will return uri used.
stopRecorder String message Stop recording.
startPlayer String uri String message Start playing.
startPlayerFromBuffer Uint8List dataBuffer String message Start playing.
stopPlayer String message Stop playing.
pausePlayer String message Pause playing.
resumePlayer String message Resume playing.
seekToPlayer int milliSecs position to goTo String message Seek audio to selected position in seconds. Parameter should be less than audio duration to correctly placed.

Subscriptions

Subscription Return Description
onRecorderStateChanged <RecordStatus> Able to listen to subscription when recorder starts.
onPlayerStateChanged <PlayStatus> Able to listen to subscription when player starts.

Default uri path

When uri path is not set during the function call in startRecorder or startPlayer, they are saved in below path depending on the platform.

  • Default path for android
    • Library/Caches/sound.aac.
  • Default path for ios
    • sound.aac.

Usage

Creating instance.

In your view/page/dialog widget's State class, create an instance of FlutterSound.

FlutterSound flutterSound = new FlutterSound();

Starting recorder with listener.

Future<String> result = await flutterSound.startRecorder(null);

result.then(path) {
	print('startRecorder: $path');

	_recorderSubscription = flutterSound.onRecorderStateChanged.listen((e) {
	DateTime date = new DateTime.fromMillisecondsSinceEpoch(e.currentPosition.toInt());
	String txt = DateFormat('mm:ss:SS', 'en_US').format(date);
	});
}

If you want to take your own path specify it like below.

String path = await flutterSound.startRecorder(Platform.isIOS ? 'ios.aac' : 'android.aac');

Actually on iOS, you can choose from two encoders :

  • AAC (this is the default)
  • CAF/OPUS

To encode with OPUS you do the following :

await flutterSound.startRecorder(null, codec: t_CODEC.CODEC_CAF_OPUS,)

Recently, Apple added a support for encoding with the standard OPUS codec. Unfortunetly, Apple encapsulates its data in its own proprietary envelope : CAF. This is really stupid, this is Apple

On Android the OPUS codec is not yet supported by flutter_sound.

Stop recorder

Future<String> result = await flutterSound.stopRecorder();

result.then(value) {
	print('stopRecorder: $value');

	if (_recorderSubscription != null) {
		_recorderSubscription.cancel();
		_recorderSubscription = null;
	}
}

You MUST ensure that the recorder has been stopped when your widget is detached from the ui. Overload your widget's dispose() method to stop the recorder when your widget is disposed.

@override
void dispose() {
	flutterSound.stopRecorder();
	super.dispose();
}

Start player

  • To start playback of a record from a URL call startPlayer.
  • To start playback of a record from a memory buffer call startPlayerFromBuffer

You must wait for the return value to complete before attempting to add any listeners to ensure that the player has fully initialised.

Future<String> result = await flutterSound.startPlayer(null);

result.then(path) {
	print('startPlayer: $path');

	_playerSubscription = flutterSound.onPlayerStateChanged.listen((e) {
		if (e != null) {
			DateTime date = new DateTime.fromMillisecondsSinceEpoch(e.currentPosition.toInt());
			String txt = DateFormat('mm:ss:SS', 'en_US').format(date);
			this.setState(() {
				this._isPlaying = true;
				this._playerTxt = txt.substring(0, 8);
			});
		}
	});
}

Stop player

Future<String> result = await flutterSound.stopPlayer();

result.then(value) {
	print('stopPlayer: $result');
	if (_playerSubscription != null) {
		_playerSubscription.cancel();
		_playerSubscription = null;
	}
}

You MUST ensure that the player has been stopped when your widget is detached from the ui. Overload your widget's dispose() method to stop the player when your widget is disposed.

@override
void dispose() {
	flutterSound.stopPlayer();
	super.dispose();
}

Pause player

Future<String> result = await flutterSound.pausePlayer();

Resume player

Future<String> result = await flutterSound.resumePlayer();

Seek player

To seek to a new location the player must already be playing.

String Future<result> = await flutterSound.seekToPlayer(miliSecs);

Setting subscription duration (Optional). 0.01 is default value when not set.

/// 0.01 is default
flutterSound.setSubscriptionDuration(0.01);

Setting volume.

/// 1.0 is default
/// Currently, volume can be changed when player is running. Try manage this right after player starts.
String path = await flutterSound.startPlayer(null);
await flutterSound.setVolume(0.1);

Using the amplitude meter

The amplitude meter allows displaying a basic representation of the input sound. When enabled, it returns values ranging 0-120dB.

//// By default this option is disabled, you can enable it by calling
setDbLevelEnabled(true);
//// You can tweak the frequency of updates by calling this function (unit is seconds)
updateDbPeakProgress(0.8);
//// You need to subscribe in order to receive the value updates
_dbPeakSubscription = flutterSound.onRecorderDbPeakChanged.listen((value) {
  setState(() {
    this._dbLevel = value;
  });
});

TODO

  • Seeking example in Example project
  • Volume Control
  • Sync timing for recorder callback handler

DEBUG

When you face below error,

* What went wrong:
A problem occurred evaluating project ':app'.
> versionCode not found. Define flutter.versionCode in the local.properties file.

Please add below to your example/android/local.properties file.

flutter.versionName=1.0.0
flutter.versionCode=1
flutter.buildMode=debug

Help Maintenance

I've been maintaining quite many repos these days and burning out slowly. If you could help me cheer up, buying me a cup of coffee will make my life really happy and get much energy out of it.
Buy Me A Coffee Paypal

About

Flutter plugin for sound. Audio recorder and player.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Dart 36.5%
  • Java 32.4%
  • Objective-C 24.3%
  • Ruby 6.8%