zoukankan      html  css  js  c++  java
  • 第二十四篇-用VideoView制作一个简单的视频播放器

    使用VideoView播放视频,视频路径有三种:

    1. SD卡中

    2. Android的资源文件中

    3. 网络视频

    第一种,SD卡中的方法。

    路径写绝对路径,如果不能播放,可以赋予读取权限。

    效果图:

    MainActivity.java

    package com.example.aimee.videotest;
    
    import android.Manifest;
    import android.content.pm.PackageManager;
    import android.net.Uri;
    import android.os.Build;
    import android.support.annotation.NonNull;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.WindowManager;
    import android.widget.MediaController;
    import android.widget.Toast;
    import android.widget.VideoView;
    
    public class MainActivity extends AppCompatActivity {
        private final int REQUESTCODE=101;
        private VideoView videoView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.layout);
    
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            if(Build.VERSION.SDK_INT>= Build.VERSION_CODES.M){
                int checkSelfPermission=checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
                if(checkSelfPermission== PackageManager.PERMISSION_DENIED){
                    requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},REQUESTCODE);
                }
            }
            play_mp4();
    
        }
    
        private void play_mp4(){
            String videoUrl1 = "/storage/emulated/0/save/a1.mp4";
            Uri uri = Uri.parse( videoUrl1 );
            videoView = (VideoView)this.findViewById(R.id.videoView );
            videoView.setMediaController(new MediaController(this));
            videoView.setVideoURI(uri);
            videoView.start();
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
            super.onRequestPermissionsResult(requestCode,permissions,grantResults);
            if(requestCode==REQUESTCODE){
                if (permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults[0]== PackageManager.PERMISSION_GRANTED){
                    Toast.makeText(this,"ok", Toast.LENGTH_LONG).show();
    
                }else {
                    Toast.makeText(this,"无权限",Toast.LENGTH_LONG).show();
                }
            }
        }
    }
    View Code

    layout.xml

    <?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">
    
        <VideoView
            android:id="@+id/videoView"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
             />
    </LinearLayout>
    View Code

    androidmanifest.xml中要添加权限

        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.INTERNET" />
    View Code

    注意:使用模拟器播放时,要确保路径下有那个视频。从电脑传视频到模拟器的方法在上一篇中有。不过,每次传完当时可以用,重启电脑或重启模拟器时,那个视频文件会丢失,所以下次想用时得重新上传。我是用的ADV tools里面创建的模拟器,不知道其他模拟器会不会同样如此。另外提醒一点,关于视频取名字的问题,好像是有规则的,应该是小写字母,数字和下划线,不知道记得准不准,尽量用小写字母吧。

    另外说一点,这个是放在sd卡中,如果将APP删除了,这个里面的文件是不会被删除的。如果想要卸载APP的同时将它生成的文件全部删除掉的话,可以将文件放在android里面data文件夹,找到自己的域名代表的文件夹,其中又会有files的文件夹,卸载APP其实就是删除的这个域名的文件夹。它的路径获取可以用getExternalFileDir(null).getPath()获取。所以,路径也可以String videoUrl1 = this.getExternalFileDir(null).getPath() + "此处填路径下的文件夹名" + “文件名”;

    创建文件夹

        public void createResourceFolder(Context context){
            String directory_Path = context.getExternalFilesDir(null).getPath()+RESOURCE_FOLDER;
            File directory = new File(directory_Path);
            if(!directory.exists()){
                Log.i(TAG, "Create resource folder");
                directory.mkdir();
            }
        }
    

    第二种,Android的资源文件raw中。

    获取路径的方法是"android.resource://" + getPackageName() + "/raw/" + R.raw.名字,值得注意的是,不要放入过大的视频,R资源文件对大小是有限制的。如果文件过大,R会飘红,放一个10s的视频都飘红了,这时候增加或修改android studio的文件就好了。

    help-->Edit Custom Properties,文件打开后,加入一行idea.max.intellisense.filesize=10000就行了。

     1     public void play_mp4(){
     2         String video_path = "android.resource://" + getPackageName() + "/raw/" + R.raw.videotest;
     3         Uri uri = Uri.parse(video_path);
     4         videoView.setMediaController(new MediaController(this));
     5         videoView.setVideoURI(uri);
     6         videoView.start();
     7 
     8         videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
     9             @Override
    10             public void onCompletion(MediaPlayer mp) {
    11                 videoView.setVisibility(View.GONE);
    12                 Toast.makeText(MainActivity.this,"播放完毕",Toast.LENGTH_LONG).show();
    13             }
    14         });
    15     }
    View Code

    解决几个小问题:

    1. 视频无法充满屏幕?

    由于视频源不一样,可能有人会遇到视频并没有全部充满屏幕的情况。这时候我们需要创建一个CustomVideoView类重写VideoView的onMeasure方法。

    CustomVideoView.java

    package com.example.aimee.oner;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.widget.VideoView;
    
    public class CustomVideoView extends VideoView {
        public CustomVideoView(Context context) {
            super(context);
        }
    
        public CustomVideoView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public CustomVideoView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //我们重新计算高度
            int width = getDefaultSize(0, widthMeasureSpec);
            int height = getDefaultSize(0, heightMeasureSpec);
            setMeasuredDimension(width, height);
        }
    }
    View Code

    然后修改layout.xml中将VideoView换成com.example.aimee.oner.CustomVideoView,前面那一串是域名,自己的是什么就写什么。

    2. 上面总是显示oner那一栏怎么办?

    在styles.xml文件中添加一行,设置windowNoTitle为true

        <style name="AppTheme" parent="Base.Theme.AppCompat.Light.DarkActionBar">
            <!-- Customize your theme here. -->
            <item name="colorPrimary">@color/colorPrimary</item>
            <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
            <item name="colorAccent">@color/colorAccent</item>
            <item name="windowNoTitle">true</item>
        </style>
    View Code

    3. 若视频放完,还需要进行别的操作怎么办?

    videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){

    @Override

    public void onCompletion(MediaPlayer mp(){

    当视频放完所需的操作

    })

    });

    4. 关于Toast第一个参数的引用问题?

    关于Toast里面的第一个参数context,如果是在MainActivity中,用的是MainActivity.this,还有种情况可以用this就行了,这些都行不通的话,可是试试先在class里面声明private Context context;然后在onstart()里面写context=this,接下来在函数中用Toast时第一个参数就是context就OK了。上述代码中之所以加了一句videoView.setVisibility(View.GONE)就是将videoView给隐藏,就是让其提示播放完毕更明显。

    5. 怎么去掉最上面显示的wifi,移动,电池那一栏呢?

    在MainActivity.java的onCreate方法开头写

            this.requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN);
    View Code
  • 相关阅读:
    线性表ADT实现
    基数排序
    二叉树之已知前序和中序遍历求后序遍历(POJ2255 &&HDU )
    acm头文件
    快排
    快读
    二分
    数据结构大师
    AC_2. 01背包问题
    AC_94. 递归实现排列型枚举
  • 原文地址:https://www.cnblogs.com/smart-zihan/p/9914848.html
Copyright © 2011-2022 走看看