Flutter Functions

 

Building a Music Player App with Flutter: UI and Audio Playback

In the ever-evolving world of mobile app development, Flutter has emerged as a powerful and versatile framework for creating beautiful, cross-platform applications. In this tutorial, we will embark on a journey to build a fully functional Music Player App using Flutter. We’ll not only focus on designing an intuitive user interface but also implement audio playback features, making our app ready to rock and roll.

Building a Music Player App with Flutter: UI and Audio Playback

1. Why Flutter for a Music Player App?

Before we dive into the technical details, it’s essential to understand why Flutter is an excellent choice for developing a Music Player App:

1.1. Cross-Platform Compatibility

Flutter allows you to create a single codebase that works seamlessly on both Android and iOS platforms. This means you can reach a broader audience with minimal effort.

1.2. Expressive UI

Flutter’s widget-based architecture provides developers with the freedom to create stunning and highly customizable user interfaces. Building a visually appealing music player app becomes a breeze with Flutter’s rich set of widgets.

1.3. Fast Development

With Flutter’s hot reload feature, you can instantly see the changes you make in your code, reducing development time and making the debugging process much smoother.

1.4. Robust Ecosystem

Flutter’s ecosystem includes a vast collection of pre-built plugins and packages, which can accelerate the development of your music player app by providing essential functionalities like audio playback.

Now that we’ve established why Flutter is the ideal choice, let’s dive into building our Music Player App step by step.

2. Setting Up Your Flutter Project

First things first, make sure you have Flutter installed on your system. If you haven’t already, you can follow the official Flutter installation guide to get started.

Once Flutter is set up, create a new Flutter project by running the following command:

bash
flutter create music_player_app

This command will generate a new Flutter project named “music_player_app” for you to work on.

3. Designing the User Interface

3.1. Project Structure

Before we start designing the UI, let’s take a moment to plan our project structure. A well-organized structure makes your codebase more maintainable as your project grows. Here’s a simplified project structure for our Music Player App:

css
music_player_app/
??? lib/
?   ??? main.dart
?   ??? screens/
?   ?   ??? home_screen.dart
?   ?   ??? now_playing_screen.dart
?   ??? widgets/
?   ?   ??? player_controls.dart
?   ?   ??? song_list.dart
??? assets/
?   ??? audio/
?   ?   ??? song1.mp3
?   ?   ??? song2.mp3
?   ??? images/
?   ?   ??? album1.jpg
?   ?   ??? album2.jpg

3.2. Creating the Home Screen

Let’s begin by designing the Home Screen, which displays a list of songs and allows users to select a song to play. We’ll use the ListView widget to create a scrollable list of songs. Here’s a simplified code snippet for the Home Screen:

dart
// lib/screens/home_screen.dart

import 'package:flutter/material.dart';
import 'package:music_player_app/widgets/song_list.dart';

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Music Player App'),
      ),
      body: SongList(),
    );
  }
}

In this code snippet, we’ve created a basic HomeScreen widget that displays an AppBar and a SongList widget, which we’ll implement next.

3.3. Implementing the Song List

The SongList widget will be responsible for displaying a list of songs. Each song item will have details like the song title and artist name. We can use the ListView.builder widget to create a dynamic list. Here’s the code snippet for the SongList widget:

dart
// lib/widgets/song_list.dart

import 'package:flutter/material.dart';

class SongList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Replace this with your list of songs
    final List<String> songs = ['Song 1', 'Song 2', 'Song 3'];

    return ListView.builder(
      itemCount: songs.length,
      itemBuilder: (ctx, index) {
        return ListTile(
          leading: Icon(Icons.music_note),
          title: Text(songs[index]),
          subtitle: Text('Artist Name'),
          onTap: () {
            // Implement song selection logic here
          },
        );
      },
    );
  }
}

In this code snippet, we’ve created a SongList widget that uses ListView.builder to generate a list of song items. You can replace the songs list with your actual list of songs, and when a song is tapped, you can implement the logic to play it.

3.4. Building the Now Playing Screen

The “Now Playing” screen displays the currently selected song along with playback controls. We’ll create a separate NowPlayingScreen widget for this purpose:

dart
// lib/screens/now_playing_screen.dart

import 'package:flutter/material.dart';
import 'package:music_player_app/widgets/player_controls.dart';

class NowPlayingScreen extends StatelessWidget {
  final String songTitle;

  NowPlayingScreen({required this.songTitle});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Now Playing'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              songTitle,
              style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
            ),
            SizedBox(height: 16),
            // Add playback controls here using PlayerControls widget
            PlayerControls(),
          ],
        ),
      ),
    );
  }
}

In this code snippet, we’ve created a NowPlayingScreen widget that displays the song title and includes a placeholder for playback controls using the PlayerControls widget.

3.5. Designing Playback Controls

To control audio playback, we’ll create a PlayerControls widget that includes buttons for play, pause, skip forward, and skip backward. We’ll also add a progress bar to indicate the playback progress. Here’s the code for the PlayerControls widget:

dart
// lib/widgets/player_controls.dart

import 'package:flutter/material.dart';

