Flutter-flutter_sound錄音與播放
highlight: a11y-dark
外掛介紹:
flutter_sound
這個外掛可以實現iOS和Android
平臺的錄音和播放功能。即可以播放本地音訊檔案,也可以播放遠端URL檔案。在這裡我講介紹這個外掛的用法以及碰到的一些常見問題如何解決。
-
flutter_sound支援多種錄音格式
-
flutter_sound支援多種播放格式
-
flutter_sound支援音訊振幅大小
外掛資訊:
外掛地址:http://github.com/ryanheise/audio_session
外掛版本:9.2.9
外掛使用前的準備工作
設定麥克風許可權描述
- iOS:需要在info.plist檔案新增一下許可權
oc
<key>NSMicrophoneUsageDescription</key>
<string>描述你使用麥克風用來幹嘛</string>
注意:還需要在Podfile檔案中配置
```js post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=1',
]
end
end
end ```
還需要在iOS工程中增加libc++.tbd
庫,具體路徑
- Android:需要設定
AndroidManifest.xml
oc
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
這裡還用了下面幾個外掛
許可權管理外掛 permission_handler
外掛資訊:permission_handler: ^9.2.0
外掛地址:http://pub.flutter-io.cn/packages/permission_handler
音訊硬體配置外掛 audio_session
外掛資訊:audio_session: ^0.1.6
外掛地址:http://github.com/ryanheise/audio_session
動畫外掛
外掛資訊:lottie: 1.2.1
外掛地址:http://pub.flutter-io.cn/packages/flutter_lottie
常用的方法
錄音常見的方法
初始化錄音物件
flutter
FlutterSoundRecorder recorderModule = FlutterSoundRecorder();
開啟錄音
flutter
Future<void> init() async {
//開啟錄音
await recorderModule.openRecorder();
//設定訂閱計時器
await recorderModule
.setSubscriptionDuration(const Duration(milliseconds: 10));
//初始化日期外掛
await initializeDateFormatting();
}
麥克風許可權
```flutter
Future
///申請許可權 void requestPermission(Permission permission) async { PermissionStatus status = await permission.request(); if (status.isPermanentlyDenied) { openAppSettings(); } } ```
開始錄音
```flutter /// 開始錄音 _startRecorder() async { try { //獲取麥克風許可權 await getPermissionStatus().then((value) async { if (!value) { return; } //使用者允許使用麥克風之後開始錄音 Directory tempDir = await getTemporaryDirectory(); var time = DateTime.now().millisecondsSinceEpoch; String path = '${tempDir.path}/$time${ext[Codec.aacADTS.index]}';
//這裡我錄製的是aac格式的,還有其他格式
await recorderModule.startRecorder(
toFile: path,
codec: Codec.aacADTS,
bitRate: 8000,
numChannels: 1,
sampleRate: 8000,
);
/// 監聽錄音
_recorderSubscription = recorderModule.onProgress!.listen((e) {
var date = DateTime.fromMillisecondsSinceEpoch(
e.duration.inMilliseconds,
isUtc: true);
var txt = DateFormat('mm:ss:SS', 'en_GB').format(date);
//設定了最大錄音時長
if (date.second >= _maxLength) {
_stopRecorder();
return;
}
setState(() {
//更新錄音時長
_recordText = txt.substring(1, 5);
});
});
setState(() {
//更新錄音狀態和錄音檔案路徑
_state = RecordPlayState.recording;
_path = path;
});
});
} catch (err) { setState(() { _stopRecorder(); _state = RecordPlayState.record; _cancelRecorderSubscriptions(); }); } } ```
結束錄音
```flutter /// 結束錄音 _stopRecorder() async { try { await recorderModule.stopRecorder(); _cancelRecorderSubscriptions(); // _getDuration(); } catch (err) {} setState(() { _state = RecordPlayState.record; }); }
///銷燬錄音 void dispose() { super.dispose(); _cancelRecorderSubscriptions(); _releaseFlauto(); }
/// 取消錄音監聽 void _cancelRecorderSubscriptions() { if (_recorderSubscription != null) { _recorderSubscription!.cancel(); _recorderSubscription = null; } }
/// 釋放錄音
Future
/// 判斷檔案是否存在
Future
播放常見的方法
初始化播放器
flutter
FlutterSoundPlayer playerModule = FlutterSoundPlayer();
初始化操作
```flutter init() async { await playerModule.closePlayer(); await playerModule.openPlayer(); await playerModule .setSubscriptionDuration(const Duration(milliseconds: 10));
//這塊是設定音訊,暫時沒用到可以不用設定 final session = await AudioSession.instance; await session.configure(AudioSessionConfiguration( avAudioSessionCategory: AVAudioSessionCategory.playAndRecord, avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.allowBluetooth | AVAudioSessionCategoryOptions.defaultToSpeaker, avAudioSessionMode: AVAudioSessionMode.spokenAudio, avAudioSessionRouteSharingPolicy: AVAudioSessionRouteSharingPolicy.defaultPolicy, avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none, androidAudioAttributes: const AndroidAudioAttributes( contentType: AndroidAudioContentType.speech, flags: AndroidAudioFlags.none, usage: AndroidAudioUsage.voiceCommunication, ), androidAudioFocusGainType: AndroidAudioFocusGainType.gain, androidWillPauseWhenDucked: true, )); } ```
開始播放
```flutter ///開始播放,這裡做了一個播放狀態的回撥 void startPlayer(PlayStateBack callBack) async { try { if (path.contains('http')) { await playerModule.startPlayer( fromURI: path, codec: Codec.mp3, sampleRate: 44000, whenFinished: () { stopPlayer(); callBack(0); }); } else { //判斷檔案是否存在 if (await _fileExists(path)) { if (playerModule.isPlaying) { playerModule.stopPlayer(); } await playerModule.startPlayer( fromURI: path, codec: Codec.aacADTS, sampleRate: 44000, whenFinished: () { stopPlayer(); callBack(0); }); } else {} }
//監聽播放進度
_playerSubscription = playerModule.onProgress!.listen((e) {});
callBack(1);
} catch (err) { callBack(0); } } ```
結束播放
```flutter /// 結束播放 void stopPlayer() async { try { await playerModule.stopPlayer(); cancelPlayerSubscriptions(); } catch (err) {} }
/// 取消播放監聽 void cancelPlayerSubscriptions() { if (_playerSubscription != null) { _playerSubscription!.cancel(); _playerSubscription = null; } }
///獲取播放狀態
Future
/// 釋放播放器 void releaseFlauto() async { try { await playerModule.closePlayer(); } catch (e) { print(e); } }
/// 判斷檔案是否存在
Future
動畫實現
在進行錄音和播放的過程中難免使用到動畫,這裡我說下如何載入gif和動畫檔案
載入GIF動畫
flutter
Visibility(
visible: (item.playing.value == 1) ? true : false,
child: Image.asset('assets/-comm/comm_audio_paly.gif', width: 20, height: 20,),
replacement: const Image(
image: AssetImage('assets/-comm/comm_audio_icon.png'),
width: 20,
height: 20,
),
)
載入動畫檔案
flutter
Lottie.asset('assets/-comm/record_audio_animation.json',
height: 25,
width: ScreenAdapter.screenWidth() -ScreenAdapter.width(160),
animate: true)
上傳檔案
上傳音訊檔案
flutter
var map = {
"file": MultipartFile.fromBytes(
await File.fromUri(Uri(path: path)).readAsBytes(),
filename: "$fileName.mp3",
contentType: MediaType.parse("audio/mp3"))
};
總結
上面介紹瞭如何錄音,如何播放本地和遠端音訊檔案,以及如何實現動畫,在錄製完音訊檔案後如何上傳,這些都是我們平常使用這個功能會遇到的問題。在使用的過程中遇到的問題也有列出,希望對您有所幫助。 這裡有記錄整合到原生專案遇到的問題。
- Flutter:仿京東專案實戰(4)-購物車頁面功能實現
- Flutter整合原生遇到的問題彙總
- Flutter:仿京東專案實戰(3)-商品詳情頁功能實現
- Flutter-Dart中的非同步和多執行緒講解
- iOS-底層原理分析之Block本質
- Flutter-官方推薦的Flutter與原生互動外掛Pigeon
- Flutter-flutter_sound錄音與播放
- iOS-CocoaPods的原理及Podfile.lock問題
- iOS配置多環境的三種方案
- iOS-各種Crash防護
- iOS-Swift中常見的幾種閉包
- Flutter:仿京東專案實戰(2)-分類和商品列表頁面功能實現
- Flutter:仿京東專案實戰(1)-首頁功能實現
- Flutter-JSON轉Model的四種便捷方案
- Flutter-導航與路由堆疊詳解
- Flutter 與原生通訊的三種方式
- iOS-記憶體洩漏檢測
- Fastlane實現自動打包
- 懶人必備神器-Xcode程式碼塊
- Jenkins實現自動化打包