简介
flutter_sound播放插件是一款非常优秀的音频记录,播放,音频文件转换插件。它更新速度非常快,我在这里不敢列出版本,免得不小心文章又过时了。
插件介绍
以目前最新版本flutter_sound: ^8.4.2为例:
你如果只是看Example会完全不知所云,所以,我们要找到它的github仓库,仓库地址为:https://github.com/canardoux/flutter_sound,然后咱们打开example项目https://github.com/Canardoux/flutter_sound/tree/master/flutter_sound/example
下载下来,并用android studio打开运行,注意,需要更新android studio到最新版本。
android配置
这里有两部分配置,一部分是build.gradle的配置,引入相应的jar包:
implementation 'com.arthenica:mobile-ffmpeg-full:4.4.LTS'
implementation 'androidx.core:core:1.3.2'
implementation 'androidx.media:media:1.2.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
// -------------------------------------------------------------------------------------
// CAUTION: The following instruction is for developping and debugging the Flauto Engine
// DO NOT INCLUDE THE FOLLOWING LINE IN A REAL APP !!!
//implementation project(':flutter_sound_core')
implementation 'com.github.canardoux:flutter_sound_core:8.4.1'
// -------------------------------------------------------------------------------------
另外一部分是在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="Manifest.permission.CAPTURE_AUDIO_OUTPUT" />
布局
布局两个按钮,一个播放,一个录音,非常简单:
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutter_sound demo'),
),
body: Row(
children: [
SizedBox(
width: 3,
),
ElevatedButton(
onPressed: () {
play();
},
child: Text('Play')),
SizedBox(
width: 20,
),
// 一般播放和录音没啥关系
ElevatedButton(
onPressed: () {
if (recording) {
stopRecorder();
} else {
record();
}
},
child: Text(recording ? 'Stop' : 'Record'))
],
),
);
}
界面显示也非常简单:
初始化
初始化主要是定义好FlutterSoundPlayer和FlutterSoundRecorder两个对象,并初始化。
Codec _codec = Codec.aacMP4;
String _mPath = 'tau_file.mp4';
bool recording = false;
FlutterSoundPlayer? _mPlayer = FlutterSoundPlayer();
FlutterSoundRecorder? _mRecorder = FlutterSoundRecorder();
Future<void> openTheRecorder() async {
var status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
throw RecordingPermissionException('Microphone permission not granted');
}
await _mRecorder!.openAudioSession();
if (!await _mRecorder!.isEncoderSupported(_codec) && kIsWeb) {
_codec = Codec.opusWebM;
_mPath = 'tau_file.webm';
if (!await _mRecorder!.isEncoderSupported(_codec) && kIsWeb) {
return;
}
}
}
@override
void initState() {
_mPlayer!.openAudioSession().then((value) {});
// await openTheRecorder().then((value) {});
// TODO: implement initState
openTheRecorder().then((value) {
setState(() {});
});
super.initState();
}
播放方法
void play() {
_mPlayer!
.startPlayer(
fromURI: _mPath,
// 'https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3',
//codec: kIsWeb ? Codec.opusWebM : Codec.aacADTS,
whenFinished: () {
setState(() {});
})
.then((value) {
setState(() {});
});
}
_mPath是音频位置,可以是本地音频,也可以是网络音频。
录音和停止录音方法
void record() async {
_mRecorder!
.startRecorder(
toFile: _mPath,
codec: _codec,
audioSource: AudioSource.microphone,
)
.then((value) {});
setState(() {
recording = true;
});
}
void stopRecorder() async {
await _mRecorder!.stopRecorder().then((value) {
setState(() {
recording = false;
});
});
}
也不复杂,就是startRecorder和stopRecorder两个方法。
全部代码
界面就很好操作了,播放和停止两个按钮就行了。全部代码如下:
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter_sound/flutter_sound.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_sound_platform_interface/flutter_sound_recorder_platform_interface.dart';
class Demo extends StatefulWidget {
Demo({Key? key}) : super(key: key);
@override
_DemoState createState() => _DemoState();
}
class _DemoState extends State<Demo> {
Codec _codec = Codec.aacMP4;
String _mPath = 'tau_file.mp4';
bool recording = false;
FlutterSoundPlayer? _mPlayer = FlutterSoundPlayer();
FlutterSoundRecorder? _mRecorder = FlutterSoundRecorder();
Future<void> openTheRecorder() async {
var status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
throw RecordingPermissionException('Microphone permission not granted');
}
await _mRecorder!.openAudioSession();
if (!await _mRecorder!.isEncoderSupported(_codec) && kIsWeb) {
_codec = Codec.opusWebM;
_mPath = 'tau_file.webm';
if (!await _mRecorder!.isEncoderSupported(_codec) && kIsWeb) {
return;
}
}
}
@override
void initState() {
_mPlayer!.openAudioSession().then((value) {});
// await openTheRecorder().then((value) {});
// TODO: implement initState
openTheRecorder().then((value) {
setState(() {});
});
super.initState();
}
void play() {
_mPlayer!
.startPlayer(
fromURI: _mPath,
// 'https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3',
//codec: kIsWeb ? Codec.opusWebM : Codec.aacADTS,
whenFinished: () {
setState(() {});
})
.then((value) {
setState(() {});
});
}
void record() async {
_mRecorder!
.startRecorder(
toFile: _mPath,
codec: _codec,
audioSource: AudioSource.microphone,
)
.then((value) {});
setState(() {
recording = true;
});
}
void stopRecorder() async {
await _mRecorder!.stopRecorder().then((value) {
setState(() {
recording = false;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutter_sound demo'),
),
body: Row(
children: [
SizedBox(
width: 3,
),
ElevatedButton(
onPressed: () {
play();
},
child: Text('Play')),
SizedBox(
width: 20,
),
// 一般播放和录音没啥关系
ElevatedButton(
onPressed: () {
if (recording) {
stopRecorder();
} else {
record();
}
},
child: Text(recording ? 'Stop' : 'Record'))
],
),
);
}
}
github地址如下:https://gitee.com/jishaofeng89/dongda_flutter_sound/,晚一点之后我会把b站视频录制一下。