安卓 MediaPlayer本地视频播放器 - 新手笔记

一.github地址:https://github.com/lingchen1854/LCPlayerAPP.git

二.硬件调试:华为nove 2s

三.部分代码:

1.MainActivity.java

// 安卓6.0以上需要获取权限

package com.likego.lcplayerapp;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity {

    private String TAG = "MainActivity xmlc";

    private String[] mPermissions = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE };

    private int READ_EXTERNAL_STORAGE_CONSTANT = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate: ");

        getPermissions();

    }

    private void getPermissions(){
        int permission = ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.READ_EXTERNAL_STORAGE);
        if (permission == PackageManager.PERMISSION_GRANTED) {
            Log.d(TAG, "onCreate: 表示已经授权,进入列表");
            Intent startList = new Intent("com.likego.xmlc.Player.ListActivity");
            startActivity(startList);
            finish();
        }else {
            Log.d(TAG, "onCreate: 表示权限被否认或首次请求权限,当前申请权限,并监听申请结果");
            ActivityCompat.requestPermissions(MainActivity.this,mPermissions,
                    READ_EXTERNAL_STORAGE_CONSTANT);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == READ_EXTERNAL_STORAGE_CONSTANT && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Log.d(TAG, "onRequestPermissionsResult: 监听到是当前申请的权限,且SDK的版本>=AndroidM(6.0)");
            if (shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE)) {
                Log.d(TAG, "权限被拒绝,进入设置打开权限");
                AskForPermission();
            }else {
                Log.d(TAG, "已获得权限,打开列表");
                Intent startList = new Intent("com.likego.xmlc.Player.ListActivity");
                startActivity(startList);
                finish();
            }
        }
    }

    private void AskForPermission() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("需要权限!");
        builder.setNegativeButton("退出", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ActivityCompat.requestPermissions(MainActivity.this,mPermissions,
                        READ_EXTERNAL_STORAGE_CONSTANT);
            }
        });
        builder.setPositiveButton("设置", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                intent.setData(Uri.parse("package:" + getPackageName())); // 根据包名打开对应的设置界面
                startActivity(intent);
            }
        });
        builder.create().show();
    }

}

2.ListActivity.java

// 扫描内部存储获取列表

package com.likego.lcplayerapp;

