Mega Bundle SALE is ON! Get ALL of our amazing Flutter codebases with 95% OFF discount 🔥

A music player may be added to your Flutter app in this tutorial. To play music from external storage, to play from an assets file, or to use a URL to play music (internet). The ability to adjust the volume of the song.

Introduction

Emotions may be expressed via music, which is a universal language. In the modern world, it’s clear that music applications are a must-have. Listening to their favorite songs on a variety of music applications is a popular way for people to cope with stress or improve their creative abilities. A developer’s job isn’t complete until he or she creates useful applications for themselves. Since you’re a fan of music, I decided to create a customized music app of my own. Here, I’ll show you how to create a simple music app in a Flutter.

Packages Used:

Our external storage will be accessed using Flutter audio query (eg. mobile phone, memory card, etc).

Flutter_audio_query: ^0.3.5+6

https://pub.dev/packages/flutter_audio_query

We may utilize the audio manager package to integrate features like play, pause, seek, inc. or dec. volume in our program.

audio_manager: ^0.8.2

https://pub.dev/packages/audio_manager

Setting Up the Project:

import the packages

import 'package:flutter_audio_query/flutter_audio_query.dart';
import 'package:audio_manager/audio_manager.dart';

Modify your AndroidManifest.xml

<application
    ...
    android:usesCleartextTraffic="true"
    ...
>

Modify your build.gradle file.

defaultConfig {
    minSdkVersion 23
}

Using the internet and other resources to play music:

Creating an audio manager instance

var audioManagerInstance = AudioManager.instance;

Playing music using the start method

AudioManager has a start() function that we may use to start playing the music. Input includes a URL as well as a title, description, and a cover image, as well as an optional auto-complete field.

onTap: () {
 audioManagerInstance
 .start("song URL", "song title",
desc: "description",
auto: true,
cover: "cover URL")
 .then((err) {
 print(err);
});
},

To listen to music from an assets file, just modify the song’s URL to the location of the assets file.

onTap: () {
 audioManagerInstance
 .start("assets/music.mp3"song title",
desc: "description",
auto: true,
cover: "assets/cover.png")
 .then((err) {
 print(err);
});
},

Our external storage is being used to download music:

FlutterAudioQuery produces a future, thus we’ll use a FutureBuilder to get the music files from external storage. For example, we can use the getSongs function to get all the songs from a certain artist or album. Only the getSongs function will be used to keep the logic basic and clean. Every single one of them is yours for the taking.

FutureBuilder(
  future: FlutterAudioQuery()
      .getSongs(sortType: SongSortType.RECENT_YEAR),
  builder: (context, snapshot) {
    List<SongInfo> songInfo = snapshot.data;
    if (snapshot.hasData) return SongWidget(songList: songInfo);
    return Container(
      height: MediaQuery.of(context).size.height * 0.4,
      child: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            CircularProgressIndicator(),
            SizedBox(
              width: 20,
            ),
            Text(
              "Loading....",
              style: TextStyle(fontWeight: FontWeight.bold),
            )
          ],
        ),
      ),
    );
  },
)

SongWidget:

External memory may only be used in the song’s path is known. The filePath field of the SongInfo class allows us to get the location of the music file.

onTap: () {
 audioManagerInstance
 .start("file://${song.filePath}", song.title,
desc: song.displayName,
auto: true,
cover: song.albumArtwork)
 .then((err) {
 print(err);
});
},

Setting Up the audio:

This is the most crucial portion since it controls a variety of audio occurrences.

void setupAudio() {
 audioManagerInstance.onEvents((events, args) {
 switch (events) {
 case AudioManagerEvents.start:
 _slider = 0;
break;
case AudioManagerEvents.seekComplete:
 _slider = audioManagerInstance.position.inMilliseconds /
audioManagerInstance.duration.inMilliseconds;
setState(() {});
break;
case AudioManagerEvents.playstatus:
isPlaying = audioManagerInstance.isPlaying;
setState(() {});
break;
case AudioManagerEvents.timeupdate:
 _slider = audioManagerInstance.position.inMilliseconds /
audioManagerInstance.duration.inMilliseconds;
audioManagerInstance.updateLrc(args["position"].toString());
setState(() {});
break;
case AudioManagerEvents.ended:
 audioManagerInstance.next();
setState(() {});
break;
default:
 break;
}
 });
}

