MediaPlayer ক্লাস ব্যবহার করে অডিও প্লেয়ার অ্যাপ তৈরি
এই উদাহরণটি দেখায় কীভাবে MediaPlayer, SeekBar এবং Handler ব্যবহার করে একটি ফাংশনাল অডিও প্লেয়ার তৈরি করা যায় যার মাধ্যমে প্লে, পজ, ফরওয়ার্ড, রিওয়াইন্ড এবং প্রগ্রেস ট্র্যাকিং করা যায়।
ধাপ ১: নতুন প্রজেক্ট তৈরি করুন
Android Studio-তে File → New Project থেকে প্রজেক্ট তৈরি করুন।
ধাপ ২: রিসোর্স ফাইল যোগ করুন
res/raw/bohemian_rhapsody.mp3- অডিও ফাইল রাখুনres/drawable/ic_play.xml,ic_pause.xml,ic_back.xml,ic_forward.xml- ভেক্টর আইকন রাখুন
ধাপ ৩: লেআউট XML (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="Now Playing:"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/txtSongName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/textView"
android:layout_toEndOf="@id/textView"
android:textStyle="bold" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/btnBackward"
android:layout_marginBottom="16dp"
android:layout_toEndOf="@id/txtStartTime"
android:layout_toStartOf="@id/txtSongTime" />
<TextView
android:id="@+id/txtStartTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/seekBar"
android:layout_marginEnd="8dp"
android:text="0:00" />
<TextView
android:id="@+id/txtSongTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/seekBar"
android:layout_marginStart="8dp"
android:layout_toEndOf="@id/seekBar"
android:text="0:00" />
<LinearLayout
android:id="@+id/controls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="44dp"
android:orientation="horizontal"
android:gravity="center">
<ImageButton
android:id="@+id/btnBackward"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:src="@drawable/ic_back"
android:contentDescription="Rewind 5s"
android:background="?attr/selectableItemBackgroundBorderless" />
<ImageButton
android:id="@+id/btnPlay"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_margin="8dp"
android:src="@drawable/ic_play"
android:contentDescription="Play"
android:background="?attr/selectableItemBackgroundBorderless" />
<ImageButton
android:id="@+id/btnPause"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:src="@drawable/ic_pause"
android:contentDescription="Pause"
android:background="?attr/selectableItemBackgroundBorderless" />
<ImageButton
android:id="@+id/btnForward"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:src="@drawable/ic_forward"
android:contentDescription="Forward 5s"
android:background="?attr/selectableItemBackgroundBorderless" />
</LinearLayout>
</RelativeLayout>
ধাপ ৪: MainActivity.java বাস্তবায়ন
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
private ImageButton btnBackward, btnForward, btnPause, btnPlay;
private MediaPlayer mediaPlayer;
private TextView txtSongName, txtStartTime, txtSongTime;
private SeekBar seekBar;
private static final int FORWARD_TIME = 5000; // 5 seconds
private static final int BACKWARD_TIME = 5000;
private Handler handler = new Handler();
private boolean isPlaying = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
setupMediaPlayer();
setupClickListeners();
}
private void initViews() {
btnBackward = findViewById(R.id.btnBackward);
btnForward = findViewById(R.id.btnForward);
btnPlay = findViewById(R.id.btnPlay);
btnPause = findViewById(R.id.btnPause);
txtSongName = findViewById(R.id.txtSongName);
txtStartTime = findViewById(R.id.txtStartTime);
txtSongTime = findViewById(R.id.txtSongTime);
seekBar = findViewById(R.id.seekBar);
txtSongName.setText("Bohemian Rhapsody");
seekBar.setMax(100); // Temporary, will update after media prepared
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser && mediaPlayer != null) {
mediaPlayer.seekTo(progress);
}
}
@Override public void onStartTrackingTouch(SeekBar seekBar) {}
@Override public void onStopTrackingTouch(SeekBar seekBar) {}
});
}
private void setupMediaPlayer() {
mediaPlayer = MediaPlayer.create(this, R.raw.bohemian_rhapsody);
mediaPlayer.setOnPreparedListener(mp -> {
seekBar.setMax(mp.getDuration());
updateTimeDisplay();
});
mediaPlayer.setOnCompletionListener(mp -> {
resetPlayer();
});
}
private void setupClickListeners() {
btnPlay.setOnClickListener(v -> playAudio());
btnPause.setOnClickListener(v -> pauseAudio());
btnForward.setOnClickListener(v -> seekForward());
btnBackward.setOnClickListener(v -> seekBackward());
}
private void playAudio() {
if (mediaPlayer != null && !mediaPlayer.isPlaying()) {
mediaPlayer.start();
isPlaying = true;
updatePlayPauseButtons();
startProgressUpdater();
Toast.makeText(this, "Playing", Toast.LENGTH_SHORT).show();
}
}
private void pauseAudio() {
if (mediaPlayer != null && mediaPlayer.isPlaying()) {
mediaPlayer.pause();
isPlaying = false;
updatePlayPauseButtons();
handler.removeCallbacks(updateProgressRunnable);
Toast.makeText(this, "Paused", Toast.LENGTH_SHORT).show();
}
}
private void seekForward() {
if (mediaPlayer != null) {
int newPosition = Math.min(mediaPlayer.getCurrentPosition() + FORWARD_TIME, mediaPlayer.getDuration());
mediaPlayer.seekTo(newPosition);
}
}
private void seekBackward() {
if (mediaPlayer != null) {
int newPosition = Math.max(mediaPlayer.getCurrentPosition() - BACKWARD_TIME, 0);
mediaPlayer.seekTo(newPosition);
}
}
private void updatePlayPauseButtons() {
btnPlay.setEnabled(!isPlaying);
btnPause.setEnabled(isPlaying);
}
private void startProgressUpdater() {
handler.postDelayed(updateProgressRunnable, 100);
}
private final Runnable updateProgressRunnable = new Runnable() {
@Override
public void run() {
if (mediaPlayer != null && isPlaying) {
int currentPosition = mediaPlayer.getCurrentPosition();
seekBar.setProgress(currentPosition);
updateTimeDisplay();
handler.postDelayed(this, 100);
}
}
};
private void updateTimeDisplay() {
if (mediaPlayer != null) {
int current = mediaPlayer.getCurrentPosition();
int total = mediaPlayer.getDuration();
txtStartTime.setText(formatTime(current));
txtSongTime.setText(formatTime(total));
}
}
private String formatTime(int millis) {
return String.format("%d:%02d",
TimeUnit.MILLISECONDS.toMinutes(millis),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);
}
private void resetPlayer() {
isPlaying = false;
updatePlayPauseButtons();
handler.removeCallbacks(updateProgressRunnable);
seekBar.setProgress(0);
updateTimeDisplay();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
handler.removeCallbacks(updateProgressRunnable);
}
}
MediaPlayer লাইফসাইকেল এবং স্টেট ম্যানেজমেন্ট
MediaPlayer একটি স্টেট-বেসড অবজেক্ট। সঠিক স্টেট ম্যানেজমেন্ট ছাড়া ক্র্যাশ হতে পারে:
- Idle: create() এর পর
- Initialized: setDataSource() এর পর
- Prepared: prepare()/prepareAsync() এর পর
- Started: start() কল করলে
- Paused: pause() কল করলে
- PlaybackCompleted: গান শেষ হলে
- Released: release() কল করলে (অবশ্যই কল করতে হবে)
ধাপ ৫: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.sample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
অ্যাপ্লিকেশন টেস্ট করুন
অ্যাপ রান করুন। প্লে বাটনে ক্লিক করলে গান বাজতে শুরু হবে। SeekBar ドラگ করে কোনো নির্দিষ্ট সময়ে যাওয়া যাবে। ফরওয়ার্ড/ব্যাকওয়ার্ড বাটনে ৫ সেকেন্ড লাফ দেয়া যাবে।