Flutter音频编码插件dart_lame的使用
Flutter音频编码插件dart_lame的使用
功能
- 将WAV(PCM-16 或 PCM IEEE Double)编码为MP3。
开始使用
要使用此库,您必须在系统上安装libmp3lame
。请确保以下库在您的系统上可用或将其放置在程序的工作目录下:
- Windows:
mp3lame.dll
- Linux:
libmp3lame.so
- macOS:
libmp3lame.dylib
另外,您可以手动加载libmp3lame
:
import 'dart:ffi' as ffi;
import 'package:dart_lame/dart_lame.dart' as lame;
class CustomLoader extends lame.LameLibraryLoader {
@override
ffi.DynamicLibrary load() {
return ffi.DynamicLibrary.open("path_to_libmp3lame");
}
}
lame.lameLoader = CustomLoader();
对于Flutter用户,请使用flutter_lame代替。
使用示例
import 'dart:io';
import 'dart:typed_data';
import 'package:dart_lame/dart_lame.dart';
final File f = File("output.mp3");
final IOSink sink = f.openWrite();
final LameMp3Encoder encoder = LameMp3Encoder(sampleRate: 44100, numChannels: 2);
Float64List leftChannelSamples;
Float64List rightChannelSamples;
// 获取来自文件或麦克风的样本。
final mp3Frame = await encoder.encode(
leftChannel: leftChannelSamples,
rightChannel: rightChannelSamples);
sink.add(mp3Frame);
// 继续直到所有样本已编码
// 最后,刷新编码器缓冲区
final lastMp3Frame = await encoder.flush();
sink.add(lastMp3Frame);
完整示例
对于完整的示例,请查看/example
文件夹中的代码。
示例代码
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:args/args.dart';
import 'package:dart_lame/dart_lame.dart';
import 'package:wav/wav.dart';
void main(List<String> arguments) async {
print("dart_lame example");
final parser = ArgParser()
..addOption("format",
abbr: "f",
allowed: ["wav", "pcm16"],
help:
"输入文件格式。注意:如果格式为pcm16,则仅接受单声道文件",
defaultsTo: "wav")
..addOption("sample-rate",
abbr: "s",
help:
"输入文件的采样率。如果输入格式为pcm16,则为必需项")
..addOption("input", abbr: "i", help: "输入文件", mandatory: true)
..addOption("output",
abbr: "o", help: "输出mp3文件", defaultsTo: "output.mp3");
final argResults = parser.parse(arguments);
print('LAME版本: ${getLameVersion()}');
final String inputPath = argResults["input"];
print("输入文件: $inputPath");
print("编码中...");
final String outputPath = argResults["output"];
final File f = File(outputPath);
final IOSink sink = f.openWrite();
try {
if (argResults["format"] == "wav") {
final wav = await Wav.readFile(inputPath);
await encodeWav(wav, sink);
} else {
String? sampleRate = argResults["sample-rate"];
if (sampleRate == null) {
throw ArgumentError("--sample-rate 是必需的");
}
await encodePcm(inputPath, sink, int.parse(sampleRate));
}
} finally {
sink.close();
}
print("成功编码mp3文件: ${f.absolute}");
}
Future encodeWav(Wav wav, IOSink sink) async {
final encoder = LameMp3Encoder(
sampleRate: wav.samplesPerSecond, numChannels: wav.channels.length);
try {
final left = wav.channels[0];
Float64List? right;
if (wav.channels.length > 1) {
right = wav.channels[1];
}
for (int i = 0; i < left.length; i += wav.samplesPerSecond) {
final mp3Frame = await encoder.encodeDouble(
leftChannel: left.sublist(i, i + wav.samplesPerSecond),
rightChannel: right?.sublist(i, i + wav.samplesPerSecond));
sink.add(mp3Frame);
}
sink.add(await encoder.flush());
} finally {
encoder.close();
}
}
Future encodePcm(String inputPath, IOSink sink, int sampleRate) async {
final encoder = LameMp3Encoder(sampleRate: sampleRate, numChannels: 1);
final File inputFile = File(inputPath);
final Completer readCompleter = Completer();
final Completer encodeCompleter = Completer();
int counter = 0;
final StreamSubscription<List<int>> sub = inputFile.openRead().listen(
(event) async {
counter++;
final Uint8List mp3frame = await encoder.encode(
leftChannel: Uint8List.fromList(event).buffer.asInt16List());
sink.add(mp3frame);
counter--;
if (readCompleter.isCompleted) {
if (counter == 0) {
encodeCompleter.complete();
}
}
},
onDone: () => readCompleter.complete(),
onError: (e) => readCompleter.completeError(e));
try {
await readCompleter.future;
await encodeCompleter.future;
final lastMp3Frame = await encoder.flush();
sink.add(lastMp3Frame);
} finally {
sub.cancel();
encoder.close();
}
}
更多关于Flutter音频编码插件dart_lame的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter音频编码插件dart_lame的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
dart_lame
是一个用于 Flutter 的音频编码插件,它允许你将原始的 PCM 音频数据编码为 MP3 格式。这个插件是基于 LAME
库的,LAME
是一个开源的 MP3 编码器。
以下是如何在 Flutter 项目中使用 dart_lame
插件的步骤:
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 dart_lame
依赖:
dependencies:
flutter:
sdk: flutter
dart_lame: ^0.2.0 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
2. 导入库
在你的 Dart 文件中导入 dart_lame
库:
import 'package:dart_lame/dart_lame.dart';
3. 初始化编码器
你需要初始化一个 LameEncoder
对象来开始编码音频数据。你可以指定采样率、通道数、比特率等参数。
final encoder = LameEncoder(
sampleRate: 44100, // 采样率 (Hz)
numChannels: 2, // 通道数 (1 为单声道,2 为立体声)
bitRate: 128, // 比特率 (kbps)
);
4. 编码音频数据
你可以使用 encoder.encode
方法将 PCM 音频数据编码为 MP3 格式。这个方法接受一个 List<int>
类型的 PCM 数据,并返回一个 List<int>
类型的 MP3 数据。
List<int> pcmData = ...; // 你的 PCM 音频数据
List<int> mp3Data = encoder.encode(pcmData);
5. 结束编码
在编码完成后,你需要调用 encoder.close
方法来释放资源并获取最终的 MP3 数据。
List<int> finalMp3Data = encoder.close();
6. 保存或处理 MP3 数据
你可以将 finalMp3Data
保存为文件或进行其他处理。
import 'dart:io';
void saveMp3File(List<int> mp3Data, String filePath) {
final file = File(filePath);
file.writeAsBytesSync(mp3Data);
}
saveMp3File(finalMp3Data, 'output.mp3');
完整示例
以下是一个完整的示例,展示如何使用 dart_lame
将 PCM 音频数据编码为 MP3 文件:
import 'package:dart_lame/dart_lame.dart';
import 'dart:io';
void main() async {
// 假设你有一个 PCM 文件
final pcmFile = File('input.pcm');
final pcmData = await pcmFile.readAsBytes();
// 初始化编码器
final encoder = LameEncoder(
sampleRate: 44100,
numChannels: 2,
bitRate: 128,
);
// 编码 PCM 数据
List<int> mp3Data = encoder.encode(pcmData);
// 结束编码并获取最终的 MP3 数据
List<int> finalMp3Data = encoder.close();
// 保存 MP3 文件
final mp3File = File('output.mp3');
await mp3File.writeAsBytes(finalMp3Data);
print('MP3 文件已保存');
}