Воспроизведение аудио

Последнее обновление: 17.10.2021

Для воспроизведения музыки и других аудиоматериалов Android предоставляет класс MediaPlayer.

Чтобы воспроизводить аудио, MediaPlayer должен знать, какой именно ресурс (файл) нужно производить. Установить нужный ресурс для воспроизведения можно тремя способами:

  • в метод create() объекта MediaPlayer передается id ресурса, представляющего аудиофайл

  • в метод create() объекта MediaPlayer передается объект Uri, представляющего аудиофайл

  • в метод setDataSource() объекта MediaPlayer передается полный путь к аудиофайлу

После установки ресурса вызывается метод prepare() или prepareAsync() (асинхронный вариант prepare()). Этот метод подготавливает аудиофайл к воспроизведению, извлекая из него первые секунды. Если мы воспроизводим файл из сети, то лучше использовать prepareAsync().

Для управления воспроизведением в классе MediaPlayer определены следующие методы:

  • start(): запускает аудио

  • pause(): приостанавливает воспроизведение

  • stop(): полностью останавливает воспроизведение

Итак, создадим новый проект. Как и в случае с видео, аудиофайл должен находиться в папке res/raw, поэтому добавим в проект в Android Studio такую папку. Для этого нажмем на папку res правой кнопкой мыши и в появившемся меню выберем New -> Android Resource Directory:

Добавление папки raw в проект Android Studio

Затем в появившемся окне в качестве типа папки укажем raw (что также будет использоваться в качестве названия папки):

Создание папки raw в проект Android Studio

И скопируем в нее какой-нибудь аудио-файл.

Добавление аудио-файла в Android Studio

Для управления аудиопотоком определим в файле activity_main.xml три кнопки:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/playButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Play"
        android:onClick="play"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/pauseButton"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/pauseButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Pause"
        android:onClick="pause"
        app:layout_constraintLeft_toRightOf="@id/playButton"
        app:layout_constraintRight_toLeftOf="@id/stopButton"
        app:layout_constraintTop_toTopOf="parent"/>
    <Button
        android:id="@+id/stopButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Stop"
        android:onClick="stop"
        app:layout_constraintLeft_toRightOf="@id/pauseButton"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

И изменим код класса MainActivity:

package com.example.mediaapp;

import androidx.appcompat.app.AppCompatActivity;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    MediaPlayer mPlayer;
    Button playButton, pauseButton, stopButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mPlayer= MediaPlayer.create(this, R.raw.music);
        mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                stopPlay();
            }
        });
        playButton = findViewById(R.id.playButton);
        pauseButton = findViewById(R.id.pauseButton);
        stopButton = findViewById(R.id.stopButton);

        pauseButton.setEnabled(false);
        stopButton.setEnabled(false);
    }
    private void stopPlay(){
        mPlayer.stop();
        pauseButton.setEnabled(false);
        stopButton.setEnabled(false);
        try {
            mPlayer.prepare();
            mPlayer.seekTo(0);
            playButton.setEnabled(true);
        }
        catch (Throwable t) {
            Toast.makeText(this, t.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
    public void play(View view){

        mPlayer.start();
        playButton.setEnabled(false);
        pauseButton.setEnabled(true);
        stopButton.setEnabled(true);
    }
    public void pause(View view){

        mPlayer.pause();
        playButton.setEnabled(true);
        pauseButton.setEnabled(false);
        stopButton.setEnabled(true);
    }
    public void stop(View view){
        stopPlay();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mPlayer.isPlaying()) {
            stopPlay();
        }
    }
}

Обработчик каждой кнопки кроме вызова определенного метода у MediaPlayer также переключает доступность кнопок.

И если запуск и приостановка воспроизведения особых сложностей не вызывает, то при обработки полной остановки воспроизведения мы можем столкнуться с рядом трудностей. В частности, когда мы выходим из приложения - полностью закрываем его через диспетчер приложений либо нажимаем на кнопку Назад, то у нас для текущей Activity вызывается метод onDestroy, activity уничтожается, но MediaPlayer продолжает работать. Если мы вернемся к приложению, то activity будет создана заново, но с помощью кнопок мы не сможем управлять воспроизведением. Поэтому в даном случае переопределяем метод onDestroy, в котором завершаем воспроизведение.

Для корректного завершения также определен обработчик естественного завершения воспроизведения OnCompletionListener, действие которого будет аналогично нажатию на кнопку "Стоп".

Воспроизведение аудио в Android и MediaPlayer

Добавим к воспроизведению индикатор громкости. Для этого в файле activity_main.xml определим SeekBar:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <Button
        android:id="@+id/playButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Play"
        android:onClick="play"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/pauseButton"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@id/volumeControl" />
    <Button
        android:id="@+id/pauseButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Pause"
        android:onClick="pause"
        app:layout_constraintLeft_toRightOf="@id/playButton"
        app:layout_constraintRight_toLeftOf="@id/stopButton"
        app:layout_constraintTop_toTopOf="parent"/>
    <Button
        android:id="@+id/stopButton"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="Stop"
        android:onClick="stop"
        app:layout_constraintLeft_toRightOf="@id/pauseButton"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <SeekBar
        android:id="@+id/volumeControl"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        app:layout_constraintTop_toBottomOf="@id/playButton"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

И далее изменим код класса MainActivity:

package com.example.mediaapp;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    MediaPlayer mPlayer;
    Button playButton, pauseButton, stopButton;
    SeekBar volumeControl;
    AudioManager audioManager;

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

        mPlayer=MediaPlayer.create(this, R.raw.music);
        mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                stopPlay();
            }
        });
        playButton = findViewById(R.id.playButton);
        pauseButton = findViewById(R.id.pauseButton);
        stopButton = findViewById(R.id.stopButton);

        audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        int curValue = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

        volumeControl = findViewById(R.id.volumeControl);
        volumeControl.setMax(maxVolume);
        volumeControl.setProgress(curValue);
        volumeControl.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        pauseButton.setEnabled(false);
        stopButton.setEnabled(false);
    }
    private void stopPlay(){
        mPlayer.stop();
        pauseButton.setEnabled(false);
        stopButton.setEnabled(false);
        try {
            mPlayer.prepare();
            mPlayer.seekTo(0);
            playButton.setEnabled(true);
        }
        catch (Throwable t) {
            Toast.makeText(this, t.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }

    public void play(View view){

        mPlayer.start();
        playButton.setEnabled(false);
        pauseButton.setEnabled(true);
        stopButton.setEnabled(true);
    }
    public void pause(View view){

        mPlayer.pause();
        playButton.setEnabled(true);
        pauseButton.setEnabled(false);
        stopButton.setEnabled(true);
    }
    public void stop(View view){
        stopPlay();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mPlayer.isPlaying()) {
            stopPlay();
        }
    }
}

Для управления громкостью звука применяется класс AudioManager. А в с помощью вызова audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0); в качестве второго параметра можно передать нужное значение громкости.

Громкость в MediaPlayer в Android и Java
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850