advanced_music_player 0.0.2
advanced_music_player: ^0.0.2 copied to clipboard
A powerful and customizable audio player plugin for Flutter, featuring background playback, queue management, and reactive UI widgets.
import 'package:flutter/material.dart';
import 'package:advanced_music_player/advanced_music_player.dart';
import 'dart:async';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
final _player = AdvancedMusicPlayer();
late TabController _tabController;
// removed unused fields
String _status = "Idle";
bool _shuffleEnabled = false;
RepeatMode _repeatMode = RepeatMode.none;
final List<String> _networkUrls = [
'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3',
'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3',
'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-4.mp3',
];
List<AudioTrack> _localTracks = [];
Future<void> _fetchLocalSongs() async {
final hasPermission = await _player.requestStoragePermission();
if (hasPermission) {
final files = await _player.getSystemAudioFiles();
if (files.isNotEmpty) {
setState(() {
_localTracks = files;
});
}
} else {
debugPrint("Permission denied");
}
}
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
_player.initialize();
_fetchLocalSongs(); // Fetch on startup
_player.currentTrackNotifier.addListener(() {
final track = _player.currentTrackNotifier.value;
if (track != null) {
setState(() {
_status = "Playing: ${track.title}";
});
}
});
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
void _playNetworkPlaylist(int startIndex) {
final tracks = _networkUrls
.map(
(url) => AudioTrack(
source: url,
title: "Song ${url.split('-').last.replaceAll('.mp3', '')}",
artist: "SoundHelix",
),
)
.toList();
_player.setQueue(tracks, initialIndex: startIndex);
}
void _playLocalPlaylist(int startIndex) {
_player.setQueue(_localTracks, initialIndex: startIndex);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Music Player'),
bottom: TabBar(
controller: _tabController,
tabs: const [
Tab(text: "Network"),
Tab(text: "Local"),
],
),
),
body: Column(
children: [
Expanded(
// ... TabBarView remains same ...
child: TabBarView(
controller: _tabController,
children: [
// Network Tab
ListView.builder(
itemCount: _networkUrls.length,
itemBuilder: (context, index) {
return ListTile(
leading: const Icon(Icons.music_note),
title: Text("Song ${index + 1}"),
subtitle: Text(_networkUrls[index]),
onTap: () => _playNetworkPlaylist(index),
);
},
),
// Local Tab
Column(
children: [
if (_localTracks.isEmpty)
const Padding(
padding: EdgeInsets.all(16.0),
child: Text("No songs found or permission needed."),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: ElevatedButton(
onPressed: _fetchLocalSongs,
child: const Text("Refresh Local Songs"),
),
),
Expanded(
child: ListView.builder(
itemCount: _localTracks.length,
itemBuilder: (context, index) {
final track = _localTracks[index];
return ListTile(
leading: const Icon(Icons.audio_file),
title: Text(track.title),
subtitle: Text(track.artist),
onTap: () => _playLocalPlaylist(index),
);
},
),
),
],
),
],
),
),
// Player Controls
Container(
color: Colors.grey[200],
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(_status, maxLines: 1, overflow: TextOverflow.ellipsis),
// New Package Widget: Slider
const AdvancedPlayerSlider(
activeColor: Colors.blue,
inactiveColor: Colors.grey,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
IconButton(
icon: Icon(
Icons.shuffle,
color: _shuffleEnabled ? Colors.blue : Colors.grey,
),
onPressed: () {
setState(() {
_shuffleEnabled = !_shuffleEnabled;
_player.setShuffleMode(_shuffleEnabled);
});
},
),
IconButton(
icon: const Icon(Icons.skip_previous),
onPressed: () => _player.previous(),
),
IconButton(
icon: const Icon(Icons.replay_10),
onPressed: () =>
_player.seekBackward(const Duration(seconds: 10)),
),
// New Package Widget: Play/Pause
const PlayPauseButton(size: 48, color: Colors.blue),
IconButton(
icon: const Icon(Icons.forward_10),
onPressed: () =>
_player.seekForward(const Duration(seconds: 10)),
),
IconButton(
icon: const Icon(Icons.skip_next),
onPressed: () => _player.next(),
),
IconButton(
icon: Icon(
Icons.repeat,
color: _repeatMode != RepeatMode.none
? Colors.blue
: Colors.grey,
),
onPressed: () {
setState(() {
if (_repeatMode == RepeatMode.none) {
_repeatMode = RepeatMode.all;
} else if (_repeatMode == RepeatMode.all) {
_repeatMode = RepeatMode.one;
} else {
_repeatMode = RepeatMode.none;
}
_player.setRepeatMode(_repeatMode);
});
},
),
],
),
],
),
),
],
),
),
);
}
}