import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaMetadataRetriever;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ProgressBar;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class ListActivity extends Activity {

    private static final String TAG = "ListActivity xmlc";
    private static HashMap<String,String> MediaHash;
    private ProgressBar mProgressBar;
    private Button mButtonAll;
    private Button mButtonDownload;
    private Button mButtonSdcard;
    private static final int MSG_VISIBLE = 1;
    private static final int MSG_GONE = 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_list);

        mProgressBar = findViewById(R.id.progressBarLarge);
        mHandler.sendEmptyMessage(MSG_GONE);
        mButtonAll = findViewById(R.id.all);
        mButtonAll.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new ScanSdcard("/storage/emulated/0/").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                mButtonAll.setVisibility(View.GONE);
                mButtonDownload.setVisibility(View.GONE);
                mButtonSdcard.setVisibility(View.GONE);

            }
        });
        mButtonDownload = findViewById(R.id.dowload);
        mButtonDownload.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new ScanSdcard("/storage/emulated/0/Download/").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                mButtonAll.setVisibility(View.GONE);
                mButtonDownload.setVisibility(View.GONE);
                mButtonSdcard.setVisibility(View.GONE);
            }
        });
        mButtonSdcard = findViewById(R.id.sdcard);
        mButtonSdcard.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                new ScanSdcard("/storage/external_storage/sdcard1").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
                mButtonAll.setVisibility(View.GONE);
                mButtonDownload.setVisibility(View.GONE);
                mButtonSdcard.setVisibility(View.GONE);
            }
        });




    }

    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            switch (message.what){
                case MSG_VISIBLE:
                    mProgressBar.setVisibility(View.VISIBLE);
                    break;
                case MSG_GONE:
                    mProgressBar.setVisibility(View.GONE);
                    break;
                default:
                    break;
            }
            return false;
        }
    });

    /***
     * 根据播放路径设置缩略图
     * @param filePath 视频资源的路径
     * @return 返回缩略图的Bitmap对象
     */
    public Bitmap getVideoThumbNail(String filePath) {
        long startTime = System.currentTimeMillis();
        Bitmap bitmap = null;
        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(filePath);
            bitmap = retriever.getFrameAtTime();//60*1000*1000

        }
        catch(IllegalArgumentException e) {
            e.printStackTrace();
        }
        catch (RuntimeException e) {
            e.printStackTrace();
        }
        finally {
            try {
                retriever.release();
            }
            catch (RuntimeException e) {
                e.printStackTrace();
            }
        }
        long endTime = System.currentTimeMillis();
        long runTime = endTime - startTime;
        if (bitmap != null){
//            bitmap = Bitmap.createScaledBitmap(bitmap, 640, 360, true);
            Log.d(TAG, filePath+"  时间 : "+ runTime + " ms "+""+bitmap.getWidth()+" * "+bitmap.getHeight());
            return bitmap;
        }else {
            Resources res=getResources();
            Bitmap nullBitmap = BitmapFactory.decodeResource(res, R.drawable.bitmap_null);
            Log.d(TAG, filePath+"  时间 : "+ runTime + " ms "+""+nullBitmap.getWidth()+" * "+nullBitmap.getHeight());
            return nullBitmap;
        }
    }

    public class ScanSdcard extends AsyncTask<Void, Void, Void> {

        private static final String TAG = "ScanSdcard xmlc";
        private long mStartTime = System.currentTimeMillis();
        private ArrayList MediaNameList;

        private List<MediaInfo> MediaList = new ArrayList<MediaInfo>();

        public ScanSdcard(String path) {
            super();
            scanSdcard(path);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            Log.d(TAG, "----------onPreExecute: onCreate Scan Sdcard----------");
            MediaNameList = new ArrayList();
            MediaHash = new HashMap<>();
        }

        @Override
        protected Void doInBackground(Void... voids) {
            Log.d(TAG, "doInBackground: ->>>>>--");
            mHandler.sendEmptyMessage(MSG_VISIBLE);
            initMediaImage();
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            Log.d(TAG, "onPostExecute: -----doInBackground over , You can update UI-----" +
                    "\n ----------视频文件数量 = "+MediaNameList.size());
            if (MediaNameList.size() == 0){
                mButtonAll.setVisibility(View.VISIBLE);
                mButtonDownload.setVisibility(View.VISIBLE);
                mButtonSdcard.setVisibility(View.VISIBLE);
            }
            long endTime = System.currentTimeMillis();
            long runTime = endTime - mStartTime;
            Log.d(TAG, "方法使用时间 : "+ runTime + " ms");
            RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
            StaggeredGridLayoutManager layoutManager = new
                    StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
            recyclerView.setLayoutManager(layoutManager);
            MediaAdapter adapter = new MediaAdapter(MediaList,ListActivity.this);
            recyclerView.setAdapter(adapter);

        }

        private void scanSdcard(String path){
            File sdcardFile = new File(path);
            File[] sdcardFileList = sdcardFile.listFiles();
            if (sdcardFileList == null) {
                Log.d(TAG, "f is null");
                return;
            }
            for (File f : sdcardFileList) {
                if (f.isFile()){
                    if (f.getName().toLowerCase().endsWith(".mp4")
                            || f.getName().toLowerCase().endsWith(".mkv")){
                        MediaNameList.add(f.getName());
                        MediaHash.put(f.getName(),f.getAbsolutePath());
                        Log.d(TAG, "scanSdcard: "+f.getName());
                    }
                }else if (f.isDirectory()) {
                    scanSdcard(f.getPath());
                    Log.d(TAG, "scanSdcard: "+f.getName());
                }
            }
        }

        private void initMediaImage(){
            mHandler.sendEmptyMessage(MSG_VISIBLE);
            for (int i = 0; i < MediaNameList.size();i++){
                Bitmap bitmap = getVideoThumbNail(MediaHash.get(MediaNameList.get(i)));
                MediaInfo info = new MediaInfo(MediaNameList.get(i).toString(),
                        bitmap);
                MediaList.add(info);
            }
            mHandler.sendEmptyMessage(MSG_GONE);
        }

    }

    public static HashMap<String, String> getMediaHash() {
        return MediaHash;
    }

}

3.MediaAdapter.java

// 设置列表适配器

package com.likego.lcplayerapp;

import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.HashMap;
import java.util.List;

