zoukankan      html  css  js  c++  java
  • andriod 播放mp4

    权限
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    activity_main.xml //gisoracle 版权所有

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <EditText
                android:id="@+id/et_path"
                android:layout_width="500px"
                android:layout_height="wrap_content"
                android:text="/sdcard/a.mp4" />
    
            <Button
                android:id="@+id/btn_browse"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="浏览" />
        </LinearLayout>
    
    
        <SeekBar
            android:id="@+id/seekBar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <Button
                android:id="@+id/btn_play"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="播放" />
    
            <Button
                android:id="@+id/btn_pause"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="暂停" />
    
            <Button
                android:id="@+id/btn_replay"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="重播" />
    
            <Button
                android:id="@+id/btn_stop"
                android:layout_width="0dip"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="停止" />
            <TextView
                android:id="@+id/textView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="时间:" />
        </LinearLayout>
    
        <VideoView
            android:id="@+id/vv_videoview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />
    
    </LinearLayout>

     java //gisoracle 版权所有

    package com.example.yanlei.myapplication;
    
    import android.media.MediaMetadataRetriever;
    import android.media.MediaPlayer;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Intent;
    import android.content.pm.ActivityInfo;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.provider.MediaStore;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.SeekBar;
    import android.widget.TextView;
    import android.widget.Toast;
    import android.widget.VideoView;
    import android.app.Activity;
    import android.media.MediaPlayer;
    import android.media.MediaPlayer.OnCompletionListener;
    import android.media.MediaPlayer.OnErrorListener;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.SeekBar;
    import android.widget.Toast;
    import android.widget.VideoView;
    import android.widget.SeekBar.OnSeekBarChangeListener;
    
    import java.io.File;
    import java.util.HashMap;
    
    import android.os.Handler;
    
    public class MainActivity extends AppCompatActivity {
    
        private final String TAG = "main";
        private EditText et_path;
        private Button btn_play, btn_pause, btn_replay, btn_stop, btn_browse;
        private SeekBar seekBar;
        private VideoView vv_video;
        private boolean isPlaying;
        private TextView pTextView = null;
        private Handler handler = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            seekBar = (SeekBar) findViewById(R.id.seekBar);
            et_path = (EditText) findViewById(R.id.et_path);
            vv_video = (VideoView) findViewById(R.id.vv_videoview);
            pTextView = (TextView) findViewById(R.id.textView);
    
            btn_play = (Button) findViewById(R.id.btn_play);
            btn_pause = (Button) findViewById(R.id.btn_pause);
            btn_replay = (Button) findViewById(R.id.btn_replay);
            btn_stop = (Button) findViewById(R.id.btn_stop);
            btn_browse = (Button) findViewById(R.id.btn_browse);
    
            btn_play.setOnClickListener(click);
            btn_pause.setOnClickListener(click);
            btn_replay.setOnClickListener(click);
            btn_stop.setOnClickListener(click);
            btn_browse.setOnClickListener(click);
    
            // 为进度条添加进度更改事件
            seekBar.setOnSeekBarChangeListener(change);
    
            //创建属于主线程的handler
            handler = new Handler();
    
        }
    
        private OnSeekBarChangeListener change = new OnSeekBarChangeListener() {
    
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // 当进度条停止修改的时候触发
                // 取得当前进度条的刻度
                int progress = seekBar.getProgress();
                if (vv_video != null && vv_video.isPlaying()) {
                    // 设置当前播放的位置
                    vv_video.seekTo(progress);
                }
            }
    
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
    
            }
    
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress,
                                          boolean fromUser) {
    
            }
        };
        private View.OnClickListener click = new View.OnClickListener() {
    
            @Override
            public void onClick(View v) {
    
                switch (v.getId()) {
                    case R.id.btn_play:
                        play(0);
                        break;
                    case R.id.btn_pause:
                        pause();
                        break;
                    case R.id.btn_replay:
                        replay();
                        break;
                    case R.id.btn_stop:
                        stop();
                        break;
                    case R.id.btn_browse:
                        browse();
                        break;
                    default:
                        break;
                }
            }
        };
    
        //获得MP4时长
        private int getTimeLong(String videoPath) {
    
    
            MediaMetadataRetriever retr = new MediaMetadataRetriever();
            retr.setDataSource(videoPath);
            //String height = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT); // 视频高度
            //String width = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH); // 视频宽度
            //String rotation = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION); // 视频旋转方向
            String timelong = retr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);//时长,单位为毫秒
            retr.release();
            int l = Integer.parseInt(timelong);
            return l;
    
        }
    
        String myText = "";
    
        protected void play(int msec) {
            Log.i(TAG, " 获取视频文件地址");
            String path = et_path.getText().toString().trim();
            File file = new File(path);
            if (!file.exists()) {
                Toast.makeText(this, "视频文件路径错误", 0).show();
                return;
            }
    
            Log.i(TAG, "指定视频源路径");
            vv_video.setVideoPath(file.getAbsolutePath());
            Log.i(TAG, "开始播放");
            vv_video.start();
    
            // 按照初始位置播放
            vv_video.seekTo(msec);
            // 设置进度条的最大进度为视频流的最大播放时长
            final int time = getTimeLong(file.getAbsolutePath()) / 100;
            seekBar.setMax(time);
            Toast.makeText(this, "长度:" + time, Toast.LENGTH_LONG).show();
            // 开始线程,更新进度条的刻度
            new Thread() {
    
                @Override
                public void run() {
                    try {
                        isPlaying = true;
                        while (isPlaying) {
                            // 如果正在播放,0.1.毫秒更新一次进度条
                            final int current = vv_video.getCurrentPosition() / 100;
                            seekBar.setProgress(current);
                         /*   try {
                                myText = "总时间:" + time / 10 + "秒,目前:" + current / 10 + "秒";
                                // pTextView.setText("总时间:" + time / 10 + "秒,目前:" + current / 10 + "秒");
                                new WorkThread().start();
                            } catch (Exception ex) {
    
                                Log.d("错误:", ex.getMessage().toString());
                            }*/
    
                            new Thread() {
                                public void run() {
                                    myText = "总时间:" + time / 10 + "秒,目前:" + current / 10 + "秒";
                                    handler.post(updateUIRunnable);
                                }
                            }.start();
    
                            //Toast.makeText(this, "当前:"+current,Toast.LENGTH_LONG).show();
                            sleep(100);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }.start();
            // 播放之后设置播放按钮不可用
            btn_play.setEnabled(false);
    
            vv_video.setOnCompletionListener(new OnCompletionListener() {
    
                @Override
                public void onCompletion(MediaPlayer mp) {
                    // 在播放完毕被回调
                    btn_play.setEnabled(true);
                }
            });
    
            vv_video.setOnErrorListener(new OnErrorListener() {
    
                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    // 发生错误重新播放
                    play(0);
                    isPlaying = false;
                    return false;
                }
            });
        }
    
    
    
        // 构建Runnable对象,并在runnable中更新UI
        Runnable updateUIRunnable = new Runnable() {
            @Override
            public void run() {
                try {
    
                    pTextView.setText(myText);
                } catch (Exception ex) {
                    Log.e("严重错误:", ex.getMessage().toString());
    
                }
            }
        };
    
        /**
         * 重新开始播放
         */
        protected void replay() {
            if (vv_video != null && vv_video.isPlaying()) {
                vv_video.seekTo(0);
                Toast.makeText(this, "重新播放", 0).show();
                btn_pause.setText("暂停");
                return;
            }
            isPlaying = false;
            play(0);
    
        }
    
        protected void browse() {
            Intent it = new Intent(Intent.ACTION_GET_CONTENT);    //创建动作为 "选取" 的 Intent
            it.setType("video/*");     //要选取所有视频类型
            startActivityForResult(it, 101);
    
        }
    
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
    
            if (resultCode == Activity.RESULT_OK) {
    
                Uri uri = convertUri(data.getData());  //获取选取文件的 Uri 并进行 Uri 格式转换
                et_path.setText(uri.getPath());  //显示文件名 (Uri 最后的节点文字)
                // txvUri.setText("文件位置:" + uri.getPath());//显示文件的路径
            }
        }
    
        Uri convertUri(Uri uri) { //将 "content://" 类型的 Uri 转换为 "file://" 的 Uri
            if (uri.toString().substring(0, 7).equals("content")) {  //如果是以 "content" 开头
                String[] colName = {MediaStore.MediaColumns.DATA};    //声明要查询的字段
                Cursor cursor = getContentResolver().query(uri, colName,  //以 uri 进行查询
                        null, null, null);
                cursor.moveToFirst();      //移到查询结果的第一个记录
                uri = Uri.parse("file://" + cursor.getString(0)); //将路径转为 Uri
                cursor.close();     //关闭查询结果
            }
            return uri;   //返回 Uri 对象
        }
    
        /**
         * 暂停或继续
         */
        protected void pause() {
            if (btn_pause.getText().toString().trim().equals("继续")) {
                btn_pause.setText("暂停");
                vv_video.start();
                Toast.makeText(this, "继续播放", 0).show();
                return;
            }
            if (vv_video != null && vv_video.isPlaying()) {
                vv_video.pause();
                btn_pause.setText("继续");
                Toast.makeText(this, "暂停播放", 0).show();
            }
        }
    
        /*
         * 停止播放
         */
        protected void stop() {
            if (vv_video != null && vv_video.isPlaying()) {
                vv_video.stopPlayback();
                btn_play.setEnabled(true);
                isPlaying = false;
            }
        }
    }
  • 相关阅读:
    122. Best Time to Buy and Sell Stock II
    121. Best Time to Buy and Sell Stock
    72. Edit Distance
    583. Delete Operation for Two Strings
    582. Kill Process
    indexDB基本用法
    浏览器的渲染原理
    js实现txt/excel文件下载
    git 常用命令
    nginx进入 配置目录时
  • 原文地址:https://www.cnblogs.com/gisoracle/p/7630064.html
Copyright © 2011-2022 走看看