Flutter音频可视化插件audio_visualizer的使用
Flutter音频可视化插件 audio_visualizer
的使用
audio_visualizer
是一个用于在Flutter应用中无缝可视化音频的插件。它支持从文件、资源、HTTP流、麦克风输入和原始PCM16数据中获取音频并进行可视化。
特性
- Visualize File:支持从本地文件加载音频
- Visualize Asset:支持从Flutter资产文件中加载音频
- Visualize HTTP:支持从网络URL加载音频
- Visualize Microphone:支持从麦克风输入音频(需配合其他插件使用)
- Visualize Raw PCM16:支持从原始PCM16数据中加载音频
组件概述
该插件提供了三个主要组件:
- VisualizerPlayer:用于从文件、资源和HTTP流中加载并播放音频。
- PCMVisualizer:用于从自定义源加载并处理原始PCM16数据。
预构建的可视化样式和波段类型
预构建的可视化样式
BarVisualizer
CircleVisualizer
LineVisualizer
MultiWaveVisualizer
RainbowBlockVisualizer
波段类型
fourBand
fourBandVisual
eightBand
tenBand
twentySixBand
thirtyOneBand
如何使用
从音频文件中可视化
你可以通过以下前缀来加载音频:
- Assets:
asset://path_to_asset
- Files:
file://path_to_file
- HTTP:
http://url
或https://url
示例代码
import 'package:audio_visualizer/audio_visualizer.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final audioPlayer = VisualizerPlayer();
[@override](/user/override)
void initState() {
super.initState();
initAudioPlayer();
}
Future<void> initAudioPlayer() async {
await audioPlayer.initialize();
await audioPlayer.setDataSource("asset://assets/sample.mp3");
await audioPlayer.play();
}
[@override](/user/override)
void dispose() {
audioPlayer.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Audio Visualizer Demo'),
),
body: Center(
child: ListenableBuilder(
listenable: audioPlayer,
builder: (context, child) {
return BarVisualizer(
input: audioPlayer.value.waveform,
backgroundColor: Colors.black,
color: Colors.greenAccent,
gap: 2,
);
},
),
),
),
);
}
}
可视化麦克风输入
要从麦克风输入音频,可以结合 record
插件使用。首先捕获音频数据,然后将其传递给 PCMVisualizer
。
示例代码
import 'package:audio_visualizer/audio_visualizer.dart';
import 'package:flutter/material.dart';
// 假设你已经添加了 record 插件,并且导入了相关包
final pcmVisualizer = PCMVisualizer();
// 在捕获到音频数据后调用
pcmVisualizer.feed(rawPCM16Data);
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ListenableBuilder(
listenable: pcmVisualizer,
builder: (context, child) {
return BarVisualizer(
input: pcmVisualizer.value.waveform,
backgroundColor: Colors.black,
color: Colors.greenAccent,
gap: 2,
);
},
),
),
);
}
[@override](/user/override)
void dispose() {
pcmVisualizer.dispose();
super.dispose();
}
权限
在Android上,需要以下权限来可视化音频:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
完整示例Demo
以下是一个完整的示例项目,展示了如何使用 audio_visualizer
插件来实现音频可视化功能。
import 'dart:math';
import 'package:audio_visualizer/audio_visualizer.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
themeMode: ThemeMode.dark,
darkTheme: ThemeData.dark(useMaterial3: true),
home: const MyApp(),
));
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final audioPlayer = VisualizerPlayer();
final sources = [
"https://www.soundhelix.com/examples/mp3/SoundHelix-Song-4.mp3",
"https://files.testfile.org/AUDIO/C/M4A/sample1.m4a",
];
var sourceIndex = 0;
[@override](/user/override)
void initState() {
super.initState();
audioPlayer.initialize().then((_) {
audioPlayer.setDataSource(sources[sourceIndex]);
audioPlayer.addListener(onUpdate);
});
}
void onUpdate() {
if (audioPlayer.value.status == PlayerStatus.ready) {
audioPlayer.play(looping: true);
}
}
[@override](/user/override)
void dispose() {
audioPlayer.removeListener(onUpdate);
audioPlayer.dispose();
super.dispose();
}
[@override](/user/override)
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Center(child: Text('Audio Visualizer')),
),
body: Column(
children: [
const SizedBox(height: 32),
Padding(
padding: const EdgeInsets.all(8.0),
child: ListenableBuilder(
listenable: audioPlayer,
builder: (context, child) {
final duration = audioPlayer.value.duration;
final position = audioPlayer.value.position;
final durationText = formatDuration(duration);
final positionText = formatDuration(position);
return Text(
"$positionText / $durationText",
style: Theme.of(context).textTheme.headlineLarge,
);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ListenableBuilder(
listenable: audioPlayer,
builder: (context, child) {
return Text(
audioPlayer.value.status == PlayerStatus.playing
? "Now Playing"
: "",
style: Theme.of(context).textTheme.bodyLarge,
);
},
),
),
Expanded(
child: ListenableBuilder(
listenable: audioPlayer,
builder: (context, child) {
final data = getMagnitudes(audioPlayer.value.fft);
return RainbowBlockVisualizer(
data: data,
maxSample: 32,
blockHeight: 14,
);
},
),
),
ListenableBuilder(
listenable: audioPlayer,
builder: (context, child) {
final duration = audioPlayer.value.duration.inMilliseconds;
final position = audioPlayer.value.position.inMilliseconds;
return LinearProgressIndicator(
value: position / max(1, duration),
minHeight: 8,
);
},
),
],
),
bottomNavigationBar: BottomAppBar(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
icon: const Icon(Icons.play_arrow),
onPressed: () {
audioPlayer.play(looping: true);
},
),
IconButton(
icon: const Icon(Icons.pause),
onPressed: () {
audioPlayer.pause();
},
),
IconButton(
icon: const Icon(Icons.stop),
onPressed: () {
audioPlayer.stop();
},
),
IconButton(
icon: const Icon(Icons.loop),
onPressed: () {
sourceIndex = (sourceIndex + 1) % sources.length;
audioPlayer.stop();
audioPlayer.setDataSource(sources[sourceIndex]);
},
),
],
),
),
);
}
String formatDuration(Duration duration) {
final minutes = duration.inMinutes;
final seconds = duration.inSeconds.remainder(60).toString().padLeft(2, '0');
return "$minutes:$seconds";
}
}
更多关于Flutter音频可视化插件audio_visualizer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter音频可视化插件audio_visualizer的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter项目中使用audio_visualizer
插件来实现音频可视化的代码案例。这个插件允许你从音频流中提取频率数据并显示在自定义的Widget上。
首先,确保你已经在pubspec.yaml
文件中添加了audio_visualizer
依赖:
dependencies:
flutter:
sdk: flutter
audio_visualizer: ^0.0.8 # 请注意版本号,使用最新版本
然后运行flutter pub get
来安装依赖。
接下来,你可以按照以下步骤在你的Flutter应用中实现音频可视化:
- 导入必要的包:
import 'package:flutter/material.dart';
import 'package:audio_visualizer/audio_visualizer.dart';
import 'package:audioplayers/audioplayers.dart';
注意:audio_visualizer
依赖于audioplayers
包来播放音频,所以你也需要添加audioplayers
依赖。
- 创建音频播放器并初始化可视化器:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Audio Visualizer Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: AudioVisualizerScreen(),
);
}
}
class AudioVisualizerScreen extends StatefulWidget {
@override
_AudioVisualizerScreenState createState() => _AudioVisualizerScreenState();
}
class _AudioVisualizerScreenState extends State<AudioVisualizerScreen> {
final AudioPlayer audioPlayer = AudioPlayer();
late AudioVisualizer visualizer;
@override
void initState() {
super.initState();
// 初始化AudioVisualizer
visualizer = AudioVisualizer()
..fftSize = 512 // 设置FFT大小
..updateFrequencyData = (List<double> data) {
// 这里你可以处理频率数据,例如更新UI
setState(() {}); // 触发UI更新(如果有UI需要基于这些数据更新)
};
// 播放音频文件(确保替换为你的音频URL)
audioPlayer.play('https://example.com/your-audio-file.mp3');
// 启动可视化器
visualizer.start(audioPlayer.playerId);
}
@override
void dispose() {
// 停止可视化器和音频播放器
visualizer.stop();
audioPlayer.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Audio Visualizer Demo'),
),
body: Center(
child: CustomVisualizerWidget(), // 自定义的可视化Widget
),
);
}
}
- 创建自定义的可视化Widget:
class CustomVisualizerWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 这里你可以根据从visualizer获取的频率数据来绘制可视化效果
// 由于我们没有直接访问到这些数据,这里只是一个简单的示例
return Container(
width: double.infinity,
height: 200,
color: Colors.black,
child: CustomPaint(
painter: VisualizerPainter(), // 自定义Painter来绘制可视化效果
),
);
}
}
class VisualizerPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.green
..strokeWidth = 2.0
..isAntiAlias = true;
// 绘制简单的波形(这里只是示例,实际应基于频率数据绘制)
double offsetX = 0.0;
for (int i = 0; i < size.width * 2; i++) {
double offsetY = size.height / 2 + (sin(i / 10.0) * 20.0);
if (i == 0) {
canvas.drawLine(Offset(offsetX, offsetY), Offset(offsetX + 1, offsetY), paint);
} else {
canvas.drawLine(Offset(offsetX - 1, offsetY - 1), Offset(offsetX, offsetY), paint);
}
offsetX += 1.0;
}
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
// 在实际情况下,这里应该根据频率数据的变化来决定是否需要重绘
return false;
}
}
注意:上面的VisualizerPainter
只是一个简单的波形绘制示例,并没有真正使用从audio_visualizer
获取的频率数据。在实际应用中,你需要根据visualizer.updateFrequencyData
回调中的频率数据来动态绘制可视化效果。
这个代码案例提供了一个基础框架,你可以在此基础上根据具体需求进行扩展和自定义。