Flutter音频裁剪插件easy_audio_trimmer的使用
Flutter音频裁剪插件easy_audio_trimmer的使用
特性
- 在Flutter应用中修剪音频文件。
- 指定修剪音频文件的起始时间和结束时间。
- 音频播放控制。
- 获取并存储音频文件。
- 修剪后的音频文件保存在设备上。
- 使用简单,只需调用一个函数。
- 兼容大多数音频文件格式(如mp3, wav, aac等)。
- 支持iOS和Android平台。
示例
以下是easy_audio_trimmer
在Android设备上运行的演示:
使用方法
添加依赖
在你的pubspec.yaml
文件中添加easy_audio_trimmer
依赖:
dependencies:
easy_audio_trimmer: ^1.0.0
Android配置
无需额外配置即可在Android平台上使用。
iOS配置
- 设置
ios/Podfile
的平台版本为10
。
platform :ios, '10'
功能实现
加载输入音频文件
final Trimmer _trimmer = Trimmer();
await _trimmer.loadAudio(audioFile: widget.file);
保存修剪后的音频
_trimmer.saveTrimmedAudio(
startValue: _startValue,
endValue: _endValue,
audioFileName: DateTime.now().millisecondsSinceEpoch.toString(),
onSave: (outputPath) {
setState(() {
_progressVisibility = false;
});
debugPrint('OUTPUT PATH: $outputPath');
},
);
音频播放状态
await _trimmer.audioPlaybackControl(
startValue: _startValue,
endValue: _endValue,
);
小部件
显示音频修剪区域
TrimViewer(
trimmer: _trimmer,
viewerHeight: 50.0,
viewerWidth: MediaQuery.of(context).size.width,
maxAudioLength: const Duration(seconds: 10),
onChangeStart: (value) => _startValue = value,
onChangeEnd: (value) => _endValue = value,
allowAudioSelection: true,
onChangePlaybackState: (value) =>
setState(() => _isPlaying = value),
)
示例代码
您可以尝试通过替换新创建的Flutter项目的main.dart
文件来使用此示例。
import 'dart:io';
import 'package:example/trimmer_view.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: createMaterialColor(const Color(0xFF332FD0)),
),
home: const FileSelectorWidget());
}
}
class FileSelectorWidget extends StatefulWidget {
const FileSelectorWidget({super.key});
@override
State<FileSelectorWidget> createState() => _FileSelectorWidgetState();
}
class _FileSelectorWidgetState extends State<FileSelectorWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Audio Trimmer"),
),
body: Center(
child: ElevatedButton(
onPressed: () async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.audio,
allowCompression: false,
);
if (result != null) {
File file = File(result.files.single.path!);
// ignore: use_build_context_synchronously
Navigator.of(context).push(
MaterialPageRoute(builder: (context) {
return AudioTrimmerView(file);
}),
);
}
},
child: const Text("Select File")),
),
);
}
}
class AudioTrimmerView extends StatefulWidget {
final File file;
const AudioTrimmerView(this.file, {Key? key}) : super(key: key);
@override
State<AudioTrimmerView> createState() => _AudioTrimmerViewState();
}
class _AudioTrimmerViewState extends State<AudioTrimmerView> {
final Trimmer _trimmer = Trimmer();
double _startValue = 0.0;
double _endValue = 0.0;
bool _isPlaying = false;
bool _progressVisibility = false;
bool isLoading = false;
@override
void initState() {
super.initState();
_loadAudio();
}
void _loadAudio() async {
setState(() {
isLoading = true;
});
await _trimmer.loadAudio(audioFile: widget.file);
setState(() {
isLoading = false;
});
}
_saveAudio() {
setState(() {
_progressVisibility = true;
});
_trimmer.saveTrimmedAudio(
startValue: _startValue,
endValue: _endValue,
audioFileName: DateTime.now().millisecondsSinceEpoch.toString(),
onSave: (outputPath) {
setState(() {
_progressVisibility = false;
});
debugPrint('OUTPUT PATH: $outputPath');
},
);
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
if (Navigator.of(context).userGestureInProgress) {
return false;
} else {
return true;
}
},
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: const Text("Audio Trimmer"),
),
body: isLoading
? const CircularProgressIndicator()
: Center(
child: Container(
padding: const EdgeInsets.only(bottom: 30.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Visibility(
visible: _progressVisibility,
child: LinearProgressIndicator(
backgroundColor:
Theme.of(context).primaryColor.withOpacity(0.5),
),
),
ElevatedButton(
onPressed:
_progressVisibility ? null : () => _saveAudio(),
child: const Text("SAVE"),
),
AudioViewer(trimmer: _trimmer),
Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: TrimViewer(
trimmer: _trimmer,
viewerHeight: 100,
viewerWidth: MediaQuery.of(context).size.width,
durationStyle: DurationStyle.FORMAT_MM_SS,
backgroundColor: Theme.of(context).primaryColor,
barColor: Colors.white,
durationTextStyle: TextStyle(
color: Theme.of(context).primaryColor),
allowAudioSelection: true,
editorProperties: TrimEditorProperties(
circleSize: 10,
borderPaintColor: Colors.pink,
borderWidth: 4,
borderRadius: 5,
circlePaintColor: Colors.pink.shade800,
),
areaProperties:
TrimAreaProperties.edgeBlur(blurEdges: true),
onChangeStart: (value) => _startValue = value,
onChangeEnd: (value) => _endValue = value,
onChangePlaybackState: (value) {
if (mounted) {
setState(() => _isPlaying = value);
}
},
),
),
),
TextButton(
child: _isPlaying
? Icon(
Icons.pause,
size: 80.0,
color: Theme.of(context).primaryColor,
)
: Icon(
Icons.play_arrow,
size: 80.0,
color: Theme.of(context).primaryColor,
),
onPressed: () async {
bool playbackState =
await _trimmer.audioPlaybackControl(
startValue: _startValue,
endValue: _endValue,
);
setState(() => _isPlaying = playbackState);
},
)
],
),
),
),
),
);
}
}
排查问题
如果在Android平台上遇到minSdkVersion
需要设置为24
的错误,或者在iOS平台上遇到Podfile平台版本应设置为11
的错误,首先检查pubspec.lock
文件中的ffmpeg_kit_flutter
版本是否有-LTS
后缀。这应该可以解决iOS平台上的所有问题。
如果在Android上仍然遇到相同的问题,可以在<project_directory>/android/app/src/main/AndroidManifest.xml
中添加以下内容:
<manifest xmlns:tools="http://schemas.android.com/tools" ....... >
<uses-sdk tools:overrideLibrary="com.arthenica.ffmpegkit.flutter, com.arthenica.ffmpegkit" />
</manifest>
更多关于Flutter音频裁剪插件easy_audio_trimmer的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter音频裁剪插件easy_audio_trimmer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
easy_audio_trimmer
是一个用于在 Flutter 应用中裁剪音频的插件。它提供了一个简单的界面,允许用户选择音频文件并对其进行裁剪。以下是使用 easy_audio_trimmer
的基本步骤:
1. 添加依赖
首先,在你的 pubspec.yaml
文件中添加 easy_audio_trimmer
依赖:
dependencies:
flutter:
sdk: flutter
easy_audio_trimmer: ^0.0.1 # 请检查最新版本
然后运行 flutter pub get
来安装依赖。
2. 导入包
在你的 Dart 文件中导入 easy_audio_trimmer
包:
import 'package:easy_audio_trimmer/easy_audio_trimmer.dart';
3. 使用 Trimmer
你可以使用 Trimmer
类来加载音频文件并进行裁剪。以下是一个简单的示例:
class AudioTrimmerExample extends StatefulWidget {
[@override](/user/override)
_AudioTrimmerExampleState createState() => _AudioTrimmerExampleState();
}
class _AudioTrimmerExampleState extends State<AudioTrimmerExample> {
Trimmer _trimmer = Trimmer();
[@override](/user/override)
void dispose() {
_trimmer.dispose();
super.dispose();
}
Future<void> _loadAudio() async {
// 选择音频文件
File file = await FilePicker.getFile(type: FileType.audio);
if (file != null) {
await _trimmer.loadAudio(audioFile: file);
}
}
Future<void> _saveAudio() async {
// 保存裁剪后的音频
String outputPath = await _trimmer.saveTrimmedAudio(
startValue: _trimmer.startValue,
endValue: _trimmer.endValue,
);
print('Trimmed audio saved to: $outputPath');
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Audio Trimmer'),
),
body: Column(
children: [
ElevatedButton(
onPressed: _loadAudio,
child: Text('Load Audio'),
),
TrimmerView(_trimmer),
ElevatedButton(
onPressed: _saveAudio,
child: Text('Save Trimmed Audio'),
),
],
),
);
}
}