Flutter 音频播放
侧边栏壁纸
  • 累计撰写 270 篇文章
  • 累计收到 275 条评论

Flutter 音频播放

Karry Bai
2021-11-28 / 0 评论 / 165 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年11月28日,已超过260天没有更新,若内容或图片失效,请留言反馈。

在Flutter中目前使用比较多的音频插件就是audioplayers啦。
插件地址:audioplayers
在项目的pubspec.yaml中引入audioplayers插件:

dependencies:
  flutter:
    sdk: flutter
  ......
  # 引入audioplayers插件:当前官方最新版本为0.20.1
  audioplayers: ^0.20.1

初始化AudioPlayer

AudioPlayer player = new AudioPlayer ();

开始播放 :开始播放音频

player.play('http://image.bkybk.com/bg.m4a');

暂停播放 :音频播放对象在播放状态才能暂停,在其它状态调用此方法无任何作用

player.pause();

继续播放 :音频播放对象在暂停状态才能恢复播放,在其它状态调用此方法无任何作用。

player.resume();

停止播放 :停止播放音频,音频播放对象在播放或暂停状态才能停止播放,在其它状态调用此方法无任何作用。停止播放后如果需要继续播放,则需调用play方法重新开始播放。

// 方法1
player.stop();

// 方法2
player.setReleaseMode(ReleaseMode.STOP);
player.release();

指定播放位置 :跳到指定位置播放音频

// 从音频的 96 秒开始播放
player.seek(new Duration(milliseconds: 96000))

设置音量 :设置播放音量的大小

// 设置音量 30
player.setVolume(0.3)

上面是关于AudioPlayer在项目中常用的声明、方法和配置,下面是关于AudioPlayer插件的具体使用:

// 引入包
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';

class AudioPage extends StatefulWidget {
  @override
  _AudioPageState createState() => _AudioPageState();
}

class _AudioPageState extends State<AudioPage> {
  String totalTime = '';
  String goTime = '';
  String playState = '';
  double _sliderValue = 30;

  bool isPlay = false;

  // 音频列表
  List _playList = [
    'http://bkybk.com/static/data/bg.mp3',
    'http://image.bkybk.com/bg.m4a'
  ];
  
  // 初始化AudioPlayer
  AudioPlayer advancedPlayer = AudioPlayer();

  @override
  void initState() {
    // TODO: implement initState
    print('------------initState---------------');
    super.initState();

    advancedPlayer.onDurationChanged.listen((Duration d) {
      setState(() {
        totalTime = d.toString();
        playState = '正在播放';
      });
    });

    advancedPlayer.onPlayerCompletion.listen((event) {
      setState(() {
        playState = '播放已完成';
      });
    });

    advancedPlayer.onAudioPositionChanged.listen((p) async {
      // p参数可以获取当前进度,也是可以调整的,比如p.inMilliseconds
      setState(() {
        goTime = p.toString();
      });
    });

    // 代码中引发意外错误时调用此函数。
    advancedPlayer.onPlayerError.listen((msg) {
      print('audioPlayer error : $msg');
//      setState(() {
//        playerState = PlayerState.stopped;
//        duration = Duration(seconds: 0);
//        position = Duration(seconds: 0);
//      });
    });
  }

  /// 当依赖的State对象改变时会调用
  /// a 在第一次构建widget时,在initState()之后立即调用此方法
  /// b 如果StatefulWidget依赖于InheritedWidget,那么当 当前的State所依赖InheritedWidget中的变量改变时会再次调用它
  /// 拓展:InheritedWidget可以高效的将数据在Widget树中向下传递、共享;
  @override
  void didChangeDependencies() {
    print('--------------didChangeDependencies--------------');
    super.didChangeDependencies();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    advancedPlayer.stop();
    advancedPlayer.dispose();
  }

