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>

    播放效果:

  • 相关阅读:
    ZOJ 1002 Fire Net (火力网)
    UVa OJ 117 The Postal Worker Rings Once (让邮差只走一圈)
    UVa OJ 118 Mutant Flatworld Explorers (变体扁平世界探索器)
    UVa OJ 103 Stacking Boxes (嵌套盒子)
    UVa OJ 110 MetaLoopless Sorts (无循环元排序)
    第一次遇到使用NSNull的场景
    NSURL使用浅析
    从CNTV下载《小小智慧树》
    NSDictionary and NSMutableDictionary
    Category in static library
  • 原文地址:https://www.cnblogs.com/android-deli/p/10142594.html
Copyright © 2011-2022 走看看