class PlayerControls extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Slider(
          // Implement playback progress here
          value: 0.5,
          onChanged: (double value) {
            // Implement seek functionality here
          },
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            IconButton(
              icon: Icon(Icons.skip_previous),
              onPressed: () {
                // Implement skip to previous song here
              },
            ),
            IconButton(
              icon: Icon(Icons.play_arrow),
              onPressed: () {
                // Implement play/pause functionality here
              },
            ),
            IconButton(
              icon: Icon(Icons.skip_next),
              onPressed: () {
                // Implement skip to next song here
              },
            ),
          ],
        ),
      ],
    );
  }
}

This PlayerControls widget provides a slider for playback progress, play/pause buttons, and skip controls. You’ll need to implement the actual audio playback functionality in the onPressed callbacks.

4. Implementing Audio Playback

Now that we’ve designed the user interface for our Music Player App, it’s time to implement audio playback. To manage audio, we’ll use the audioplayers package, a popular Flutter package for audio playback. To add this package to your project, add the following dependency to your pubspec.yaml file:

yaml
dependencies:
  audioplayers: ^0.21.2

Then, run flutter pub get to fetch the package.

4.1. Setting Up Audio Playback

Let’s start by initializing the audio player in your main.dart file:

dart
// lib/main.dart

import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';
import 'package:music_player_app/screens/home_screen.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final AudioPlayer audioPlayer = AudioPlayer();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Music Player App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeScreen(audioPlayer: audioPlayer),
    );
  }
}

In this code snippet, we’ve imported the audioplayers package and initialized an AudioPlayer instance in the MyApp widget. We’ll pass this audioPlayer instance to our HomeScreen so that we can control audio playback from the home screen.

4.2. Implementing Playback Logic

Now, let’s implement the playback logic in the SongList widget when a song is tapped:

dart
// lib/widgets/song_list.dart

import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';

class SongList extends StatelessWidget {
  final AudioPlayer audioPlayer;

  SongList({required this.audioPlayer});

  @override
  Widget build(BuildContext context) {
    final List<String> songs = ['Song 1', 'Song 2', 'Song 3'];

    return ListView.builder(
      itemCount: songs.length,
      itemBuilder: (ctx, index) {
        return ListTile(
          leading: Icon(Icons.music_note),
          title: Text(songs[index]),
          subtitle: Text('Artist Name'),
          onTap: () async {
            final url = 'URL_OF_YOUR_AUDIO_FILE'; // Replace with your audio URL

            // Check if the audio player is currently playing
            if (audioPlayer.state == PlayerState.PLAYING) {
              await audioPlayer.stop();
            }

            // Play the selected song
            await audioPlayer.play(url);
            
            // Navigate to the Now Playing screen
            Navigator.of(context).push(MaterialPageRoute(
              builder: (context) => NowPlayingScreen(songTitle: songs[index]),
            ));
          },
        );
      },
    );
  }
}

In this code snippet, we’ve added the audio playback logic in the onTap callback. When a song is tapped, we stop any currently playing audio, play the selected song, and navigate to the “Now Playing” screen, passing the song title as a parameter.

4.3. Updating Playback Controls

Now, let’s connect the playback controls in the PlayerControls widget to the audioPlayer instance:

dart
// lib/widgets/player_controls.dart

import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';

class PlayerControls extends StatelessWidget {
  final AudioPlayer audioPlayer;

  PlayerControls({required this.audioPlayer});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Slider(
          value: audioPlayer.position.inSeconds.toDouble(),
          max: audioPlayer.duration.inSeconds.toDouble(),
          onChanged: (double value) {
            // Implement seek functionality here
            audioPlayer.seek(Duration(seconds: value.toInt()));
          },
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            IconButton(
              icon: Icon(Icons.skip_previous),
              onPressed: () {
                // Implement skip to previous song here
                // You can use audioPlayer.previous() if you have a playlist
              },
            ),
            IconButton(
              icon: Icon(audioPlayer.state == PlayerState.PLAYING
                  ? Icons.pause
                  : Icons.play_arrow),
              onPressed: () {
                // Implement play/pause functionality here
                if (audioPlayer.state == PlayerState.PLAYING) {
                  audioPlayer.pause();
                } else {
                  audioPlayer.resume();
                }
              },
            ),
            IconButton(
              icon: Icon(Icons.skip_next),
              onPressed: () {
                // Implement skip to next song here
                // You can use audioPlayer.next() if you have a playlist
              },
            ),
          ],
        ),
      ],
    );
  }
}

In this code snippet, we’ve connected the playback controls to the audioPlayer instance. The slider shows the current playback position and allows seeking, the play/pause button toggles between play and pause states, and the skip buttons can be used to navigate between songs if you have a playlist.

5. Testing Your Music Player App

With the UI and audio playback logic in place, it’s time to test your Music Player App. Run the app on an emulator or physical device to ensure everything is working as expected.

Conclusion

In this tutorial, we’ve learned how to build a Music Player App with Flutter, covering UI design and audio playback functionality. Flutter’s cross-platform capabilities and expressive UI widgets make it an excellent choice for developing music apps that can be enjoyed by users on both Android and iOS devices. By implementing the provided code samples and customizing them to your needs, you can create a feature-rich music player app that brings your music collection to life.

Happy coding, and may your music app be a hit with users around the world!

Previously at
Flag Argentina
Brazil
time icon
GMT-3
Full Stack Systems Analyst with a strong focus on Flutter development. Over 5 years of expertise in Flutter, creating mobile applications with a user-centric approach.