Open In App

How to Build Music Player Application Using Flutter?

Last Updated : 31 Jul, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Music can inspire and motivate us, it makes every person feel enthusiastic and relaxed. In this article, we will explain how to build a Music Player application step by step with some basic functionalities like pause, play, and seek in Flutter from a music URL. Flutter is an open-source framework developed and supported by Google to build and deploy hybrid applications easily.

Tools Required

To build this app, you require the following tools on your machine :

  1. Visual Studio Code (Recommended IDE)
  2. Android Emulator / Original Device for testing.
  3. Flutter SDK
  4. Flutter Plugin for VS Code.

Create a New Project

Follow these steps to create a brand new project to make building the app.

  • Create and name a folder of your choice.
  • Open VS Code and open the newly created folder in it.
  • Open the command palette by pressing CTRL + SHIFT + P and type Flutter. Choose Flutter: New Project from the listed options.

flutter-project-ss.png

  • Select Application from the drop down and it will open in the current folder you are in.

flutter-app-ss.png

  • Now name your app as per your choice, We are naming mine with musicplayer (Use lowercase convention).

Step-by-Step Implementation

Step 1:

After the initial setup of the project, you get a folder structure like this.

Open main.dart file from the lib folder.

Step 2:

Add the following required packages in the pubspec.yaml file just below the dependencies section which we are going to use in our app.

  • just_audio: (For audio streaming)
  • audio_video_progress_bar: (For progress bar UI)

depends-ss.png

Step 3:

Create a new file named player_screen.dart in the lib folder.

Step 4:

Import the material file using the following statement in the newly created file.

import 'package:flutter/material.dart';

Import the below files for the working of the application.

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

Step 5:

Open the AndroidManifest.xml file which is available under the android/app/src/main folder. Add the following line above the <application> tag to give the app internet permission for loading music.

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

Step 6:

Open application-level build.gradle file which is available under the android/app folder and change the minSdkVersion to 21.

minSdkVersion 21

Step 7:

Create a StateFul Widget named PlayerScreen in the player_screen.dart file.

Step 8:

Get an audio file URL that you want to play in the app. Ensure that the URL contains a valid music extension format like mp3. Also, get an image URL for showing the thumbnail image of the song that is being played.

Step 9:

Add the following Dart code into the Stateful Widget above the build method. Add required URLs.

  • loadMusic() function is used to load the specified music file from the internet.
  • playMusic() function is used to play the music.
  • pauseMusic() function is used to pause the music.

Dart




String musicUrl = ""; // Insert your music URL
String thumbnailImgUrl = ""; // Insert your thumbnail URL
var player = AudioPlayer();
bool loaded = false;
bool playing = false;
 
void loadMusic() async {
  await player.setUrl(musicUrl);
  setState(() {
    loaded = true;
  });
}
 
void playMusic() async {
  setState(() {
    playing = true;
  });
  await player.play();
}
 
void pauseMusic() async {
  setState(() {
    playing = false;
  });
  await player.pause();
}
 
@override
void initState() {
  loadMusic();
  super.initState();
}
 
@override
void dispose() {
  player.dispose();
  super.dispose();
}


Step 10:

Now we will design the UI of the music player. Here are the steps in designing each Widget. The equivalent Dart code is mentioned below the steps.

  • An AppBar is added with the title Music Player.
  • A Column Widget is added and under children below widgets are added.
  • A Network Image to load the thumbnail image mentioned from the URL given.
  • Below it after a Spacer, a ProgressBar is added to show the music progress and use it as a slider for seeking forward and backward.
  • ProgressBar is wrapped with StreamBuilder to get stream updates from the music player and update the current progress of music played.
  • A Row Widget is taken and the following children are added to it.
  • An IconButton is added in the middle of the row for Pausing/Playing the music.
  • Two Seek buttons are added at both sides of the Pause button to seek backward and forward. Currently, music is seen for 10 seconds, you can update it as per your preference.

