AudioPlayer 是flutter 的一个音乐播放器插件
插件地址 https://pub.dev/packages/audioplayers#-readme-tab-
测试demo效果图
image.png
初始化播放器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | _initAudioPlayer(){ // /// Ideal for long media files or streams. mode =PlayerMode.MEDIA_PLAYER; //初始化 _audioPlayer = AudioPlayer(mode: mode); _durationSubscription = _audioPlayer.onDurationChanged.listen((duration) { setState(() => _duration = duration); // TODO implemented for iOS, waiting for android impl if (Theme.of(context).platform == TargetPlatform.iOS) { // (Optional) listen for notification updates in the background _audioPlayer.startHeadlessService(); // set at least title to see the notification bar on iOS. _audioPlayer.setNotification( title: 'App Name', artist: 'Artist or blank', albumTitle: 'Name or blank', imageUrl: 'url or blank', forwardSkipInterval: const Duration(seconds: 30), // default is 30s backwardSkipInterval: const Duration(seconds: 30), // default is 30s duration: duration, elapsedTime: Duration(seconds: 0)); } }); //监听进度 _positionSubscription = _audioPlayer.onAudioPositionChanged.listen((p) => setState(() { _position = p; })); //播放完成 _playerCompleteSubscription = _audioPlayer.onPlayerCompletion.listen((event) { // _onComplete(); setState(() { _position = Duration(); }); }); //监听报错 _playerErrorSubscription = _audioPlayer.onPlayerError.listen((msg) { print('audioPlayer error : $msg'); setState(() { // _playerState = PlayerState.stopped; _duration = Duration(seconds: 0); _position = Duration(seconds: 0); }); }); //播放状态改变 _audioPlayer.onPlayerStateChanged.listen((state) { if (!mounted) return; setState(() { }); }); ///// iOS中来自通知区域的玩家状态变化流。 _audioPlayer.onNotificationPlayerStateChanged.listen((state) { if (!mounted) return; }); // _playingRouteState = PlayingRouteState.speakers; } |
开始播放
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | //开始播放 void _play() async { final playPosition = (_position != null && _duration != null && _position.inMilliseconds > 0 && _position.inMilliseconds < _duration.inMilliseconds) ? _position : null; final result = await _audioPlayer.play(url, position: playPosition); if (result == 1){ print('succes'); } // default playback rate is 1.0 // this should be called after _audioPlayer.play() or _audioPlayer.resume() // this can also be called everytime the user wants to change playback rate in the UI _audioPlayer.setPlaybackRate(playbackRate: 1.0); } |
暂停
1 2 3 4 5 6 | void _pause() async { final result = await _audioPlayer.pause(); if (result == 1){ print('succes'); } } |
停止播放
1 2 3 4 5 6 7 8 9 | //停止播放 _stop() async { final result = await _audioPlayer.stop(); if (result == 1) { setState(() { _position = Duration(); }); } } |
释放播放器
1 2 3 4 5 6 7 8 9 10 11 | @override void dispose() { //释放 _audioPlayer.dispose(); _durationSubscription?.cancel(); _positionSubscription?.cancel(); _playerCompleteSubscription?.cancel(); _playerErrorSubscription?.cancel(); _playerStateSubscription?.cancel(); super.dispose(); } |
完整demo演示代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | import 'package:flutter/material.dart'; import 'dart:async'; import 'package:audioplayers/audioplayers.dart'; class AudioPlaybackPage extends StatefulWidget { @override _AudioPlaybackPageState createState() => _AudioPlaybackPageState(); } class _AudioPlaybackPageState extends State<AudioPlaybackPage> { String url; PlayerMode mode; AudioPlayer _audioPlayer; Duration _duration; Duration _position; StreamSubscription _durationSubscription; StreamSubscription _positionSubscription; StreamSubscription _playerCompleteSubscription; StreamSubscription _playerErrorSubscription; StreamSubscription _playerStateSubscription; get _durationText => _duration?.toString()?.split('.')?.first ?? ''; get _positionText => _position?.toString()?.split('.')?.first ?? ''; @override void initState() { // TODO: implement initState super.initState(); url = 'https://cdn.laitoon.com/audio/1561606091656-a510bda9a6ef0bcfd535253a283b102e.mp3?Expires=1591776008&OSSAccessKeyId=LTAI4Fikui9yCgsEVhzKa9Xe&Signature=ZIEc3pNLI2MD1o%2BgN9e0kGVnQDg%3D'; _initAudioPlayer(); } @override void dispose() { //释放 _audioPlayer.dispose(); _durationSubscription?.cancel(); _positionSubscription?.cancel(); _playerCompleteSubscription?.cancel(); _playerErrorSubscription?.cancel(); _playerStateSubscription?.cancel(); super.dispose(); } _initAudioPlayer(){ // /// Ideal for long media files or streams. mode =PlayerMode.MEDIA_PLAYER; //初始化 _audioPlayer = AudioPlayer(mode: mode); _durationSubscription = _audioPlayer.onDurationChanged.listen((duration) { setState(() => _duration = duration); // TODO implemented for iOS, waiting for android impl if (Theme.of(context).platform == TargetPlatform.iOS) { // (Optional) listen for notification updates in the background _audioPlayer.startHeadlessService(); // set at least title to see the notification bar on iOS. _audioPlayer.setNotification( title: 'App Name', artist: 'Artist or blank', albumTitle: 'Name or blank', imageUrl: 'url or blank', forwardSkipInterval: const Duration(seconds: 30), // default is 30s backwardSkipInterval: const Duration(seconds: 30), // default is 30s duration: duration, elapsedTime: Duration(seconds: 0)); } }); //监听进度 _positionSubscription = _audioPlayer.onAudioPositionChanged.listen((p) => setState(() { _position = p; })); //播放完成 _playerCompleteSubscription = _audioPlayer.onPlayerCompletion.listen((event) { // _onComplete(); setState(() { _position = Duration(); }); }); //监听报错 _playerErrorSubscription = _audioPlayer.onPlayerError.listen((msg) { print('audioPlayer error : $msg'); setState(() { // _playerState = PlayerState.stopped; _duration = Duration(seconds: 0); _position = Duration(seconds: 0); }); }); //播放状态改变 _audioPlayer.onPlayerStateChanged.listen((state) { if (!mounted) return; setState(() { }); }); ///// iOS中来自通知区域的玩家状态变化流。 _audioPlayer.onNotificationPlayerStateChanged.listen((state) { if (!mounted) return; }); // _playingRouteState = PlayingRouteState.speakers; } //开始播放 void _play() async { final playPosition = (_position != null && _duration != null && _position.inMilliseconds > 0 && _position.inMilliseconds < _duration.inMilliseconds) ? _position : null; final result = await _audioPlayer.play(url, position: playPosition); if (result == 1){ print('succes'); } // default playback rate is 1.0 // this should be called after _audioPlayer.play() or _audioPlayer.resume() // this can also be called everytime the user wants to change playback rate in the UI _audioPlayer.setPlaybackRate(playbackRate: 1.0); } //暂停 void _pause() async { final result = await _audioPlayer.pause(); if (result == 1){ print('succes'); } } //停止播放 _stop() async { final result = await _audioPlayer.stop(); if (result == 1) { setState(() { _position = Duration(); }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(), body: Column( children: <Widget>[ Text( _position != null ? '${_positionText ?? ''} / ${_durationText ?? ''}' : _duration != null ? _durationText : '',), Padding( padding: EdgeInsets.all(12.0), child: Stack( children: [ Slider( onChanged: (v) { final Position = v * _duration.inMilliseconds; _audioPlayer .seek(Duration(milliseconds: Position.round())); }, value: (_position != null && _duration != null && _position.inMilliseconds > 0 && _position.inMilliseconds < _duration.inMilliseconds) ? _position.inMilliseconds / _duration.inMilliseconds : 0.0, ), ], ), ), Row( children: <Widget>[ IconButton(icon: Icon(Icons.play_arrow), onPressed: (){ _play(); }), IconButton(icon: Icon(Icons.pause), onPressed: (){ _pause(); }), IconButton(icon: Icon(Icons.stop), onPressed: (){ _stop(); }), ], ) ], ) ); } } |