public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.ViewHolder> {

    private static final String TAG = "MediaAdapter xmlc";
    private List<MediaInfo> mMediaInfos;
    private Context mContext;

    public MediaAdapter(List<MediaInfo> fruitList, Context context) {
        mContext = context;
        mMediaInfos = fruitList;
        Log.d(TAG, "MediaAdapter: "+mMediaInfos.size());
    }

    public class ViewHolder extends RecyclerView.ViewHolder{

        View mediaView;
        ImageView mediaImage;
        TextView mediaName;

        public ViewHolder(View view) {
            super(view);
            mediaView = view;
            mediaImage = (ImageView) view.findViewById(R.id.media_image);
            mediaName = (TextView) view.findViewById(R.id.media_name);
        }
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.media_item,
                viewGroup, false);
        final ViewHolder holder = new ViewHolder(view);
        holder.mediaView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = holder.getAdapterPosition();
                MediaInfo mediaInfo = mMediaInfos.get(position);
                Log.d(TAG, "onClick:--->>name "+mediaInfo.getMediaName());
                HashMap<String,String> mediaHashMap = ListActivity.getMediaHash();
                String path = mediaHashMap.get(mediaInfo.getMediaName());
                Intent intent = new Intent(mContext, MediaPlayerActivity.class);
                intent.putExtra("path",path);
                mContext.startActivity(intent);
            }
        });
        holder.mediaImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int position = holder.getAdapterPosition();
                MediaInfo mediaInfo = mMediaInfos.get(position);
                Log.d(TAG, "onClick:--->>image  "+mediaInfo.getMediaName());
                HashMap<String,String> mediaHashMap = ListActivity.getMediaHash();
                String path = mediaHashMap.get(mediaInfo.getMediaName());
                Intent intent = new Intent(mContext, MediaPlayerActivity.class);
                intent.putExtra("path",path);
                mContext.startActivity(intent);
            }
        });
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        MediaInfo mediaInfo = mMediaInfos.get(i);
        viewHolder.mediaImage.setImageBitmap(mediaInfo.getMediaImage());
        viewHolder.mediaName.setText(mediaInfo.getMediaName());
    }

    @Override
    public int getItemCount() {
//        Log.d(TAG, "getItemCount: "+mMediaInfos.size());
        return mMediaInfos.size();
    }
}

4.MediaInfo.java

package com.likego.lcplayerapp;

import android.graphics.Bitmap;
import android.util.Log;

public class MediaInfo {

    private String mMediaName;

    private Bitmap mMediaBitmap;

    public MediaInfo(String name, Bitmap bitmap) {
        this.mMediaName = name;
        this.mMediaBitmap = bitmap;
    }

    public String getMediaName() {
        return mMediaName;
    }

    public Bitmap getMediaImage() {
        return mMediaBitmap;
    }

}

5.MediaPlayerActivity.java

// 从列表获取播放路径并播放

package com.likego.lcplayerapp;

import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
import android.view.WindowManager;

public class MediaPlayerActivity extends Activity {
    private  String TAG = "MediaPlayerActivity xmlc";
    private MediaPlayer mMediaPlayer;
    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_media_player);

        mSurfaceView = findViewById(R.id.SurfaceView);
        mSurfaceHolder = mSurfaceView.getHolder();
        Log.d(TAG, "onCreate: "+mSurfaceHolder.toString());
        mSurfaceHolder.addCallback(callback);

    }

    private SurfaceHolder.Callback callback = new SurfaceHolder.Callback(){
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {
            try {
                Intent intent = getIntent();
                String path = intent.getStringExtra("path");
                Log.d(TAG, "surfaceCreated: " + path);
                Uri uri = Uri.parse(path);
                mMediaPlayer = MediaPlayer.create(MediaPlayerActivity.this,uri);
                mMediaPlayer.setDisplay(mSurfaceHolder);
//                mMediaPlayer.prepareAsync();
                mMediaPlayer.start();

                mediaPlayerListener();
            }catch (Exception e){
                e.printStackTrace();
            }

        }

        @Override
        public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
            Log.d(TAG, "surfaceChanged: ");
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
            Log.d(TAG, "surfaceDestroyed: ");
        }
    };





    private void mediaPlayerListener(){
        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {
                Log.d(TAG, "onCompletion: 播放结束");
                if (mMediaPlayer != null){
                    mMediaPlayer.stop();
                    mMediaPlayer.release();
                    mMediaPlayer = null;
                }
            }
        });
        mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                Log.e(TAG, "onError: 播放错误"+i+","+i1);
                if (i == 1 && i1 == -1){
                    Log.d(TAG, "onError: 1");
                }else if (i == 100 && i1 == 0){
                    Log.d(TAG, "onError: 错误代码(100,0),该视频路径对应的存储设备不存在,无法缓存");
                }else if (i == -38 && i1 == 0){
                    Log.d(TAG, "onError: -38,0.播U盘1,切音乐,拔U盘1,切视频,空路径请求下一曲/突然拔U盘也会");
                }else if (i == 1 && i1 == -2147483648){
                    Log.d(TAG, "onError: Play方法出错,reset,缓存");
                }else if (i == 1 && i1 == -33554449){
                    Log.d(TAG, "onError: 拔U盘触发的");
                }else if (i == 1 && i1 == -33554485){
                    Log.d(TAG, "onError: 不支持的文件格式");
                }else {
                    Log.d(TAG, "onError: else");
                }
                return true;
            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mMediaPlayer != null){
            mMediaPlayer.pause();
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (mMediaPlayer != null){
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mMediaPlayer != null){
            mMediaPlayer.stop();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }
}

四、小结

    花了两天把这几个月学习的东西整合成这个项目,只是初版,并没有查找和解决BUG,还有许多可以优化的地方。还有重要的缺点,扫描列表和获取缩略图比较慢。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值