VideoView使用小结

本文总结了在Android开发中播放视频的三种方式,重点探讨了VideoView的使用。VideoView作为封装好的控件,底层依赖于MediaPlayer和SurfaceView。示例代码展示了如何简单加载并循环播放本地视频文件,同时提到了布局文件和Activity中实现的代码片段,以及在清单文件中添加读写权限的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

安卓实现播放视频的方式
1、使用其自带的播放器。指定Action为ACTION_VIEW,Data为Uri,Type为其MIME类型。
2、使用VideoView来播放。在布局文件中使用VideoView结合MediaController来实现对其控制。
3、使用MediaPlayer类和SurfaceView来实现。
本文主要探讨VideoView的使用,VideoView是安卓提供的封装好的控件,底层也是通过MediaPlayer类和SurfaceView来实现。
//简单加载循环播放本地视频文件
//布局文件

<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drag_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:gravity="left"
        android:text="正在播放:"
        android:textColor="@color/color_black"
        android:textSize="20sp"
        app:layout_heightPercent="10%"
        app:layout_widthPercent="100%" />

    <RelativeLayout
        android:id="@+id/ll"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_below="@id/tv_name"
        app:layout_heightPercent="70%"
        app:layout_widthPercent="100%">

        <VideoView
            android:id="@+id/vv_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </RelativeLayout>
    <Button
        android:id="@+id/tv_quanpin"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:text="全屏播放"
        app:layout_heightPercent="10%"
        app:layout_widthPercent="100%"
        android:layout_below="@+id/ll"
        android:layout_alignParentLeft="true" />
</android.support.percent.PercentRelativeLayout>

//Activity中代码

public class MainActivity extends AppCompatActivity {

    @InjectView(R.id.tv_name)
    TextView tvName;
    @InjectView(R.id.vv_main)
    VideoView vvMain;
    @InjectView(R.id.tv_quanpin)
    Button button;
    private int i = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.inject(this);
        final List<String> pathList = new ArrayList<String>();
        //Uri uri = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.raw.cxgk);
        getPath(pathList);
         //vvMain.setVideoURI(uri);//raw目录下面的文件
       vvMain.setVideoPath(pathList.get(i));
        vvMain.setMediaController(new MediaController(this));//设置控制器
        vvMain.start();
        vvMain.requestFocus();
        vvMain.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {
                tvName.setText("当前播放:"+pathList.get(i));

            }
        });
        vvMain.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {
                if(i>=pathList.size()-1){
                    vvMain.setVideoPath(pathList.get(i));
                    vvMain.start();
                    i=0;
                }else if(i<pathList.size()){
                    i++;
                    vvMain.setVideoPath(pathList.get(i));
                    vvMain.start();//设置循环播放文件夹中的视频
                }

            }
        });
        //可以自己处理错误信息
        vvMain.setOnErrorListener(new MediaPlayer.OnErrorListener() {
            @Override
            public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
                if (i == MediaPlayer.MEDIA_ERROR_SERVER_DIED) { 
                //媒体服务器挂掉了。此时,程序必须释放MediaPlayer 对象,并重新new 一个新的。
                    return true;
                } else if (i == MediaPlayer.MEDIA_ERROR_IO) { 
                //网络访问错误
                    return true;
                } else if (i == MediaPlayer.MEDIA_ERROR_MALFORMED) {
                //流不符合有关标准或文件的编码规范
                    return true;
                } else if (i == MediaPlayer.MEDIA_ERROR_UNSUPPORTED) { 
                //比特流符合相关编码标准或文件的规格,但媒体框架不支持此功能
                    return true;
                } else if (i == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
                    return true;
                } else if (i == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
                    return true;
                } else if (i == MediaPlayer.MEDIA_ERROR_UNKNOWN) {
                    return true;
                }
                return false;
            }
//vedeoView提供的一些API调用
//        int getCurrentPosition():获取当前播放的位置。
//        int getDuration():获取当前播放视频的总长度。
//        isPlaying():当前VideoView是否在播放视频。
//        void pause():暂停
//        void seekTo(int msec):从第几毫秒开始播放。
//        void resume():重新播放。
//        void setVideoPath(String path):以文件路径的方式设置VideoView播放的视频源。
//        void setVideoURI(Uri uri):以Uri的方式设置VideoView播放的视频源,可以是网络Uri或本地Uri。
//        void start():开始播放。
//        void stopPlayback():停止播放。
//        setMediaController(MediaController controller):设置MediaController控制器。
//        setOnCompletionListener(MediaPlayer.onCompletionListener l):监听播放完成的事件。
//        setOnErrorListener(MediaPlayer.OnErrorListener l):监听播放发生错误时候的事件。
//        setOnPreparedListener(MediaPlayer.OnPreparedListener l)::监听视频装载完成的事件。
//手动切换横屏和竖屏
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (getRequestedOrientation() == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                } else {
                    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                }
            }
        });


    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {//横屏
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().getDecorView().invalidate();
            float height = Util.getWidthInPx(this);
            float width = Util.getHeightInPx(this);
            vvMain.getLayoutParams().height = (int) width;//getLayoutParams相对viewGroup来说
            vvMain.getLayoutParams().width = (int) height;
        } else {
            final WindowManager.LayoutParams attrs = getWindow().getAttributes();
            attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().setAttributes(attrs);
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);//
            float width = Util.getWidthInPx(this);
            float height = Util.dip2px(this, 200.f);
            vvMain.getLayoutParams().height = (int) height;
            vvMain.getLayoutParams().width = (int) width;
        }
    }

    public void getPath(List<String> list) {
        String path = Environment.getExternalStorageDirectory().getPath() + "/新文件夹2/";
        File files = new File(path);
        if (files.exists() && files.isDirectory()) {
            File[] files1 = files.listFiles();
            if (files1 != null && files1.length > 0) {
                for (File file2 : files1) {
                    list.add(file2.getAbsolutePath());
                }
            }
        }
    }
}

清单文件中加入读写权限

  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> //按需申请
  <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> //按需申请
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值