Flutter音频处理插件native_audio的使用
Flutter音频处理插件native_audio的使用
插件介绍
native_audio
是一个用于Flutter的音频插件,它利用原生Android和iOS的音频播放器来处理音频播放、通知和外部控制(如蓝牙)。
安装与设置
该插件适用于Android和iOS平台。以下是安装和设置步骤:
Android
-
先决条件:
- Flutter项目需要最小版本
MinSDK 21
- Flutter项目需要支持
AndroidX
- Flutter项目需要最小版本
-
应用配置: 在
Application
类中添加以下代码:import io.flutter.app.FlutterApplication import io.flutter.plugin.common.PluginRegistry import io.flutter.plugins.GeneratedPluginRegistrant import com.danielgauci.native_audio.NativeAudioPlugin class Application : FlutterApplication(), PluginRegistry.PluginRegistrantCallback { override fun onCreate() { super.onCreate() NativeAudioPlugin.setPluginRegistrantCallback(this) } override fun registerWith(registry: PluginRegistry) { GeneratedPluginRegistrant.registerWith(registry) } }
确保在
AndroidManifest.xml
文件中反映此更改:<application android:name=".Application" ...
注意:如果不调用
NativeAudioPlugin.setPluginRegistrant
,当播放音频时会抛出异常。
iOS
-
先决条件:
- Flutter项目需要最小版本
iOS 10
- Flutter项目需要最小构建版本
Swift 4.2
- Flutter项目需要最小版本
-
无需额外设置: 对于iOS,不需要进行额外设置。
自定义
-
通知图标: 可以通过添加名为
native_audio_notification_icon
的drawable资源来覆盖通知图标。这可以在.xml
或其他任何支持的格式中实现。注意:仅对Android有用,在iOS上,将始终使用启动图标。
-
设置跳过时间: 设置跳过时间可以控制向前/向后跳转的时间,当调用
skipForward()
、skipBackward()
或通知中的媒体图标时。_audio.setSkipTime(forwardTime: Duration(seconds: 30), backwardTime: Duration(seconds: 10));
示例代码
import 'package:flutter/material.dart';
import 'package:native_audio/native_audio.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
[@override](/user/override)
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
var _audio = NativeAudio();
var _progressText = "0:00:00";
var _isLoaded = false;
var _isPlaying = false;
var _status = "stopped";
[@override](/user/override)
void initState() {
super.initState();
_audio.setSkipTime(
forwardTime: Duration(seconds: 30),
backwardTime: Duration(seconds: 10));
_listenForAudioEvents();
}
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Native Audio'),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Text(_progressText, textAlign: TextAlign.center),
Padding(
padding: EdgeInsets.all(16.0),
child: Text(_status, textAlign: TextAlign.center),
),
SizedBox(height: 48),
if (!_isLoaded)
MaterialButton(
child: Text("Play"), onPressed: () => _playSampleAudio()),
if (_isLoaded)
MaterialButton(
child: Text("Stop"), onPressed: () => _audio.stop()),
if (!_isPlaying && _isLoaded)
MaterialButton(
child: Text("Resume"), onPressed: () => _audio.resume()),
if (_isPlaying)
MaterialButton(
child: Text("Pause"), onPressed: () => _audio.pause()),
if (_isLoaded)
MaterialButton(
child: Text("Seek to 30m"),
onPressed: () => _audio.seekTo(Duration(minutes: 30))),
if (_isLoaded)
MaterialButton(
child: Text("Seek to 70m"),
onPressed: () => _audio.seekTo(Duration(minutes: 70))),
if (_isLoaded)
MaterialButton(
child: Text("Skip Forward"),
onPressed: () => _audio.skipForward()),
if (_isLoaded)
MaterialButton(
child: Text("Skip Backward"),
onPressed: () => _audio.skipBackward()),
],
),
),
);
}
void _listenForAudioEvents() {
_audio.onLoaded = (totalDuration, startedAutomatically) {
setState(() {
_isLoaded = true;
_isPlaying = startedAutomatically;
_status = "loaded";
});
};
_audio.onResumed = () {
setState(() => _isPlaying = true);
_status = "resumed";
};
_audio.onPaused = () {
setState(() {
_isPlaying = false;
_status = "paused";
});
};
_audio.onStopped = () {
setState(() {
_isLoaded = false;
_isPlaying = false;
_status = "stopped";
});
};
_audio.onCompleted = () {
setState(() {
_isLoaded = false;
_isPlaying = false;
_status = "completed";
});
};
_audio.onProgressChanged = (progress) {
setState(() {
this._progressText = _durationToString(progress);
});
};
}
void _playSampleAudio() {
setState(() => _status = "loadinging");
_audio.play(
"https://s3.amazonaws.com/scifri-episodes/scifri20181123-episode.mp3",
title: "How The Fashion Industry Is Responding To Climate Change",
album: "Science Friday",
artist: "WNYC Studio",
imageUrl:
"https://www.sciencefriday.com/wp-content/uploads/2019/09/clothes-close-min.jpg");
}
String _durationToString(Duration duration) {
String twoDigits(int n) {
if (n >= 10) return "$n";
return "0$n";
}
String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60));
String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60));
return "${twoDigits(duration.inHours)}:$twoDigitMinutes:$twoDigitSeconds";
}
}
更多关于Flutter音频处理插件native_audio的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter音频处理插件native_audio的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中使用native_audio
插件来处理音频的示例代码。这个示例将展示如何播放和停止音频文件。
首先,确保你已经在pubspec.yaml
文件中添加了native_audio
依赖:
dependencies:
flutter:
sdk: flutter
native_audio: ^0.10.0 # 请检查最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,在你的Flutter项目中创建一个简单的界面,用于播放和停止音频。以下是一个完整的示例:
import 'package:flutter/material.dart';
import 'package:native_audio/native_audio.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Audio Example',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: AudioExampleScreen(),
);
}
}
class AudioExampleScreen extends StatefulWidget {
@override
_AudioExampleScreenState createState() => _AudioExampleScreenState();
}
class _AudioExampleScreenState extends State<AudioExampleScreen> {
late AudioManager audioManager;
String? audioFilePath;
@override
void initState() {
super.initState();
audioManager = AudioManager();
// 假设你的音频文件在assets文件夹下
audioFilePath = 'assets/sample_audio.mp3'; // 请确保你的音频文件路径正确
loadAssets();
}
@override
void dispose() {
audioManager.dispose();
super.dispose();
}
Future<void> loadAssets() async {
// 如果音频文件在assets中,你需要先确保它们被加载(尽管native_audio通常处理本地文件)
// 这里仅作为示例,实际使用native_audio时可能不需要这一步
await rootBundle.load(audioFilePath!);
}
void playAudio() async {
if (audioFilePath != null) {
await audioManager.play(audioFilePath!);
}
}
void stopAudio() async {
await audioManager.stop();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Audio Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: playAudio,
child: Text('Play Audio'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: stopAudio,
child: Text('Stop Audio'),
),
],
),
),
);
}
}
请注意以下几点:
-
音频文件路径:在示例中,我们假设音频文件位于
assets
文件夹下。你需要确保在pubspec.yaml
中声明了这些资产文件,例如:flutter: assets: - assets/sample_audio.mp3
然而,
native_audio
插件通常用于处理本地文件系统上的音频文件,而不是直接从assets中加载。如果你从assets加载音频,可能需要先将音频文件复制到设备的本地存储,然后再使用native_audio
播放。 -
权限:如果你的应用需要访问设备的存储来播放音频文件,请确保在
AndroidManifest.xml
和Info.plist
中添加了相应的权限声明。 -
平台特定配置:
native_audio
是一个平台特定的插件,它依赖于iOS的AVFoundation
框架和Android的MediaPlayer
API。因此,在某些情况下,你可能需要在原生代码中进行额外的配置。
这个示例代码展示了如何使用native_audio
插件的基本功能。根据你的具体需求,你可能需要进一步定制和扩展这个示例。