  @override
  Widget build(BuildContext context) {
    String? localFilePath;
    String? localAudioCacheURI;

    return new Scaffold(
      appBar: AppBar(
        title: Text('Audio 组件演示'),
        leading: GestureDetector(
          onTap: () {
            Navigator.pop(context);
          },
          child: Icon(Icons.arrow_back),
        ),
      ),
      body: Container(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Expanded(
              child: ListView(
                children: [
                  ElevatedButton(
                      onPressed: () => play(advancedPlayer, 0),
                      child: Text('播放音乐1')),
                  ElevatedButton(
                      onPressed: () => play(advancedPlayer, 1),
                      child: Text('播放音乐2')),
                  ElevatedButton(
                      onPressed: () => pause(advancedPlayer),
                      child: Text('暂停')),
                  ElevatedButton(
                      onPressed: () => stop(advancedPlayer), child: Text('停止')),
                  ElevatedButton(
                      onPressed: () => skip(advancedPlayer, 96300),
                      child: Text('从96秒播放')),
                  ElevatedButton(
                      onPressed: () => resume(advancedPlayer),
                      child: Text('继续播放')),
                  Text('音频总长:$totalTime'),
                  Text('当前播放:$goTime'),
                  Text('播放状态:$playState'),
                  Text('调整音量:'),
                  Slider(
                    min: 0,
                    max: 100,
                    value: _sliderValue,
                    onChanged: (v) {
                      setState(() {
                        _sliderValue = v;
                      });
                      setVolume(advancedPlayer, v);
                    },
                  ),
                  ElevatedButton(
                      onPressed: () {
                        countFunction(advancedPlayer);
                      },
                      child: Text('其他常用(控制台输出)'))
                ],
              ),
            )
          ],
        ),
      ),
    );
  }

  countFunction(AudioPlayer audioPlayer) {
    setState(() {
      _count++;
    });

    // 获取当前播放状态
    PlayerState ps = audioPlayer.state;
    print(ps);

    // 判断目标是否为本地资源
    bool isLocal = audioPlayer.isLocalUrl("http://image.bkybk.com/bg.m4a");
    print(isLocal);

    // 设置音量
    audioPlayer.setVolume(0.23);
  }

  /**
   * 设置音量
   */
  setVolume(AudioPlayer audioPlayer, double value) {
    audioPlayer.setVolume(value / 100);
  }

  /**
   * 开始播放音频
   */
  play(AudioPlayer audioPlayer, int index) async {
    if (isPlay) {
      // 当音乐正在播放时,先停止当前播放;
      int stopResult = await audioPlayer.stop();
      if (stopResult == 1) {
        isPlay = false;
        int playResult = await audioPlayer.play(_playList[index], volume: 0.3);
        if (playResult == 1) {
          // success
          print('play success');
          setState(() {
            isPlay = true;
            playState = '正在加载资源......';
          });
        } else {
          print('play failed');
        }
      }
    } else {
      int playResult = await audioPlayer.play(_playList[index], volume: 0.3);
      if (playResult == 1) {
        // success
        print('play success');
        setState(() {
          isPlay = true;
          playState = '正在加载资源......';
        });
      } else {
        print('play failed');
      }
    }
  }

  /**
   * 暂停播放音频
   */
  pause(AudioPlayer audioPlayer) async {
    // 音频播放对象在播放状态才能暂停,在其它状态调用此方法无任何作用
    int result = await audioPlayer.pause();
    if (result == 1) {
      // success
      print('pause success');
      setState(() {
        isPlay = false;
        playState = '播放暂停';
      });
    } else {
      print('pause failed');
    }
  }

  /**
   * 停止播放音频
   */
  stop(AudioPlayer audioPlayer) async {
    // 停止播放音频,音频播放对象在播放或暂停状态才能停止播放,在其它状态调用此方法无任何作用。
    // 停止播放后如果需要继续播放,则需调用play方法重新开始播放。
    // 停止播放的方法一:
    int stopResult = await audioPlayer.stop();
    // 停止播放的方法二:
//    audioPlayer.setReleaseMode(ReleaseMode.STOP);
//    int stopResult = await audioPlayer.release();

    if (stopResult == 1) {
      setState(() {
        isPlay = false;
        playState = '播放停止';
      });
    } else {
      print('release failed');
    }
    super.deactivate();
  }

  /**
   * 跳到指定位置播放音频
   */
  skip(AudioPlayer audioPlayer, int startMilliseconds) async {
    // 跳到指定位置播放音频,音频播放对象在播放或暂停状态才能跳到指定播放音频,在其它状态调用此方法无任何作用。
    int result =
        await audioPlayer.seek(new Duration(milliseconds: startMilliseconds));
    if (result == 1) {
      print('go to success');
      // await audioPlayer.resume();
    } else {
      print('go to failed');
    }
  }

  /**
   * 恢复播放音频
   */
  resume(AudioPlayer audioPlayer) async {
    // 音频播放对象在暂停状态才能恢复播放,在其它状态调用此方法无任何作用。
    int result = await audioPlayer.resume();
    if (result == 1) {
      print('resume success');
      // await audioPlayer.resume();
    } else {
      print('resume failed');
    }
  }
}

代码的实际运行效果:
效果图

0

评论 (0)

取消