Android MediaPlayer 播放音频

本文链接: Android MediaPlayer 播放音频

主要介绍使用MediaPlayer播放音频的方式。关于MediaPlayer的基础知识,比如状态,可以参考Android MediaPlayer 基础简介

为了方便表达,定义变量名为mediaPlayer。

MediaPlayer的使用方式

创建MediaPlayer

可以直接 new MediaPlayer,也可以用MediaPlayer提供的create方法创建。

mediaPlayer = new MediaPlayer();

使用create方法创建成功后,mediaPlayer处于Prepared状态。可以直接start播放。

    mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.fromFile(file));
    mediaPlayer.start();

设置音源 - setDataSource

通过调用setDataSource来设置音源。setDataSource有多个重载方法,我们来看常用的几种。

例如设置使用assets里的资源。实际情况可能需要try catch。

    AssetFileDescriptor fd = null;
    MediaPlayer mediaPlayer = new MediaPlayer();
    fd = context.getApplicationContext().getAssets().openFd(name);
    mediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());

本地文件,需要文件的绝对路径。

mediaPlayer.setDataSource(file.getAbsolutePath());

或者获取文件的Uri来创建mediaPlayer。

mediaPlayer = MediaPlayer.create(getApplicationContext(), Uri.fromFile(file));

设置网络音频,也是用setDataSource方法,设置url。

mediaPlayer.setDataSource("https://demo.com/sample.mp3"));

播放网络音频时,如果使用的是http,有可能会报错

java.io.IOException: Cleartext HTTP traffic to demo.com not permitted

可以简单地设置一下manifest,设置usesCleartextTraffic="true"

<application
        android:usesCleartextTraffic="true">

准备 - prepare

同步和异步准备音频资源。prepareAsync()是异步的方式,prepare是同步的。注意线程调度问题,同时不要阻塞UI线程。

使用异步方式准备音频,经常与MediaPlayer.OnPreparedListener监听器配合使用。异步准备时,也可以进行其他的设置。

    mediaPlayer.prepareAsync();
    mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mediaPlayer) {
            mediaPlayer.start(); // 准备好了就播放
        }
    });

循环播放 - Looping

设置循环播放setLooping。

mediaPlayer.setLooping(true);

播放完毕后,不会回调OnCompletionListener,而是从头播放当前音频。

播放 - start

播放音频,调用start方法。

mediaPlayer.start();

处于Prepared,Pause和PlaybackComplete状态时,可以调用start方法,进入Started状态。

暂停 - pause

暂停播放,使用pause方法。在暂停前先判断一下mediaPlayer的是否在播放。

    if (mediaPlayer.isPlaying()) {
        mediaPlayer.pause();
    }

暂停成功则处于Paused状态。

停止 - stop

回顾一下MediaPlayer状态切换的图示,我们可以得知在播放中,暂停,播放完成这3个状态下,可以调用stop方法,进入Stopped状态。

mediaPlayer.stop();

调进度 - seekTo

调整播放进度。我们平时使用音乐播放软件一般都会有这个功能。
seekTo方法接受一个毫秒参数。

    int targetMS = (int) (percent * mediaPlayer.getDuration());
    mediaPlayer.seekTo(targetMS);

seekTo并不会改变MediaPlayer的状态。

重置 - reset

reset后的mediaPlayer进入Idle状态。需要重新设置音源与准备。

释放 - release

不再使用这个mediaPlayer时,应当尽快释放掉,以释放相关的资源。
调用release后,mediaPlayer进入End状态。此时这个mediaPlayer就不能再使用了。

常用监听器

缓冲监听器 OnBufferingUpdateListener

比如我们加载网络音频的时候,常用这个监听器来监听缓冲进度。显示缓冲进度,也可以提高用户体验。

    mMediaPlayer.prepareAsync();
    mMediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
        @Override
        public void onBufferingUpdate(MediaPlayer mp, int percent) {
            // percent代表缓冲百分比
        }
    });

错误监听器 OnErrorListener

mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
    @Override
    public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
        return true; // 返回true表示在此处理错误,不会回调onCompletion
    }
});

注意onError的返回值。可以选择自己处理error。

         * @return True if the method handled the error, false if it didn't.
         * Returning false, or not having an OnErrorListener at all, will
         * cause the OnCompletionListener to be called.
         */
        boolean onError(MediaPlayer mp, int what, int extra);

播放完毕监听器 OnCompletionListener

mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        // 播放完毕
    }
});

使用示例

播放assets里的音频

播放assets里的音频文件,使用到AssetFileDescriptor类。使用后记得关闭AssetFileDescriptor。

    private void playAssetsAudio(final String name, Context context) {
        Log.d(TAG, "playAssetWordSound: try to play assets sound file. -> " + name);
        AssetFileDescriptor fd = null;
        try {
            MediaPlayer mediaPlayer;
            Log.v(TAG, "Looking in assets.");
            fd = context.getApplicationContext().getAssets().openFd(name);
            mediaPlayer = new MediaPlayer();
            mediaPlayer.reset();
            mediaPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    Log.d(TAG, "onPrepared: " + name);
                    mediaPlayer.start();
                }
            });
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    mp.release();
                    Log.d(TAG, "onCompletion: " + name);
                }
            });
            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mp, int i, int i1) {
                    mp.release();
                    return true;
                }
            });
        } catch (Exception e) {
            try {
                if (fd != null) {
                    fd.close();
                }
            } catch (Exception e1) {
                Log.e(TAG, "Exception close fd: ", e1);
            }
        } finally {
            if (fd != null) {
                try {
                    fd.close();
                } catch (IOException e) {
                    Log.e(TAG, "Finally, close fd ", e);
                }
            }
        }
    }

播放本地音频文件

尝试播放音频文件。仅播放一次。

    private void playAudioFile(final File file) {
        Log.d(TAG, "playAudioFile: " + file.getAbsolutePath());
        MediaPlayer mediaPlayer;
        try {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setLooping(false);
            mediaPlayer.setDataSource(file.getAbsolutePath());
            mediaPlayer.prepare();
            mediaPlayer.start();
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    mp.release();
                }
            });
            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                    Log.d(TAG, "Play local sound onError: " + i + ", " + i1);
                    return true;
                }
            });
        } catch (Exception e) {
            Log.e(TAG, "playAudioFile: ", e);
        }
    }

播放在线音频

设置url,播放在线音频

    private void playOnlineSound(String soundUrlDict) {
        try {
            MediaPlayer mediaPlayer = new MediaPlayer();
            mediaPlayer.setDataSource(soundUrlDict);
            mediaPlayer.prepareAsync();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mediaPlayer) {
                    mediaPlayer.start();
                }
            });
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    if (mp != null) {
                        mp.release();
                    }
                    Log.d(TAG, "onCompletion: play sound.");
                }
            });
            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                    Log.d(TAG, "Play online sound onError: " + i + ", " + i1);
                    return false;
                }
            });
        } catch (IOException e1) {
            Log.e(TAG, "url: ", e1);
        }
    }

代码可以参考示例工程: https://github.com/RustFisher/android-MediaPlayer

原文地址:https://www.cnblogs.com/rustfisher/p/11568524.html

时间: 2024-11-06 17:25:35

Android MediaPlayer 播放音频的相关文章

Android(java)学习笔记180:Android MediaPlayer 播放prepareAsync called in state 8解决办法

使用android MediaPlayer播放音频文件时,有时会出现prepareasync called in state 8错误. 以下方法可以避免这个异常出现.  第一种方法: private void playAudio(String audioUri){ Uri uri = Uri.parse(audioUri); mMediaPlayer = MediaPlayer.create(getApplicationContext(), uri); try { //在播放之前先判断playe

【Android】播放音频的几种方式介绍

接下来笔者介绍一下Android中播放音频的几种方式,android.media包下面包含了Android开发中媒体类,当然笔者不会依次去介绍,下面介绍几个音频播放中常用的类: 1.使用MediaPlayer播放音频 MediaPlayer的功能很强大,下面附上一张该类封装音频的生命周期图: MediaPlayer支持AAC.AMR.FLAC.MP3.MIDI.OGG.PCM等格式,MediaPlayer可以通过设置元数据和播放源来音频. 1.1播放Raw文件夹下面音频的元数据 //直接创建,不

从零开始学android&lt;Mediaplayer播放器组件(播放音频).四十八.&gt;

在win计算机中播放视频和音频往往会使用到计算机当中的windowsMediaPlayer播放器,而在Android中则同样会使用mediaplayer播放器对音频和视频进行播放. 下图是mediaplayer的生命周期 dle状态:当使用关键字new实例化一个MediaPlayer对象或者是调用了类中的reset()方法会进入到此状态: End状态:当调用release()方法之后将进入到此状态,此时会释放掉所有占用的硬件和软件资源,并且不会再进入到其他的任何一种状态了: Initialize

使用MediaPlayer播放音频-----之二

MediaPlayer播放不同来源的音频文件: 一.播放应用的资源文件 1.调用MediaPlayer的create(Context  context , int  resid)方法加载指定资源文件. 2.调用MediaPlayer的start().pause().stop()等方法控制播放即可. 注:音频资源文件一般放在Android应用的/res/raw目录下. 二.播放应用的原始资源文件 1.调用Context的getAssets()方法获取应用的AssetManager. 2.调用Ass

Android MediaPlayer播放音乐并实现进度条

提前工作,往sd卡里放音乐文件 1.布局文件main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="

【转】解决在Android设备播放音频与其他应用重音的问题,并监听耳机的控制按钮

概述 在安卓开发中免不了需要播放一点音乐了,音频了.但是这时候有别的应用正在播放,这时候就会出现重音的现象,完全影响用户体验,我们的项目就遇上了这样的尴尬,然后查找了一些文档,记录一下: 管理音频焦点 从谷歌开发了解到,这跟音频的焦点又关系,我们可以获取当前音频的焦点来解决问题: 有多个应用程序可能播放音频,重要的是要考虑他们应该如何交互.为了避免每个音乐应用程序同时播放,Android使用音频焦点来控制音频播放 - 只有拥有音频焦点的应用程序才能播放音频. 在您的应用程序开始播放音频之前,应该

Android 简单播放音频

简单介绍: 播放声音有两种.一种是SoundPool,一种是MediaPlayer. SundPool用于播放短小的音乐,比如游戏里面的特效音,按键音等等. MediaPlayer可以播放视频和音频. 1.使用SoundPool package com.shao; import android.app.Activity; import android.media.AudioManager; import android.media.MediaPlayer; import android.medi

Android MediaPlayer播放raw资源封装类

import android.content.Context; import android.media.MediaPlayer; import com.bhuitong.yibaocan.R; public class MediaUtil { MediaPlayer mPlayer=null; Context context; public MediaUtil(Context context){ this.context=context; } //释放 public void Release(

MediaPlayer 播放音频问题汇总

最近界面里要添加语音功能,记录下做的过程中遇到的问题: 1.java.io.IOException: Prepare failed.: status=0x1 解决方法: mp.setDataSource(PATH_TO_FILE);mp.prepare();这个地方修改如下:File file = new File(strPath);FileInputStream fis = new FileInputStream(file);mediaPlayer.setDataSource(fis.getF