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
|
import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/services.dart' show ByteData, rootBundle;
class AudioPlayersPage extends StatefulWidget {
const AudioPlayersPage({super.key});
@override
State<AudioPlayersPage> createState() => _AudioPlayersPageState();
}
class _AudioPlayersPageState extends State<AudioPlayersPage> {
PlayerState? _playerState;
static const String _audioPath = 'audio/test.mp3';
late AudioPlayer _audioPlayer;
Duration _position = Duration.zero;
Duration? _duration;
bool get _isPlaying => _playerState == PlayerState.playing;
bool get _isPaused => _playerState == PlayerState.paused;
@override
void initState() {
super.initState();
_audioPlayer = AudioPlayer();
playAudio();
}
void playAudio() async {
try {
//请注意AssetSource构造函数中的路径是audio/test.mp3
//而不是 assets/audio/test.mp3。这是因为AssetSource会自动将路径解析为assets/目录下的文件。
//确保您的音频文件确实位于项目目录的assets/audio/文件夹中,并且文件名和扩展名都是正确的。
//final source = AssetSource('assets/audio/test.mp3');
//await _audioPlayer.setSourceAsset('audio/test.mp3');
//为了与播放器播放时设置的AssetSource对象路径作对比。
final ByteData data = await rootBundle.load('assets/audio/test.mp3');
debugPrint('ByteData = ${data.lengthInBytes}');
// 设置音频源并播放
_audioPlayer.play(AssetSource(_audioPath));
//监听播放器状态
_audioPlayer.onPlayerStateChanged.listen((state) {
setState(() {
_playerState = state;
debugPrint('_playerState: $_playerState');
if(_playerState == PlayerState.completed) {
debugPrint('重新播放');
playAudio();
}
});
});
_audioPlayer.onPositionChanged.listen((position) {
setState(() {
_position = position;
});
});
_audioPlayer.onDurationChanged.listen((duration) {
_duration = duration;
});
} catch (e) {
// 处理异常
debugPrint('Error playing audio: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(''),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
_duration != null
? SizedBox(
child: Slider(
value: (_duration != null &&
_position.inMilliseconds > 0 &&
_position.inMilliseconds <
_duration!.inMilliseconds)
? _position.inMilliseconds / _duration!.inMilliseconds
: 0.0,
onChanged: _onSliderChanged,
),
)
: Container(),
Text('音频播放当前位置: ${_position.toString().split('.').first}'),
Text('音频播放总时长: ${_duration?.toString().split('.').first ?? ''}'),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: IconButton(
key: const Key('play_button'),
onPressed: () {
if (!_isPlaying) {
_play();
}
},
iconSize: 48.0,
icon: const Icon(Icons.play_arrow),
),
),
Expanded(
child: IconButton(
key: const Key('pause_button'),
onPressed: () {
if (_isPlaying) {
_pause();
}
},
iconSize: 48.0,
icon: const Icon(Icons.pause),
),
),
Expanded(
child: IconButton(
key: const Key('stop_button'),
onPressed: () {
if (_isPlaying || _isPaused) {
_stop();
}
},
iconSize: 48.0,
icon: const Icon(Icons.stop),
),
),
],
)
],
),
);
}
void _onSliderChanged(double newValue) {
if (_duration == null) {
return;
}
final position = newValue * _duration!.inMilliseconds;
_audioPlayer.seek(Duration(milliseconds: position.round()));
}
Future<void> _play() async {
await _audioPlayer.resume();
setState(() => _playerState = PlayerState.playing);
}
Future<void> _pause() async {
await _audioPlayer.pause();
setState(() => _playerState = PlayerState.paused);
}
Future<void> _stop() async {
await _audioPlayer.stop();
setState(() {
_playerState = PlayerState.stopped;
});
}
@override
void dispose() {
super.dispose();
_audioPlayer.dispose();
}
}
|