Flutter音频流处理插件mp_audio_stream的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter音频流处理插件mp_audio_stream的使用

Features

  • 持续播放44.1kHz缓冲音频数据,直到缓冲区为空
  • 支持格式:float32多声道
  • 支持所有Flutter平台:Android、iOS、macOS、Linux、Windows和Web平台
    • Web平台实现依赖于WebAudio和AudioWorkletProcessor
    • 其他平台利用miniaudio,一个出色的多平台音频库

Getting started

在您的项目中添加mp_audio_stream插件:

flutter pub add mp_audio_stream

Usage

以下是一个完整的示例demo,演示了如何使用mp_audio_stream生成并播放立体声正弦波PCM流:

示例代码

import 'dart:math' as math;
import 'dart:async';
import 'dart:typed_data';

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('MP Audio Stream Example')),
        body: Center(child: AudioStreamWidget()),
      ),
    );
  }
}

class AudioStreamWidget extends StatefulWidget {
  @override
  _AudioStreamWidgetState createState() => _AudioStreamWidgetState();
}

class _AudioStreamWidgetState extends State<AudioStreamWidget> with WidgetsBindingObserver {
  final audioStream = getAudioStream();
  bool isPlaying = false;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);

    // 初始化音频流
    audioStream.init(channels: 2);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed && !isPlaying) {
      startPlayback();
    }
  }

  void startPlayback() async {
    isPlaying = true;

    // For web platform, call this after user interaction
    await audioStream.resume();

    const rate = 44100;
    const freqL = 440;
    const freqR = 660;
    const dur = 10;

    Float32List samples = Float32List(rate * 2); // stereo

    for (var t = 0; t < dur; t++) {
      int pos = 0;

      for (var i = 0; i < rate; i++) {
        samples[pos++] = math.sin(2 * math.pi * ((i * freqL) % rate) / rate);
        samples[pos++] = math.sin(2 * math.pi * ((i * freqR) % rate) / rate);

        if (pos == samples.length) {
          pos = 0;

          // playback the generated PCM stream
          audioStream.push(samples);
        }
      }
      await Future.delayed(const Duration(seconds: 1));
    }

    isPlaying = false;
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    audioStream.uninit();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {
        if (!isPlaying) {
          startPlayback();
        }
      },
      child: Text(isPlaying ? 'Playing...' : 'Start Playback'),
    );
  }
}

说明

  • 初始化:在initState方法中初始化音频流。
  • 播放控制:通过按钮点击或应用恢复状态触发播放。
  • 生成音频数据:根据指定频率生成立体声音频数据,并推送到音频流中进行播放。
  • 清理资源:在dispose方法中释放音频流资源。

更多API文档,请访问pub.dev。一个可运行的Flutter示例应用程序位于/example/目录下。

For developers

如果您需要更新miniaudio子模块,请执行以下命令:

git submodule update --init

以上是关于Flutter音频流处理插件mp_audio_stream的使用介绍及完整示例demo。希望对您有所帮助!


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

1 回复

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


当然,以下是如何在Flutter项目中使用mp_audio_stream插件来处理音频流的示例代码。这个插件允许你从麦克风或其他音频源获取音频流,并进行实时处理。

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

dependencies:
  flutter:
    sdk: flutter
  mp_audio_stream: ^最新版本号  # 请替换为实际的最新版本号

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

接下来,在你的Flutter项目中,你可以按照以下步骤来使用mp_audio_stream插件。

1. 导入必要的包

在你的Dart文件中导入mp_audio_stream包:

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

2. 配置权限

由于音频流处理需要访问麦克风,你需要在AndroidManifest.xmlInfo.plist中配置相应的权限。

Android (AndroidManifest.xml)

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

iOS (Info.plist)

<key>NSMicrophoneUsageDescription</key>
<string>需要麦克风权限来录制音频</string>

3. 使用MpAudioStream进行音频流处理

以下是一个完整的示例,展示了如何使用MpAudioStream从麦克风获取音频流并进行简单的处理(例如,将音频数据转换为PCM格式并打印出来):

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late MpAudioStream _audioStream;

  @override
  void initState() {
    super.initState();
    _initAudioStream();
  }

  @override
  void dispose() {
    _audioStream.close();
    super.dispose();
  }

  Future<void> _initAudioStream() async {
    // 请求麦克风权限(在实际应用中,应该使用更健壮的权限请求逻辑)
    bool hasPermission = await Permission.microphone.request().isGranted;
    if (!hasPermission) {
      // 处理权限被拒绝的情况
      return;
    }

    // 初始化音频流
    _audioStream = MpAudioStream(
      audioFormat: AudioFormat.pcm16,
      sampleRate: 44100,
      channelCount: 1,
    );

    // 监听音频数据
    _audioStream.audioData.listen((audioData) {
      // 这里可以处理音频数据,例如将其转换为PCM格式并打印出来
      List<int> pcmData = audioData.buffer.asUint8List();
      print('Received PCM data: $pcmData');
    });

    // 开始录音
    try {
      await _audioStream.start(audioSourceType: AudioSourceType.microphone);
    } catch (e) {
      print('Failed to start audio stream: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('MpAudioStream Demo'),
        ),
        body: Center(
          child: Text('正在从麦克风获取音频流...'),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            // 停止录音
            _audioStream.stop();
          },
          tooltip: 'Stop Recording',
          child: Icon(Icons.stop),
        ),
      ),
    );
  }
}

在这个示例中,我们首先请求麦克风权限,然后初始化MpAudioStream实例,并设置音频格式、采样率和通道数。接着,我们监听audioData流,该流会提供从麦克风获取的音频数据。最后,我们通过点击浮动操作按钮来停止录音。

请注意,这个示例代码仅用于演示目的,并可能需要根据你的实际需求进行调整。例如,你可能需要更复杂的权限请求逻辑,或者你可能希望将音频数据保存到文件而不是仅仅打印出来。

回到顶部