Dart Code for UI

Dart




@override
Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Music Player"),
      ),
      body: Column(
        children: [
          const Spacer(
            flex: 2,
          ),
          ClipRRect(
            borderRadius: BorderRadius.circular(8),
            child: Image.network(
              thumbnailImgUrl,
              height: 350,
              width: 350,
              fit: BoxFit.cover,
            ),
          ),
          const Spacer(),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 8),
            child: StreamBuilder(
                stream: player.positionStream,
                builder: (context, snapshot1) {
                  final Duration duration = loaded
                      ? snapshot1.data as Duration
                      : const Duration(seconds: 0);
                  return StreamBuilder(
                      stream: player.bufferedPositionStream,
                      builder: (context, snapshot2) {
                        final Duration bufferedDuration = loaded
                            ? snapshot2.data as Duration
                            : const Duration(seconds: 0);
                        return SizedBox(
                          height: 30,
                          child: Padding(
                            padding: const EdgeInsets.symmetric(horizontal: 16),
                            child: ProgressBar(
                              progress: duration,
                              total:
                                  player.duration ?? const Duration(seconds: 0),
                              buffered: bufferedDuration,
                              timeLabelPadding: -1,
                              timeLabelTextStyle: const TextStyle(
                                  fontSize: 14, color: Colors.black),
                              progressBarColor: Colors.red,
                              baseBarColor: Colors.grey[200],
                              bufferedBarColor: Colors.grey[350],
                              thumbColor: Colors.red,
                              onSeek: loaded
                                  ? (duration) async {
                                      await player.seek(duration);
                                    }
                                  : null,
                            ),
                          ),
                        );
                      });
                }),
          ),
          const SizedBox(
            height: 8,
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              const SizedBox(
                width: 10,
              ),
              IconButton(
                  onPressed: loaded
                      ? () async {
                          if (player.position.inSeconds >= 10) {
                            await player.seek(Duration(
                                seconds: player.position.inSeconds - 10));
                          } else {
                            await player.seek(const Duration(seconds: 0));
                          }
                        }
                      : null,
                  icon: const Icon(Icons.fast_rewind_rounded)),
              Container(
                height: 50,
                width: 50,
                decoration: const BoxDecoration(
                    shape: BoxShape.circle, color: Colors.red),
                child: IconButton(
                    onPressed: loaded
                        ? () {
                            if (playing) {
                              pauseMusic();
                            } else {
                              playMusic();
                            }
                          }
                        : null,
                    icon: Icon(
                      playing ? Icons.pause : Icons.play_arrow,
                      color: Colors.white,
                    )),
              ),
              IconButton(
                  onPressed: loaded
                      ? () async {
                          if (player.position.inSeconds + 10 <=
                              player.duration!.inSeconds) {
                            await player.seek(Duration(
                                seconds: player.position.inSeconds + 10));
                          } else {
                            await player.seek(const Duration(seconds: 0));
                          }
                        }
                      : null,
                  icon: const Icon(Icons.fast_forward_rounded)),
              const SizedBox(
                width: 10,
              ),
            ],
          ),
          const Spacer(
            flex: 2,
          )
        ],
      ),
    );
  }


Step 11:

The final step remaining is to update the main.dart file where the applications start running the code. Add the following dart code in the main.dart file.

Dart




import 'package:flutter/material.dart';
import 'package:music_player_gfg/player_screen.dart';
  
void main() {
  runApp(const MyApp());
}
  
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  
  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: PlayerScreen(),
      debugShowCheckedModeBanner: false,
      title: "Music Player",
    );
  }
}


Voila, your application is coded completely and ready to be built, and run.

Step 12:

Build and Run

To run your app, select Run from the toolbar and click on Run Without Debugging or CTRL + F5 then select your preferred device to test the app. You can modify the code and update the UI as per your choice.

Output

Here is the final output of the app.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads