安卓浏览本地指定路径视频文件并播放

项目需要打开本地的一个指定路径下的文件夹,获取视频后再调用一个播放器播放。获取本地视频并生成缩略图我查到了两种思路:

1.使用安卓系统自带浏览器

这种方法不需要自己定义一个图片展示的布局文件,只写几行代码就可以,缺点是会获取存储中所有mp4和3gp的视频,无法指定打开路径,所以不符合项目需求没有采用。

先定义了一个按钮打开浏览器:

Button button2 = (Button) findViewById(R.id.xuanshipin);
        button2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType("video/*");//这里是设置打开文件的类型,也可以换成图片

                startActivityForResult(intent, VIDEO_CAPTURE1);//定义处理浏览结果的类,也就是说点击某一个文件后需要执行的操作,VIDEO_CAPTURE是参数,在多个按钮时使用
            }
        });

处理结果的类定义如下:
这里定义了一个imageview来显示选择后的视频第一帧,所及记得在一开始声明,bitmap和imageview

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == Activity.RESULT_OK && requestCode == VIDEO_CAPTURE0) {
            Uri uri = data.getData();
            Cursor cursor = this.getContentResolver().query(uri, null, null, null, null);
            if (cursor != null && cursor.moveToNext()) {
                int id = cursor.getInt(cursor.getColumnIndex(VideoColumns._ID));
                String filePath = cursor.getString(cursor.getColumnIndex(VideoColumns.DATA));
                 bitmap = Thumbnails.getThumbnail(getContentResolver(), id, Thumbnails.MICRO_KIND, null);
                // ThumbnailUtils类2.2以上可用
                // Bitmap bitmap = ThumbnailUtils.createVideoThumbnail(filePath,
                // Thumbnails.MICRO_KIND);
                imageView.setImageBitmap(bitmap);
                Log.d("ddd", "filepath==" + filePath);
                File file=new File(filePath);
                cursor.close();

            }
        }

        else if (resultCode == Activity.RESULT_OK && requestCode == VIDEO_CAPTURE1) {
            Uri uri = data.getData();
            File file = getFileByUri(uri);
             MediaMetadataRetriever mmr=new MediaMetadataRetriever();//实例化MediaMetadataRetriever对象  
             mmr.setDataSource(file.getAbsolutePath());
             bitmap=mmr.getFrameAtTime(2000);//获得视频第一帧的Bitmap对象
             String duration = mmr.extractMetadata(android.media.MediaMetadataRetriever.METADATA_KEY_DURATION);//时长(毫秒)
             Log.d("ddd","duration=="+duration);
            int int_duration= Integer.parseInt(duration);

             if(int_duration>45000){
                 Toast.makeText(getApplicationContext(), "视频时长超过45秒请重新选择", Toast.LENGTH_SHORT).show();;

             }
             imageView.setImageBitmap(bitmap);

        }

这种方法打开浏览器时很快,用户体验很好。

2.自己定义listview

缺点是代码量大,而且耗时操作不会处理

先看布局文件,其实也不怎么费事:
线性布局下整个listview

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Choose_video" >

    <LinearLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView 
        android:id="@+id/lv_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    </LinearLayout>

</RelativeLayout>

然后是往布局里填充文件预览图片的操作,直接是一个activity,

public class Choose_video extends Activity implements OnItemClickListener{

    private String cur_path=Environment.getExternalStorageDirectory().toString()+"/VRDemo/video/";//这里就是自定义打开路径啦
    private List<Picture> listPictures;
    ListView listView ;

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            if (msg.what == 0) {
                List<Picture> listPictures = (List<Picture>) msg.obj;
                MyAdapter adapter = new MyAdapter(listPictures);
                listView.setAdapter(adapter);
            }
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.choose_video);
        new Thread(new Runnable() {

            @Override
            public void run() {

                loadVaule();//oncreate()里定义这个方法特别耗时,导致整个界面启动超级慢,需要4/5秒的样子

            }
        }).start();
    }
    //下面就看看这个方法里有多耗时
    private void loadVaule(){
        File file = new File(cur_path);
        File[] files  = null;
        files = file.listFiles();
        listPictures = new ArrayList<Picture>();
        for (int i = 0; i < files.length; i++) {
            Picture picture = new Picture();
            picture.setBitmap(getVideoThumbnail(files[i].getPath(), 200, 200, MediaStore.Images.Thumbnails.MICRO_KIND));
            picture.setPath(files[i].getPath());
            listPictures.add(picture);

        }
        listView = (ListView) findViewById(R.id.lv_show);
        listView.setOnItemClickListener(this);
        Message msg = new Message();
        msg.what = 0;
        msg.obj = listPictures;

        handler.sendMessage(msg);

    }


      //获取视频的缩略图
    private Bitmap getVideoThumbnail(String videoPath, int width, int height, int kind) {   
           Bitmap bitmap = null;  
                // 获取视频的缩略图  
           bitmap = ThumbnailUtils.createVideoThumbnail(videoPath, kind);  
//         System.out.println("w"+bitmap.getWidth());  
//         System.out.println("h"+bitmap.getHeight());  
           bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,  
           ThumbnailUtils.OPTIONS_RECYCLE_INPUT);  
           return bitmap;  
    }


//定义适配器放listview                
public class MyAdapter extends BaseAdapter {
                    private List<Picture> listPictures;

                    public MyAdapter(List<Picture> listPictures) {
                        super();
                        this.listPictures = listPictures;

                    }

                    @Override
                    public int getCount() {
                        // TODO Auto-generated method stub
                        return listPictures.size();
                    }

                    @Override
                    public Object getItem(int position) {
                        // TODO Auto-generated method stub
                        return listPictures.get(position);
                    }

                    @Override
                    public long getItemId(int position) {
                        // TODO Auto-generated method stub
                        return position;
                    }

                    @Override
                    public View getView(int position, View v, ViewGroup arg2) {
                        // TODO Auto-generated method stu
                        View view = getLayoutInflater().inflate(R.layout.item,null);
                        ImageView imageView = (ImageView) view.findViewById(R.id.iv_show);
                        TextView textView = (TextView) view.findViewById(R.id.tv_show);

                        imageView.setImageBitmap(listPictures.get(position).getBitmap());
                        textView.setText(listPictures.get(position).getPath());
                        return view;

                    }
                }





    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1,
                        int arg2, long arg3) {
        // TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "点击了"+arg2, 200).show();
    startPlay(this, listPictures.get(arg2).getPath());//点击后打开播放器
    Log.e("path", listPictures.get(arg2).getPath());
                }


public static void startPlay(Context context, String url) {
                    if (url.contains(".mp4") || url.contains(".MP4")) {
                        Intent intent = new Intent();
                        intent.setClassName(context, "com.easemob.chatuidemo.activity.VideoPlayerActivity");
                        intent.putExtra("playpath", url);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(intent);
                    }else if(url.contains("rtsp") || url.contains("RTSP")){
                        Intent intent = new Intent();
                        intent.setClassName(context, "com.easemob.chatuidemo.activity.MakeVideoActivity");
                        intent.putExtra("playpath", url);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(intent);
                    } else if (url.contains(".jpg") || url.contains(".png")) {
                        Intent intent = new Intent();
                        intent.setClassName(context, "com.easemob.chatuidemo.activity.VideoPlayerActivity");
                        intent.putExtra("playpath", "/sdcard/VRDemo/capture/aa.jpg");
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(intent);

                    }else {
                        Toast.makeText(context, "没有资源哦", Toast.LENGTH_SHORT).show();
                        Intent intent = new Intent();
                        intent.setClassName(context, "com.easemob.chatuidemo.activity.MainActivity");
                    }
                }


}

onCreate()里有耗时操作的解决办法:
(1)在Activity启动前,尽量少做。
(2)对于布局比较复杂的时候,可以考虑不要一次性全部加载上,动态加载是一个好的办法。
(3)对于及时需要的数据,加载起来耗时的又有异常危险的,一定记得开辟一个线程来做这些动作,千万记得不要做阻塞主线程(UI线程)的任何事情。
(4)对于特殊情况下,Activity启动确实需要大量工作时候,可以考虑先加载一个简单的布局(或是Activity)来过渡.

猜你喜欢

转载自blog.csdn.net/ulike_mfy/article/details/54134579