Flutter音频处理插件wav_io的使用

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

Flutter音频处理插件 wav_io 的使用

wav_io 是一个用于读取和写入 WAVE 文件的简单插件。它支持多种PCM格式(16位、24位、32位)以及浮点格式(32位、64位),并支持RIFX格式(大端版本)。该插件适用于编写WAV实用程序。

主要功能

  • 支持读取/写入 16bit/24bit/32bit PCM 文件。
  • 支持读取/写入 32bit/64bit 浮点文件。
  • 支持读取/写入 RIFX 格式(大端版本)。
  • 可以用于编写 WAV 实用程序。

开始使用

首先,在你的 pubspec.yaml 文件中添加 wav_io 包:

dependencies:
  wav_io: ^0.1.0

然后运行以下命令来安装依赖:

flutter pub get

使用示例

示例1:生成正弦波并存储为WAV文件 (sine.dart)

这个例子展示了如何生成一个正弦波并将它存储在WAV文件中。你可以通过命令行参数指定采样率、持续时间、频率和输出格式。

命令行使用方法:

dart example/lib/sine.dart --samplerate <sr> --duration <duration in seconds> --freq <note frequency> --format <i16|i24|i32|f32|f64> -o output.wav

示例代码:

import 'package:wav_io/wav_io.dart';

void main(List<String> arguments) {
  // 解析命令行参数
  final parser = ArgParser();
  parser.addOption('samplerate', abbr: 'r', defaultsTo: '44100');
  parser.addOption('duration', abbr: 'd', defaultsTo: '5');
  parser.addOption('freq', abbr: 'f', defaultsTo: '440');
  parser.addOption('format', abbr: 'fmt', defaultsTo: 'f32');
  parser.addOption('output', abbr: 'o', defaultsTo: 'output.wav');

  final results = parser.parse(arguments);

  final sampleRate = int.parse(results['samplerate']);
  final duration = double.parse(results['duration']);
  final freq = double.parse(results['freq']);
  final format = results['format'];
  final outputPath = results['output'];

  // 生成正弦波数据
  final waveData = generateSineWave(sampleRate, duration, freq, format);

  // 创建WAV文件
  final wavFile = WavFile(
    format: _getFormat(format),
    channels: [waveData],
    sampleRate: sampleRate,
  );

  // 写入文件
  wavFile.write(outputPath);
}

List<double> generateSineWave(int sampleRate, double duration, double freq, String format) {
  final samples = (sampleRate * duration).toInt();
  final data = List<double>.generate(samples, (index) {
    return sin(2 * pi * freq * index / sampleRate);
  });

  if (format == 'i16') {
    return data.map((e) => (e * 32767).toInt()).cast<double>().toList();
  } else if (format == 'i24' || format == 'i32') {
    return data.map((e) => (e * 8388607).toInt()).cast<double>().toList();
  } else {
    return data;
  }
}

AudioFormat _getFormat(String format) {
  switch (format) {
    case 'i16':
      return AudioFormat.int16;
    case 'i24':
      return AudioFormat.int24;
    case 'i32':
      return AudioFormat.int32;
    case 'f32':
      return AudioFormat.float32;
    case 'f64':
      return AudioFormat.float64;
    default:
      throw ArgumentError('Unsupported format $format');
  }
}

示例2:合并多个WAV文件 (concat.dart)

这个例子展示了如何将多个WAV文件合并成一个长的WAV文件。

命令行使用方法:

dart example/lib/concat.dart <in1> <in2> <in3> ... -o output.wav

示例代码:

import 'package:wav_io/wav_io.dart';
import 'dart:io';

