Flutter音频处理插件native_audio的使用

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

Flutter音频处理插件native_audio的使用

插件介绍

native_audio 是一个用于Flutter的音频插件,它利用原生Android和iOS的音频播放器来处理音频播放、通知和外部控制(如蓝牙)。

安装与设置

该插件适用于Android和iOS平台。以下是安装和设置步骤:

Android
  1. 先决条件

    • Flutter项目需要最小版本 MinSDK 21
    • Flutter项目需要支持 AndroidX
  2. 应用配置: 在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
  1. 先决条件

    • Flutter项目需要最小版本 iOS 10
    • Flutter项目需要最小构建版本 Swift 4.2
  2. 无需额外设置: 对于iOS,不需要进行额外设置。

自定义

  1. 通知图标: 可以通过添加名为native_audio_notification_icon的drawable资源来覆盖通知图标。这可以在.xml或其他任何支持的格式中实现。

    注意:仅对Android有用,在iOS上,将始终使用启动图标。

  2. 设置跳过时间: 设置跳过时间可以控制向前/向后跳转的时间,当调用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

1 回复

更多关于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'),
            ),
          ],
        ),
      ),
    );
  }
}

请注意以下几点:

  1. 音频文件路径:在示例中,我们假设音频文件位于assets文件夹下。你需要确保在pubspec.yaml中声明了这些资产文件,例如:

    flutter:
      assets:
        - assets/sample_audio.mp3
    

    然而,native_audio插件通常用于处理本地文件系统上的音频文件,而不是直接从assets中加载。如果你从assets加载音频,可能需要先将音频文件复制到设备的本地存储,然后再使用native_audio播放。

  2. 权限:如果你的应用需要访问设备的存储来播放音频文件,请确保在AndroidManifest.xmlInfo.plist中添加了相应的权限声明。

  3. 平台特定配置native_audio是一个平台特定的插件,它依赖于iOS的AVFoundation框架和Android的MediaPlayer API。因此,在某些情况下,你可能需要在原生代码中进行额外的配置。

这个示例代码展示了如何使用native_audio插件的基本功能。根据你的具体需求,你可能需要进一步定制和扩展这个示例。

回到顶部