🎵 Аудиоплеер для FlutterFlow
Слой 1+2: Решение и Логика
Стандартный аудиоплеер во FlutterFlow иногда имеет ограничения в Web-версии или требует сложной настройки. Данный кастомный виджет на базе библиотеки just_audio работает стабильно на всех платформах и поддерживает фоновое воспроизведение.
Основные возможности:
- Полная поддержка Web (в отличие от некоторых встроенных решений).
- Кастомизация интерфейса (цвета, прогресс-бар).
- Работа с заблокированным экраном (для мобильных устройств).
Параметры виджета:
audioUrl(String): прямая ссылка на аудиофайл.name(String): название трека для отображения.showProgressBar(bool): переключатель видимости шкалы прогресса.
💻 Код виджета (Вариант 1)
Вы можете скопировать этот код и вставить его в раздел Custom Widgets во FlutterFlow. Не забудьте добавить зависимость just_audio в Pubspec Dependencies.
import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';
class MusicWidget extends StatefulWidget {
const MusicWidget({
super.key,
this.width,
this.height,
required this.audioUrl,
required this.showProgressBar,
required this.name,
});
final double? width;
final double? height;
final String audioUrl;
final bool showProgressBar;
final String name;
@override
State<MusicWidget> createState() => _MusicWidgetState();
}
class _MusicWidgetState extends State<MusicWidget> {
late AudioPlayer _audioPlayer;
bool _isPlaying = false;
@override
void initState() {
super.initState();
_audioPlayer = AudioPlayer();
_loadAudio();
}
Future<void> _loadAudio() async {
try {
await _audioPlayer.setUrl(widget.audioUrl);
} catch (e) {
print("Error loading audio: $e");
}
}
void _togglePlayPause() async {
setState(() {
_isPlaying = !_isPlaying;
});
if (_isPlaying) {
await _audioPlayer.play();
} else {
await _audioPlayer.pause();
}
}
@override
void dispose() {
_audioPlayer.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Color(0xFF1C0335),
borderRadius: BorderRadius.circular(10),
),
padding: const EdgeInsets.all(12),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
widget.name,
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white),
),
const SizedBox(height: 15),
IconButton(
icon: Icon(
_isPlaying ? Icons.pause_circle_filled : Icons.play_circle_filled,
color: Colors.white,
size: 50,
),
onPressed: _togglePlayPause,
),
if (widget.showProgressBar)
StreamBuilder<Duration>(
stream: _audioPlayer.positionStream,
builder: (context, snapshot) {
final position = snapshot.data ?? Duration.zero;
final duration = _audioPlayer.duration ?? Duration.zero;
return Slider(
value: position.inSeconds.toDouble(),
max: duration.inSeconds.toDouble(),
onChanged: (value) => _audioPlayer.seek(Duration(seconds: value.toInt())),
activeColor: Colors.white,
inactiveColor: Colors.white24,
);
},
),
],
),
);
}
}Слой 3: Источники (Proven Roots)
- 💬 Telegram: Сообщение от Aleksandr Stepanov
- 📄 Оригинал: Аудиоплеер.md — полная версия переписки и Вариант 2.