Initializing setupAudio

void initState() {
super.initState();
setupAudio();
}

Creating a control panel:

This panel contains a play-pause button, previous button, next button, and a songProgress Slider.

Widget bottomPanel() {
  return Column(children: <Widget>[
    Padding(
      padding: EdgeInsets.symmetric(horizontal: 16),
      child: songProgress(context),
    ),
    Container(
      padding: EdgeInsets.symmetric(vertical: 16),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          CircleAvatar(
            child: Center(
              child: IconButton(
                  icon: Icon(
                    Icons.skip_previous,
                    color: Colors.white,
),
                  onPressed: () => audioManagerInstance.previous()),
            ),
            backgroundColor: Colors.cyan.withOpacity(0.3),
          ),
          CircleAvatar(
            radius: 30,
            child: Center(
              child: IconButton(
                onPressed: () async {
                  if(audioManagerInstance.isPlaying)
                    audioManagerInstance.toPause();
                  audioManagerInstance.playOrPause();
                },
                padding: const EdgeInsets.all(0.0),
                icon: Icon(
                  audioManagerInstance.isPlaying
                      ? Icons.pause: Icons.play_arrow,
                  color: Colors.white,
                ),
              ),
            ),
          ),
          CircleAvatar(
            backgroundColor: Colors.cyan.withOpacity(0.3),
            child: Center(
              child: IconButton(
                  icon: Icon(
                    Icons.skip_next,
                    color: Colors.white,
                  ),
                  onPressed: () => audioManagerInstance.next()),
            ),
          ),
        ],
      ),
    ),
  ]);
}

Duration of a song:

Using this function, we may format the song’s length in milliseconds into this format: 000:00. Format, in this case, is a string equal to 00:00. The song’s runtime is used to calculate the duration. Otherwise, it returns the provided duration formatted as [insert format here].

String _formatDuration(Duration d) {
 if (d == null) return "--:--";
int minute = d.inMinutes;
int second = (d.inSeconds > 60) ? (d.inSeconds % 60) : d.inSeconds;
String format = ((minute < 10) ? "0$minute" : "$minute") +
 ":" +
 ((second < 10) ? "0$second" : "$second");
return format;
}

SongProgress:

Widget songProgress(BuildContext context) {
  var style = TextStyle(color: Colors.black);
  return Row(
    children: <Widget>[
      Text(
        _formatDuration(audioManagerInstance.position),
        style: style,
      ),
      Expanded(
        child: Padding(
          padding: EdgeInsets.symmetric(horizontal: 5),
          child: SliderTheme(
              data: SliderTheme.of(context).copyWith(
                trackHeight: 2,
                thumbColor: Colors.blueAccent,
                overlayColor: Colors.blue,
                thumbShape: RoundSliderThumbShape(
                  disabledThumbRadius: 5,
                  enabledThumbRadius: 5,
                ),
                overlayShape: RoundSliderOverlayShape(
                  overlayRadius: 10,
                ),
                activeTrackColor: Colors.blueAccent,
                inactiveTrackColor: Colors.grey,
              ),
              child: Slider(
                value: _slider ?? 0,
                onChanged: (value) {
                  setState(() {
                    _slider = value;
                  });
                },
                onChangeEnd: (value) {
                  if (audioManagerInstance.duration != null) {
                    Duration msec = Duration(
                        milliseconds:
                        (audioManagerInstance.duration.inMilliseconds *
                            value)
                            .round());
                    audioManagerInstance.seekTo(msec);
                  }
                },
              )),
        ),
      ),
      Text(
        _formatDuration(audioManagerInstance.duration),
        style: style,
      ),
    ],
  );
}

Conclusion

After all these steps, we have got the following output:


Leave a Reply

Your email address will not be published. Required fields are marked *

Shopping Cart