Tutorial

Android Media Player Song With SeekBar

Published on August 4, 2022
author

Anupam Chugh

Android Media Player Song With SeekBar

In this tutorial, we’ll use the MediaPlayer class to implement a basic Audio Player in our Android Application. We’ll add a Play/Stop feature and also allow the user to change the position of the song with a SeekBar.

Android MediaPlayer

MediaPlayer class is used for playing Audio and Video files. The common methods of the MediaPlayer class that we’ll use are:

  • start()
  • stop()
  • release() - To prevent memory leaks.
  • seekTo(position) - This will be used with the SeekBar
  • isPlaying() - Let’s us know whether the song is being played or not.
  • getDuration() - Is used to get the total duration. Using this we’ll know the upper limit of our SeekBar. This function returns the duration in milli seconds
  • setDataSource(FileDescriptor fd) - This is used to set the file to be played.
  • setVolume(float leftVolume, float rightVolume) - This is used to set the volume level. The value is a float between 0 an 1.

We’ll be playing an mp3 file stored in the assets folder of our Android Studio Project. Fetching the sound assets file from the Assets folder

AssetFileDescriptor descriptor = getAssets().openFd("filename");
                mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
                descriptor.close();

In order to create an Application that plays Audio and lets you change the position of the current song track we need to implement three things:

  • MediaPlayer
  • SeekBar With Text - To show the current progress time besides the thumb.
  • Runnable Thread - To update the Seekbar.

Project Structure

android media player song seekbar project Add the following dependency in your build.gradle:

implementation 'com.android.support:design:28.0.0-alpha3'

Code

The code for the activity_main.xml is given below:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:gravity="center"
    android:layout_margin="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="PLAY/STOP SONG.\nSCRUB WITH SEEKBAR"
        android:textStyle="bold" />


    <SeekBar
        android:id="@+id/seekbar"
        android:layout_margin="16dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />


    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:src="@android:drawable/ic_media_play"
        android:text="PLAY SOUND" />

</LinearLayout>

We’ve added a FloatingActionButon that’ll play/stop when clicked. The code for the MainActivity.java class is given below:

package com.journaldev.androidmediaplayersong;

import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements Runnable {


    MediaPlayer mediaPlayer = new MediaPlayer();
    SeekBar seekBar;
    boolean wasPlaying = false;
    FloatingActionButton fab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        fab = findViewById(R.id.button);

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                playSong();
            }
        });

        final TextView seekBarHint = findViewById(R.id.textView);

        seekBar = findViewById(R.id.seekbar);

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

                seekBarHint.setVisibility(View.VISIBLE);
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
                seekBarHint.setVisibility(View.VISIBLE);
                int x = (int) Math.ceil(progress / 1000f);

                if (x  0 && mediaPlayer != null && !mediaPlayer.isPlaying()) {
                    clearMediaPlayer();
                    fab.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, android.R.drawable.ic_media_play));
                    MainActivity.this.seekBar.setProgress(0);
                }

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {


                if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                    mediaPlayer.seekTo(seekBar.getProgress());
                }
            }
        });
    }

    public void playSong() {

        try {


            if (mediaPlayer != null && mediaPlayer.isPlaying()) {
                clearMediaPlayer();
                seekBar.setProgress(0);
                wasPlaying = true;
                fab.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, android.R.drawable.ic_media_play));
            }


            if (!wasPlaying) {

                if (mediaPlayer == null) {
                    mediaPlayer = new MediaPlayer();
                }

                fab.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, android.R.drawable.ic_media_pause));

                AssetFileDescriptor descriptor = getAssets().openFd("suits.mp3");
                mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
                descriptor.close();

                mediaPlayer.prepare();
                mediaPlayer.setVolume(0.5f, 0.5f);
                mediaPlayer.setLooping(false);
                seekBar.setMax(mediaPlayer.getDuration());

                mediaPlayer.start();
                new Thread(this).start();

            }

            wasPlaying = false;
        } catch (Exception e) {
            e.printStackTrace();

        }
    }

    public void run() {

        int currentPosition = mediaPlayer.getCurrentPosition();
        int total = mediaPlayer.getDuration();


        while (mediaPlayer != null && mediaPlayer.isPlaying() && currentPosition < total) {
            try {
                Thread.sleep(1000);
                currentPosition = mediaPlayer.getCurrentPosition();
            } catch (InterruptedException e) {
                return;
            } catch (Exception e) {
                return;
            }

            seekBar.setProgress(currentPosition);

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        clearMediaPlayer();
    }

    private void clearMediaPlayer() {
        mediaPlayer.stop();
        mediaPlayer.release();
        mediaPlayer = null;
    }
}

In the above code on clicking the FloatingActionButton, the playSong function gets triggered in which we stop the song and reset the MediaPlayer and FloatingActionButton icon every second time. Once the mediaPlayer.prepare() is called, the details are available for the song. We can now get the duration and set it on the SeekBar max position. setLoooping to false prevents the song from playing infinitely until stopped by the user. We start the thread which triggers the run method which was a part of the Runnable interface that we’ve implemented. Inside the run method, we update the progress every second which triggers the onProgressChanged method of the SeekBar listener. Inside the listener, we’ve set the TextView offset to below the SeekBar’s thumb. We set the time duration by converting the milliseconds to seconds there. When the seek bar is moved the same method is triggered. When the user stops scrubbing the SeekBar the onStopTrackingTouch is triggered in which using the seekTo method we update the song position on the MediaPlayer instance. Once the song is completed, we update the position of the SeekBar back to the initial and clear the MediaPlayer instance. The output of the application without audio is given below: android media player song seekbar output This brings an end to this tutorial. You can download the project from the link below and play the song for yourself.

AndroidMediaPlayerSong

Github Project Link

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Anupam Chugh

author

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
April 28, 2020

I think it is not allowed to update the UI - update seekbar progress from within another thread

- Bala

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    August 31, 2019

    How can i add music from mobile… on button click…please help me

    - Manish

      Try DigitalOcean for free

      Click below to sign up and get $200 of credit to try our products over 60 days!

      Sign up

      Join the Tech Talk
      Success! Thank you! Please check your email for further details.

      Please complete your information!

      Become a contributor for community

      Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

      DigitalOcean Documentation

      Full documentation for every DigitalOcean product.

      Resources for startups and SMBs

      The Wave has everything you need to know about building a business, from raising funding to marketing your product.

      Get our newsletter

      Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

      New accounts only. By submitting your email you agree to our Privacy Policy

      The developer cloud

      Scale up as you grow — whether you're running one virtual machine or ten thousand.

      Get started for free

      Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

      *This promotional offer applies to new accounts only.