void main(List<String> arguments) {
  final parser = ArgParser();
  parser.addOption('output', abbr: 'o', defaultsTo: 'output.wav');

  final results = parser.parse(arguments);
  final inputFiles = results.rest;
  final outputPath = results['output'];

  if (inputFiles.isEmpty) {
    print('No input files specified.');
    return;
  }

  // 读取所有输入文件
  final waves = inputFiles.map((file) => WavFile.read(File(file).readAsBytesSync())).toList();

  // 检查所有文件是否具有相同的采样率和通道数
  for (var i = 1; i < waves.length; i++) {
    if (waves[i].sampleRate != waves[0].sampleRate ||
        waves[i].channels.length != waves[0].channels.length) {
      print('Input files must have the same sample rate and number of channels.');
      return;
    }
  }

  // 合并通道数据
  final combinedChannels = List.generate(waves[0].channels.length, (_) => <double>[]);

  for (var wave in waves) {
    for (var i = 0; i < wave.channels.length; i++) {
      combinedChannels[i].addAll(wave.channels[i]);
    }
  }

  // 创建新的WAV文件
  final newWave = WavFile(
    format: waves[0].format,
    channels: combinedChannels,
    sampleRate: waves[0].sampleRate,
  );

  // 写入文件
  newWave.write(outputPath);
}

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

1 回复

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


当然,wav_io 是一个用于在 Flutter 中处理 WAV 音频文件的 Dart 插件。以下是如何在 Flutter 项目中使用 wav_io 插件来读取和写入 WAV 音频文件的示例代码。

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

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

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

读取 WAV 文件

以下是如何读取 WAV 文件的示例代码:

import 'dart:io';
import 'package:wav_io/wav_io.dart';
import 'package:flutter/material.dart';

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

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

class _MyAppState extends State<MyApp> {
  List<int>? audioData;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('WAV IO Demo'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _loadWavFile,
            child: Text('Load WAV File'),
          ),
        ),
      ),
    );
  }

  Future<void> _loadWavFile() async {
    final File file = File('path/to/your/audiofile.wav'); // 替换为你的 WAV 文件路径
    final WavHeader header = await WavHeader.fromBytes(await file.readAsBytes());
    final List<int> pcmData = await file.readAsBytes(header.dataChunkSize);

    setState(() {
      audioData = pcmData;
      // 这里你可以处理 pcmData,比如播放或进一步处理
    });
  }
}

写入 WAV 文件

以下是如何写入 WAV 文件的示例代码。这里假设你已经有一些 PCM 数据想要保存为 WAV 文件:

import 'dart:io';
import 'package:wav_io/wav_io.dart';
import 'package:flutter/material.dart';

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

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

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('WAV IO Demo'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _saveWavFile,
            child: Text('Save WAV File'),
          ),
        ),
      ),
    );
  }

  Future<void> _saveWavFile() async {
    final List<int> pcmData = List<int>.filled(44100 * 2 * 2, 0); // 1秒长的静音数据,44100 Hz, 立体声, 16位深度
    final int sampleRate = 44100;
    final int numChannels = 2;
    final int bitsPerSample = 16;
    final int byteRate = sampleRate * numChannels * bitsPerSample ~/ 8;
    final int blockSize = numChannels * bitsPerSample ~/ 8;

    final WavHeader header = WavHeader(
      numChannels: numChannels,
      sampleRate: sampleRate,
      byteRate: byteRate,
      blockSize: blockSize,
      bitsPerSample: bitsPerSample,
      dataChunkSize: pcmData.length,
    );

    final File file = File('output_audiofile.wav');
    final List<int> wavData = header.toBytes() + pcmData;

    await file.writeAsBytes(wavData);

    // 显示保存成功的Snackbar(可选)
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
      content: Text('WAV file saved successfully!'),
    ));
  }
}

注意事项

  1. 文件路径:确保你提供的文件路径是正确的,并且设备有权限访问该路径。在 Android 上,你可能需要在 AndroidManifest.xml 中请求存储权限。
  2. PCM 数据:在读取 WAV 文件后,你得到的 PCM 数据需要进一步处理(如解码或播放)。在写入 WAV 文件时,你需要提供正确的 PCM 数据。
  3. 错误处理:在实际应用中,添加错误处理逻辑是很重要的,比如处理文件不存在或读取失败的情况。

这样,你就可以在 Flutter 项目中使用 wav_io 插件来处理 WAV 音频文件了。

回到顶部