Flutter音频输入输出插件audio_io的使用

Flutter音频输入输出插件audio_io的使用

audio_io

目标

简单地将音频数据从平台传输到Flutter。 最小化代码以将PCM数据导入Dart环境进行跨平台处理/录制/可视化。

输入音频流为列表

目前仅支持iOS。

开始使用

此项目是一个Flutter插件包的起点, 这是一种包含针对Android和/或iOS的特定平台实现代码的专门包。

对于如何开始使用Flutter的帮助,请参阅我们的在线文档,其中提供了教程、示例、移动开发指南以及完整的API参考。


示例代码

example/lib/main.dart

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

import 'package:flutter/services.dart';
import 'package:audio_io/audio_io.dart';

void main() => runApp(MyApp());

// 定义延迟值映射
final _latencyValues = {
  AudioIoLatency.Realtime: '实时',
  AudioIoLatency.Balanced: '平衡',
  AudioIoLatency.Powersave: '省电模式',
};

// 主应用状态类
class MyApp extends StatefulWidget {
  [@override](/user/override)
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _status = '未知';
  AudioIoLatency _latencyValue = AudioIoLatency.Balanced;

  [@override](/user/override)
  void initState() {
    super.initState();
    initPlatformState();
  }

  // 平台消息异步初始化
  Future<void> initPlatformState() async {
    AudioIo.instance.input.listen((data) {
      // 将输入数据乘以0.9后发送到输出
      final out = List<double>.generate(
          data.length, (index) => data[index] * 0.9); 
      AudioIo.instance.output.add(out); // 发送到输出(耳机扬声器或耳机)
    });

    if (!mounted) return;
    setState(() {
      _status = _status;
    });
  }

  // 启动音频
  void startAudio() async {
    try {
      await AudioIo.instance.start();
      final latency = await AudioIo.instance.currentLatency();
      final lstring = latency.toStringAsPrecision(2);
      final format = await AudioIo.instance.getFormat();
      setState(() {
        _status = '已启动 ($lstring 毫秒)';
      });
      print(format);
    } on PlatformException {
      setState(() {
        _status = '失败';
      });
    }
  }

  // 停止音频
  void stopAudio() async {
    try {
      await AudioIo.instance.stop();
      setState(() {
        _status = '已停止';
      });
    } on PlatformException {
      setState(() {
        _status = '失败';
      });
    }
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: Center(
          child: Column(children: [
            latencyDropdown(context), // 延迟选择框
            Text('状态: $_status\n'),
            TextButton(onPressed: startAudio, child: Text('开始')), // 开始按钮
            TextButton(onPressed: stopAudio, child: Text('停止')), // 停止按钮
          ]),
        ),
      ),
    );
  }

  // 延迟选择框
  Widget latencyDropdown(BuildContext context) {
    return DropdownButton<AudioIoLatency>(
      value: _latencyValue,
      icon: Icon(Icons.arrow_downward),
      iconSize: 24,
      elevation: 16,
      underline: Container(
        height: 2,
        color: Colors.blueAccent,
      ),
      onChanged: (AudioIoLatency? newValue) {
        if (newValue != null) {
          setState(() {
            _latencyValue = newValue;
          });
        }
      },
      items: AudioIoLatency.values
          .map<DropdownMenuItem<AudioIoLatency>>((AudioIoLatency value) {
        return DropdownMenuItem<AudioIoLatency>(
          value: value,
          child: Text(_latencyValues[value]!),
        );
      }).toList(),
    );
  }
}

更多关于Flutter音频输入输出插件audio_io的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter音频输入输出插件audio_io的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用audio_io插件来实现音频输入和输出的代码案例。audio_io插件允许你处理音频数据的录制和播放,但请注意,由于插件和API可能会随时间更新,请参考最新的插件文档以确保兼容性。

首先,确保你已经在pubspec.yaml文件中添加了audio_io依赖:

dependencies:
  flutter:
    sdk: flutter
  audio_io: ^x.y.z  # 替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来是一个简单的示例,演示如何使用audio_io进行音频录制和播放:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AudioIOExample(),
    );
  }
}

class AudioIOExample extends StatefulWidget {
  @override
  _AudioIOExampleState createState() => _AudioIOExampleState();
}

class _AudioIOExampleState extends State<AudioIOExample> {
  late AudioIO _audioIO;
  late AudioRecorder _recorder;
  late AudioPlayer _player;
  bool _isRecording = false;
  bool _isPlaying = false;

  @override
  void initState() {
    super.initState();
    _audioIO = AudioIO();
    _recorder = AudioRecorder(audioIO: _audioIO);
    _player = AudioPlayer(audioIO: _audioIO);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Audio IO Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: _isRecording ? null : _startRecording,
              child: Text(_isRecording ? 'Stop Recording' : 'Start Recording'),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _isPlaying ? null : _playRecording,
              child: Text(_isPlaying ? 'Stop Playing' : 'Play Recording'),
            ),
          ],
        ),
      ),
    );
  }

  void _startRecording() async {
    setState(() {
      _isRecording = true;
    });

    try {
      final recording = await _recorder.start(path: 'example.wav');
      // 停止录制,这里我们假设录制5秒作为示例
      Future.delayed(Duration(seconds: 5), () {
        _stopRecording(recording);
      });
    } catch (e) {
      print('Recording error: $e');
      setState(() {
        _isRecording = false;
      });
    }
  }

  void _stopRecording(AudioRecording recording) async {
    await recording.stop();
    print('Recording stopped');
    setState(() {
      _isRecording = false;
    });
  }

  void _playRecording() async {
    setState(() {
      _isPlaying = true;
    });

    try {
      final player = await _player.start(path: 'example.wav');
      // 停止播放,这里我们假设播放5秒作为示例
      Future.delayed(Duration(seconds: 5), () {
        _stopPlaying(player);
      });
    } catch (e) {
      print('Playing error: $e');
      setState(() {
        _isPlaying = false;
      });
    }
  }

  void _stopPlaying(AudioPlayer player) async {
    await player.stop();
    print('Playing stopped');
    setState(() {
      _isPlaying = false;
    });
  }

  @override
  void dispose() {
    _recorder.dispose();
    _player.dispose();
    super.dispose();
  }
}

说明

  1. 依赖安装:确保在pubspec.yaml中添加了audio_io依赖,并运行flutter pub get
  2. 初始化:在initState方法中初始化AudioIOAudioRecorderAudioPlayer实例。
  3. 录制音频:使用_recorder.start(path: 'example.wav')开始录制音频,并假设录制5秒后自动停止。
  4. 播放音频:使用_player.start(path: 'example.wav')开始播放录制的音频文件,并假设播放5秒后自动停止。
  5. UI交互:使用按钮控制录制和播放的开始与停止,并根据状态更新按钮文本。
  6. 资源释放:在dispose方法中释放AudioRecorderAudioPlayer实例,以避免内存泄漏。

请注意,这只是一个基础示例,实际应用中你可能需要处理更多的错误情况,并根据具体需求调整录制和播放的逻辑。

回到顶部