Wednesday, February 4, 2026
HomeFlutterHow to create music player app with free source code using flutter

How to create music player app with free source code using flutter

🎵 FLUTTER MUSIC PLAYER – FINAL COMPLETE GUIDE

(Playlist + Mini Player + Equalizer + Production + Play Store Fixes)


✅ FINAL FEATURES YOU WILL HAVE

✔ Playlist UI
✔ Mini player (bottom bar)
✔ Background playback + notification
✔ Phone storage picker
✔ Equalizer (Android)
✔ AdMob monetization
✔ Production release (AAB)
✔ Play Store rejection prevention
✔ ASO basics


🧱 PART 1: PROJECT BASE (REQUIRED)

Create project

flutter create music_player_final
cd music_player_final

📦 Dependencies (pubspec.yaml)

dependencies:
  flutter:
    sdk: flutter

  just_audio: ^0.9.36
  audio_service: ^0.18.12
  file_picker: ^6.1.1
  permission_handler: ^11.3.1
  google_mobile_ads: ^4.0.0
  flutter_equalizer: ^0.0.3   # Android equalizer
flutter pub get

🔐 PART 2: ANDROID PERMISSIONS

📄 android/app/src/main/AndroidManifest.xml

Inside <manifest>:

<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.INTERNET"/>

🎧 PART 3: BACKGROUND AUDIO + NOTIFICATION

📄 lib/audio_handler.dart

import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart';

class MyAudioHandler extends BaseAudioHandler
    with QueueHandler, SeekHandler {

  final AudioPlayer _player = AudioPlayer();

  MyAudioHandler() {
    _player.playerStateStream.listen((state) {
      playbackState.add(
        playbackState.value.copyWith(
          playing: state.playing,
          controls: [
            MediaControl.skipToPrevious,
            state.playing ? MediaControl.pause : MediaControl.play,
            MediaControl.skipToNext,
          ],
          processingState: AudioProcessingState.ready,
        ),
      );
    });
  }

  Future<void> playFile(String path) async {
    await _player.setFilePath(path);
    play();
  }

  @override
  Future<void> play() => _player.play();

  @override
  Future<void> pause() => _player.pause();

  @override
  Future<void> stop() => _player.stop();
}

📂 PART 4: PLAYLIST UI (MULTIPLE SONGS)

📄 lib/main.dart (FULL FILE)

import 'package:flutter/material.dart';
import 'package:audio_service/audio_service.dart';
import 'package:file_picker/file_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter_equalizer/flutter_equalizer.dart';
import 'audio_handler.dart';

late MyAudioHandler audioHandler;

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  MobileAds.instance.initialize();

  audioHandler = await AudioService.init(
    builder: () => MyAudioHandler(),
    config: const AudioServiceConfig(
      androidNotificationChannelName: 'Music Player',
      androidNotificationOngoing: true,
    ),
  );

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MusicHome(),
    );
  }
}

class MusicHome extends StatefulWidget {
  const MusicHome({super.key});
  @override
  State<MusicHome> createState() => _MusicHomeState();
}

class _MusicHomeState extends State<MusicHome> {
  List<String> songs = [];
  String? currentSong;
  BannerAd? bannerAd;

  @override
  void initState() {
    super.initState();
    bannerAd = BannerAd(
      adUnitId: 'ca-app-pub-3940256099942544/6300978111',
      size: AdSize.banner,
      request: const AdRequest(),
      listener: BannerAdListener(),
    )..load();
  }

  Future<void> pickSongs() async {
    await Permission.audio.request();
    FilePickerResult? result =
        await FilePicker.platform.pickFiles(
      type: FileType.audio,
      allowMultiple: true,
    );

    if (result != null) {
      setState(() {
        songs = result.paths.whereType<String>().toList();
      });
    }
  }

  void playSong(String path) {
    currentSong = path;
    audioHandler.playFile(path);
    setState(() {});
  }

  void openEqualizer() {
    FlutterEqualizer.open(0);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Offline Music Player"),
        actions: [
          IconButton(
            icon: const Icon(Icons.equalizer),
            onPressed: openEqualizer,
          )
        ],
      ),
      body: Column(
        children: [
          ElevatedButton(
            onPressed: pickSongs,
            child: const Text("Pick Songs"),
          ),

          Expanded(
            child: ListView.builder(
              itemCount: songs.length,
              itemBuilder: (context, index) {
                final song = songs[index];
                return ListTile(
                  title: Text(song.split('/').last),
                  onTap: () => playSong(song),
                );
              },
            ),
          ),

          /// MINI PLAYER
          if (currentSong != null)
            Container(
              color: Colors.black87,
              child: Row(
                children: [
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(8),
                      child: Text(
                        currentSong!.split('/').last,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ),
                  ),
                  IconButton(
                    icon: const Icon(Icons.play_arrow),
                    onPressed: () => audioHandler.play(),
                  ),
                  IconButton(
                    icon: const Icon(Icons.pause),
                    onPressed: () => audioHandler.pause(),
                  ),
                ],
              ),
            ),

          if (bannerAd != null)
            SizedBox(
              height: bannerAd!.size.height.toDouble(),
              child: AdWidget(ad: bannerAd!),
            ),
        ],
      ),
    );
  }
}

🎚 PART 5: EQUALIZER (ANDROID ONLY)

✔ Uses system equalizer
✔ Play Store safe
✔ No special permissions

⚠️ iOS does NOT support equalizer (hide button on iOS if needed)


🚀 PART 6: PRODUCTION RELEASE (REQUIRED)

Build App Bundle

flutter build appbundle

File:

build/app/outputs/bundle/release/app-release.aab

🔐 PART 7: PLAY STORE REJECTION – FIXES

❌ COMMON REJECTIONS & SOLUTIONS

RejectionFix
CopyrightPlay local files only
Missing privacy policyAdd privacy link
Background abuseUse audio_service only
Ad policyUse test ads while testing
PermissionsExplain in Play Console

✅ PRIVACY POLICY (MANDATORY)

Example text:

This app does not collect personal data.
It only plays music selected by the user.

📈 PART 8: ASO (APP RANKING)

App Title

Offline Music Player – MP3 Player

Short Description

Play local music offline with playlist, equalizer & background play.

Keywords

music player
offline mp3
background audio
equalizer

🎉 FINAL RESULT

✅ Playlist UI
✅ Mini player
✅ Equalizer
✅ Background + notification
✅ Ads monetization
✅ Play Store compliant
✅ Production ready

RELATED ARTICLES

3 COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments