zoukankan      html  css  js  c++  java
  • Android-MediaPlayer-音频播放-普通准备

    MediaPlayer是Android设计的媒体播放器,不仅仅可以播放音频文件,还可以播放视频文件

    播放:Audio(音频,.mp3)相关

    播放:Video(视频,.mp4)相关

    以下图,是Android官方提供:MediaPlayer时序图:

    只要会看这个图:就能实现音频/视频播放,暂停,继续,停止,重播,等等

    看图规律:

        1.蓝色椭圆形是状态,例如:Initialized已初始化状态,Prepared准备状态,Started启动状态,Stopped停止状态,End结束状态,等等;

        2.单箭头是方法调用:例如:调用reset方法重置,调用prepare方法准备,调用start方法播放,等等;

        3.双箭头是监听回调:例如:onError回调错误,等等


    此MediaPlayer播放使用普通准备,不使用异步准备

    package liudeli.my_media1;
    
    import android.database.Cursor;
    import android.media.MediaPlayer;
    import android.net.Uri;
    import android.os.SystemClock;
    import android.provider.MediaStore;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    
    /**
     * 此MediaPlayer播放使用普通准备,不使用异步准备
     */
    public class MediaPlayAudioActivity extends AppCompatActivity {
    
        private TextView tvPlayerPath;  // 显示播放的路径
        private TextView tvAudioInfo;   // 歌曲时长/歌手/专辑
        private TextView tvAudioThisDuration; // 当前播放的时长
    
        /**
         * 媒体播放器,可以播放(音频/视频)
         * 播放(音频/视频)操作一模一样
         */
        private MediaPlayer mediaPlayer;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_play_audio);
    
            tvPlayerPath = findViewById(R.id.tv_player_path);
            tvAudioInfo = findViewById(R.id.tv_audio_info);
            tvAudioThisDuration = findViewById(R.id.tv_audio_this_duration);
            mediaPlayer = new MediaPlayer();
    
            // 为了测试,这样写,真实开发中,不这样写
            new Thread(){
                @Override
                public void run() {
                    super.run();
                    while (true) {
    
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (mediaPlayer.isPlaying()) {
                                    tvAudioThisDuration.setText("当前时长:" + postions(mediaPlayer.getCurrentPosition()));
                                }
                            }
                        });
    
                        SystemClock.sleep(1000);
                    }
                }
            }.start();
    
            /**
             * 监听播放完成
             */
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    Log.d("mp", "播放完成");
                    Toast.makeText(MediaPlayAudioActivity.this, "播放完成", Toast.LENGTH_SHORT).show();
                    tvAudioThisDuration.setText("当前时长:-");
                }
            });
    
    
            /**
             * 去获取第一条外置存储的音频文件.mp3 的路径
             * 通过Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; 获取外置存储音频文件
             *    getContentResolver.query(uri)
             */
            initAudioPlayerPath();
        }
    
        /**
         * 去获取第一条外置存储的音频文件.mp3 的路径
         */
        private void initAudioPlayerPath() {
            Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            // 查询的列
            String[] projection = new String[]{MediaStore.Audio.Media.DATA, // 音频路径
                                               MediaStore.Audio.Media.DURATION, // 音频时长
                                               MediaStore.Audio.Media.ARTIST, // 歌手
                                               MediaStore.Audio.Media.ALBUM // 专辑
            };
            // 让Android系统也会去读取外置存储
            Cursor cursor = getContentResolver().query(uri,
                                       projection,
                                        null,
                                    null,
                                       null,
                                 null);
            if (cursor.moveToFirst()) {
                tvPlayerPath.setText(cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA)));
                String duration = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
                String artist = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
                String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
                tvAudioInfo.setText("歌曲时长:" + postions(Integer.parseInt(duration)) + " 
    歌手:" + artist + " 
    专辑:" + album);
            }
        }
    
        /**
         * 转换时长值
         */
        private String postions(int postion) {
            int musicTime =  postion / 1000;
    
            return musicTime / 60 + ":" + musicTime % 60;
        }
    
        /**
         * 开始播放:此次播放使用普通准备,不使用异步准备
         * @param view
         */
        public void player(View view) {
            try {
                // 重置
                mediaPlayer.reset();
                // 设置音频文件路径
                mediaPlayer.setDataSource(tvPlayerPath.getText().toString().trim());
                // 准备:是操作硬件在播放,所以需要准备
                mediaPlayer.prepare();
                // 开始
                mediaPlayer.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 暂停播放 继续播放
         * @param view
         */
        public void pause(View view) {
            /**
             * 这种方式可以拿到控件
             */
            Button pause_continue = (Button) view;
            if (mediaPlayer.isPlaying()) {
                pause_continue.setText("继续");
                // 暂停
                mediaPlayer.pause();
            } else {
                pause_continue.setText("暂停");
                // 继续播放
                mediaPlayer.start();
            }
        }
    
        /**
         * 停止播放
         */
        public void stop(View view) {
            // 停止播放
            mediaPlayer.stop();
        }
    
        /**
         * 重播
         * @param view
         */
        public void recorded(View view) {
            try {
                /**
                 * 一定要seekTo
                 *  因为由于没有执行reset,mediaPlayer不会从0开始播放,所以要设置
                 */
                mediaPlayer.seekTo(0);
                // 准备:是操作硬件在播放,所以需要准备
                mediaPlayer.prepare();
                // 播放
                mediaPlayer.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 此Activity销毁后,一定要
         *              mediaPlayer.release();
         *              mediaPlayer = null;
         * 因为 MediaPlayer 是操作硬件在播放,所以一定要释放资源
         */
        @Override
        protected void onDestroy() {
            super.onDestroy();
            mediaPlayer.release();
            mediaPlayer = null;
            System.gc();
        }
    }

    AndroidManifest.xml 配置 外部存储读取权限:

    Android系统也会去读取外置存储,需要读取外部存储的权限

      <!--
            getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, ...)
            Android系统也会去读取外置存储,需要读取外部存储的权限
        -->
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    布局文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MediaPlayAudioActivity"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp">
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="播放音频.mp3路径:"
                />
    
            <TextView
                android:id="@+id/tv_player_path"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="/mnt/sdcard/"
                />
    
        </LinearLayout>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="播放"
                android:onClick="player"
                />
    
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="暂停"
                android:onClick="pause"
                />
    
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="停止"
                android:onClick="stop"
                />
    
            <Button
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="重播"
                android:onClick="recorded"
                />
    
        </LinearLayout>
    
        <TextView
            android:id="@+id/tv_audio_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="test"
            />
    
        <TextView
            android:id="@+id/tv_audio_this_duration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="歌曲时长:-"
            />
    
    
    </LinearLayout>

    播放效果:

  • 相关阅读:
    Windows Phone 开发 MD5计算
    php 3des加密算法以及与java,.net,c#的交互的一致性
    <加密算法c#>——— 3DES加密之ECB模式 和 CBC模式
    Blend PathListBox 使用
    计算机的几种类型单词、快捷键
    【SQL Server】 数据定义语言(定义基本表、完整性约束实现、索引)
    【SQL Server】 数据查询语句
    【WindowsPhone】 独立存储
    终结,铭记
    Day 3,4,5
  • 原文地址:https://www.cnblogs.com/android-deli/p/10142594.html
Copyright © 2011-2022 走看看