欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于flutter?sound插件實現(xiàn)錄音與播放功能

 更新時間:2022年05月18日 10:33:41   作者:周糖果  
這篇文章主要介紹了基于flutter?sound插件實現(xiàn)錄音與播放功能,介紹了如何錄音,如何播放本地和遠程音頻文件,以及如何實現(xiàn)動畫,在錄制完音頻文件后如何上傳,這些都是我們平常使用這個功能會遇到的問題。在使用的過程中遇到的問題也有列出,需要的朋友可以參考下

插件介紹:

flutter_sound這個插件可以實現(xiàn)iOS和Android平臺的錄音和播放功能。即可以播放本地音頻文件,也可以播放遠程URL文件。在這里我講介紹這個插件的用法以及碰到的一些常見問題如何解決。

  • flutter_sound支持多種錄音格式

  • flutter_sound支持多種播放格式

  • flutter_sound支持音頻振幅大小

插件信息:

插件地址:github.com/ryanheise/a…

插件版本:9.2.9

插件使用前的準備工作

設置麥克風權限描述

  • iOS:需要在info.plist文件添加一下權限
<key>NSMicrophoneUsageDescription</key>
<string>描述你使用麥克風用來干嘛</string>

注意:還需要在Podfile文件中配置

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
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

這里還用了下面幾個插件

權限管理插件 permission_handler

插件信息:permission_handler: ^9.2.0

插件地址:pub.flutter-io.cn/packages/pe…

音頻硬件配置插件 audio_session

插件信息:audio_session: ^0.1.6

插件地址:github.com/ryanheise/a…

動畫插件

插件信息:lottie: 1.2.1

插件地址:pub.flutter-io.cn/packages/fl…

常用的方法

錄音常見的方法

初始化錄音對象

FlutterSoundRecorder recorderModule = FlutterSoundRecorder();

開啟錄音

Future<void> init() async {
  //開啟錄音
  await recorderModule.openRecorder();
  //設置訂閱計時器
  await recorderModule
      .setSubscriptionDuration(const Duration(milliseconds: 10));
  //初始化日期插件
  await initializeDateFormatting();
}

麥克風權限

Future<bool> getPermissionStatus() async {
  Permission permission = Permission.microphone;
  //granted 通過,denied 被拒絕,permanentlyDenied 拒絕且不在提示
  PermissionStatus status = await permission.status;
  if (status.isGranted) {
    return true;
  } else if (status.isDenied) {
    requestPermission(permission);
  } else if (status.isPermanentlyDenied) {
    openAppSettings();
  } else if (status.isRestricted) {
    requestPermission(permission);
  } else {}
  return false;
}

///申請權限
void requestPermission(Permission permission) async {
  PermissionStatus status = await permission.request();
  if (status.isPermanentlyDenied) {
    openAppSettings();
  }
}

開始錄音

/// 開始錄音
_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,
      );
      /// 監(jiān)聽錄音
      _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(() {
         //更新錄音狀態(tài)和錄音文件路徑
        _state = RecordPlayState.recording;
        _path = path;
      });
    });
  } catch (err) {
    setState(() {
      _stopRecorder();
      _state = RecordPlayState.record;
      _cancelRecorderSubscriptions();
    });
  }
}

結束錄音

/// 結束錄音
_stopRecorder() async {
  try {
    await recorderModule.stopRecorder();
    _cancelRecorderSubscriptions();
    // _getDuration();
  } catch (err) {}
  setState(() {
    _state = RecordPlayState.record;
  });
}
///銷毀錄音
void dispose() {
  super.dispose();
  _cancelRecorderSubscriptions();
  _releaseFlauto();
}
/// 取消錄音監(jiān)聽
void _cancelRecorderSubscriptions() {
  if (_recorderSubscription != null) {
    _recorderSubscription!.cancel();
    _recorderSubscription = null;
  }
}
/// 釋放錄音
Future<void> _releaseFlauto() async {
  try {
    await recorderModule.closeRecorder();
  } catch (e) {}
}
/// 判斷文件是否存在
Future<bool> _fileExists(String path) async {
  return await File(path).exists();
}

播放常見的方法

初始化播放器

FlutterSoundPlayer playerModule = FlutterSoundPlayer();

初始化操作

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,
  ));
}

開始播放

///開始播放,這里做了一個播放狀態(tài)的回調(diào)
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 {}
    }
    //監(jiān)聽播放進度
    _playerSubscription = playerModule.onProgress!.listen((e) {});
    callBack(1);
  } catch (err) {
    callBack(0);
  }
}

結束播放

/// 結束播放
void stopPlayer() async {
  try {
    await playerModule.stopPlayer();
    cancelPlayerSubscriptions();
  } catch (err) {}
}
/// 取消播放監(jiān)聽
void cancelPlayerSubscriptions() {
  if (_playerSubscription != null) {
    _playerSubscription!.cancel();
    _playerSubscription = null;
  }
}
///獲取播放狀態(tài)
Future<PlayerState> getPlayState() async {
  return await playerModule.getPlayerState();
}
/// 釋放播放器
void releaseFlauto() async {
  try {
    await playerModule.closePlayer();
  } catch (e) {
    print(e);
  }
}
/// 判斷文件是否存在
Future<bool> _fileExists(String path) async {
  return await File(path).exists();
}

動畫實現(xiàn)

在進行錄音和播放的過程中難免使用到動畫,這里我說下如何加載gif和動畫文件

加載GIF動畫

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,
  ),
)

加載動畫文件

Lottie.asset('assets/-comm/record_audio_animation.json',
    height: 25,
    width: ScreenAdapter.screenWidth() -ScreenAdapter.width(160),
    animate: true)

上傳文件

上傳音頻文件

var map = {
  "file": MultipartFile.fromBytes(
      await File.fromUri(Uri(path: path)).readAsBytes(),
      filename: "$fileName.mp3",
      contentType: MediaType.parse("audio/mp3"))
};

總結

上面介紹了如何錄音,如何播放本地和遠程音頻文件,以及如何實現(xiàn)動畫,在錄制完音頻文件后如何上傳,這些都是我們平常使用這個功能會遇到的問題。在使用的過程中遇到的問題也有列出,希望對您有所幫助。

到此這篇關于基于flutter sound插件實現(xiàn)錄音與播放功能的文章就介紹到這了,更多相關flutter sound錄音與播放內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論