• 安卓视频播放器(VideoView)


    VideoView是安卓自带的视频播放器类,该类集成有显示和控制两大部分,在布局文件中添加VideoView然后在java文件中简单的调用控制命令,即可实现本地或者网络视频的播放。本章实现视频的居中播放、网络视频播放、本地视频播放、视频卡顿监听、网络连接错误监听、视频外自定义视频控件、视频内自定义视频控件等。

    支持的格式:flv、3gp、mp4

     

    类的一些重要方法

    void start();                 //开始播放

    void pause();              //暂停

    void resume();           //重新播放,使用时需要在本句后加上开始播放

    void seekTo(int msec);       //从第几毫秒开始播放

    void stopPlayback();          //停止播放并释放资源

    int getCurrentPosition();    //获取当前播放的位置。

    int getDuration();               //获取当前播放视频的总长度。

    void setVideoPath(String path);    //以文件路径的方式设置VideoView播放的视频源。

    void setVideoURI(Uri uri);            //以Uri的方式设置VideoView播放的视频源,可以是网络Uri或本地Uri

    void isPlaying();                           //当前VideoView是否在播放视频

    setMediaController(MediaController controller);                               //设置MediaController控制器

    setOnCompletionListener(MediaPlayer.onCompletionListener l);     //监听播放完成的事件

    setOnErrorListener(MediaPlayer.OnErrorListener l);                        //监听播放发生错误时候的事件

    setOnPreparedListener(MediaPlayer.OnPreparedListener l);          //监听视频装载完成的事件

    setOnInfoListener(new MediaPlayer.OnInfoListener(){});                 //视频卡顿监听

    实现简单的视频播放

                                                 

    布局文件:

    实现视频播放重要在于VideoView标签,如果让该标签的父级标签为FramLayout,设置相应属性就可以实现视频居中播放和默认的播放控件 MediaController 在视频内显示效果,还可以在VidoView标签上层加入TextView标签,实现视频播放的一些状态显示,如播放卡顿、切换播放、播放失败等的提示信息显示。另外可加入ImageView标签,即可显示图片或gif图,更具人性化。

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:tools="http://schemas.android.com/tools"
     4     android:layout_width="match_parent"
     5     android:layout_height="match_parent"
     6     android:paddingBottom="0dp"
     7     android:paddingLeft="0dp"
     8     android:paddingRight="0dp"
     9     android:orientation="vertical"
    10     android:paddingTop="0dp"
    11     tools:context="com.example.videodong.MainActivity">
    12 
    13     <TextView
    14         android:layout_width="wrap_content"
    15         android:layout_height="wrap_content"
    16         android:text="视频播放器:
    "
    17         android:textSize="15dp"
    18         android:id="@+id/textView" />
    19     <FrameLayout
    20         android:layout_width="match_parent"
    21         android:background="@color/colorBlack"
    22         android:layout_height="300dp">
    23        <VideoView
    24         android:layout_width="match_parent"
    25         android:layout_gravity="center"
    26         android:layout_height="300dp"
    27         android:id="@+id/videoView"
    28         />
    29 
    30         <TextView
    31             android:layout_width="wrap_content"
    32             android:layout_height="wrap_content"
    33             android:textSize="15dp"
    34             android:text="点击播放"
    35             android:textColor="@color/colorWhite"
    36             android:id="@+id/vv_text"
    37             android:layout_gravity="center" />
    38     </FrameLayout>
    39 
    40     <ProgressBar
    41         android:id="@+id/vv_bar"
    42         style="?android:attr/progressBarStyleHorizontal"
    43         android:layout_width="match_parent"
    44         android:layout_height="wrap_content"/>
    45 
    46         <TextView
    47             android:layout_width="wrap_content"
    48             android:text="时间轴为:0.00/000"
    49             android:id="@+id/vv_starttime"
    50             android:layout_height="wrap_content" />
    51 
    52 
    53      <LinearLayout
    54          android:layout_width="match_parent"
    55          android:orientation="horizontal"
    56          android:layout_gravity="center"
    57          android:layout_height="wrap_content">
    58          <TextView
    59              android:layout_width="wrap_content"
    60              android:layout_weight="1"
    61              android:layout_height="wrap_content" />
    62          <Button
    63              android:layout_width="wrap_content"
    64              android:text="开始"
    65              android:id="@+id/vv_start"
    66              android:layout_height="wrap_content" />
    67          <Button
    68              android:layout_width="wrap_content"
    69              android:text="暂停"
    70              android:id="@+id/vv_pause"
    71              android:layout_height="wrap_content" />
    72          <Button
    73              android:layout_width="wrap_content"
    74              android:text="重播"
    75              android:id="@+id/vv_restart"
    76              android:layout_height="wrap_content" />
    77          <Button
    78              android:layout_width="wrap_content"
    79              android:text="下一个"
    80              android:id="@+id/vv_next"
    81              android:layout_height="wrap_content" />
    82          
    83      </LinearLayout>
    84     <TextView
    85         android:layout_width="wrap_content"
    86         android:id="@+id/vv_state"
    87         android:layout_height="wrap_content" />
    88 </LinearLayout>
    View Code

    需要添加的权限:

    因为视频来源可以是网络或者本地,所以需要动态申请网络访问权限和本地文件读写权限,文件读写权限一般还需要手动获取

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

    寻找到VideoView控件:

    vv=(VideoView)findViewById(R.id.videoView);

    视频预装完成监听:

    1 //视频准备完成时进入
    2 vv.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    3             @Override
    4             public void onPrepared(MediaPlayer mp) {
    5                 //设置屏幕提示信息为空
    6                 vv_text.setText("");
    7             }
    8 });

    视频播放完成监听:

     1 vv.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
     2             @Override
     3             public void onCompletion(MediaPlayer mp) {
     4                 String strres="播放完成";
     5                 //判断视频的总长度与当前长度是否在误差区间内
     6                 if(Math.abs(vv.getDuration()-vv.getCurrentPosition())>1000){
     7 
     8                     strres="播放错误,可能无网络连接";
     9 
    10                 }
    11                 //设置屏幕提示信息
    12                 vv_text.setText(strres);
    13 
    14             }
    15 });

    视频播放错误监听:

     1 vv.setOnErrorListener(new MediaPlayer.OnErrorListener() {
     2             @Override
     3             public boolean onError(MediaPlayer mp, int what, int extra) 
     4            {
     5                //设置屏幕显示信息
     6                 vv_text.setText("视频未知错误");
     7 
     8                 return false;
     9             }
    10  });

    视频卡顿和停止卡顿监听:

     1 vv.setOnInfoListener(new MediaPlayer.OnInfoListener(){
     2             @Override
     3             public boolean onInfo(MediaPlayer mp, int what, int extra){
     4 
     5                 switch(what){
     6                     case MediaPlayer.MEDIA_INFO_BUFFERING_START:
     7                         //设置屏幕显示信息,开始卡顿
     8                         vv_text.setText("视频卡顿,加载中.....");
     9                         break ;
    10                     case MediaPlayer.MEDIA_INFO_BUFFERING_END:
    11                         //设置屏幕显示信息,卡顿结束
    12                         vv_text.setText("");
    13                         break ;
    14                 }
    15              return true;
    16             }
    17 }) ;

    设置播放资源:

    1 //本地文件
    2 vv.setVideoPath(Environment.getExternalStorageDirectory()+"/dongxiaodong/kk1.mp4");
    3 
    4 //URL形式,支持本地URL和网络URL
    5 //vv.setVideoURI(Uri.parse("https://www.bilibili.com/video/xxxxx"));
    6        
    7 //设置自带的播放控件
    8 //vv.setMediaController(new MediaController(this));

    播放开始按钮监听:

     1 //开始播放视频按钮
     2 vv_start.setOnClickListener(new View.OnClickListener() {
     3             @Override
     4             public void onClick(View v) {
     5                 
     6                 //设置屏幕显示信息
     7                 vv_text.setText("");
     8 
     9                 //开始播放
    10                 vv.start();
    11 
    12             }
    13 });

    播放暂停按钮监听:

     1 //暂停播放视频按钮
     2 vv_pause.setOnClickListener(new View.OnClickListener() {
     3             @Override
     4             public void onClick(View v) {
     5 
     6                 //设置屏幕显示信息
     7                 vv_text.setText("视频暂停中");
     8 
     9                 //暂停视频播放
    10                 vv.pause();
    11 
    12             }
    13 });

    重新播放按钮监听:

     1 //重新播放视频
     2 vv_restart.setOnClickListener(new View.OnClickListener() {
     3             @Override
     4             public void onClick(View v) {
     5                 //设置屏幕显示信息
     6                 vv_text.setText("正在重新播放中,请稍等");
     7 
     8                 //设置时间轴显示为0
     9                 vv_starttime.setText("时间轴为:0.00/0.00");
    10 
    11                 //设置进度条显示为0
    12                 vv_bar.setProgress(0);
    13                 
    14                 //重新播放视频
    15                 vv.resume();
    16                 vv.start();
    17 
    18             }
    19 });

    播放下一个视频监听:

     1 vv_next.setOnClickListener(new View.OnClickListener() {
     2             @Override
     3             public void onClick(View v) {
     4                 //设置屏幕显示信息
     5                 vv_text.setText("正在切换,请稍等");
     6 
     7                 //设置时间轴为0
     8                 vv_starttime.setText("时间轴为:0.00/0.00");
     9 
    10                 //设置进度条为0
    11                 vv_bar.setProgress(0);
    12                 
    13                 //停止播放
    14                 vv.pause();//暂停
    15                 vv.stopPlayback();//停止播放并释放资源
    16 
    17                 //得到下一个视频的资源
    18                 if(nextbool){
    19                     nextbool=false;
    20                     //网络资源,该url已经过期
    21                     vv.setVideoURI(Uri.parse("http://193.112.87.88/video/xx.flv"));
    22                 } else {
    23                     nextbool=true;
    24                     //本地资源
    25                     vv.setVideoPath(Environment.getExternalStorageDirectory()+"/dongxiaodong/kk1.mp4");
    26                 }
    27 
    28                 //开始播放下一个
    29                 vv.start();
    30 
    31             }
    32 });

    时间轴时间显示和进度条更新实现:

    时间轴时间显示计算将在后文给出解释,另外 %02d 可以实现自动补零效果,runOnUiThread可以在普通线程中进入UI线程,可以实现UI的一系列操作。

     1 new Thread(new Runnable() {
     2             @Override
     3             public void run() {
     4                 while (true){
     5                     //延时1秒
     6                     try {
     7                         Thread.sleep(1);
     8                     } catch (InterruptedException e) {
     9                         e.printStackTrace();
    10                     }
    11 
    12                     //进入主线程更新UI
    13                     runOnUiThread(new Runnable() {
    14                         @Override
    15                         public void run() {
    16                             if(vv.isPlaying()) {
    17                                  
    18                                 //获取到视频播放进度
    19                                 int maxx=vv.getDuration();
    20                                 int progress=vv.getCurrentPosition();
    21 
    22                                 //设置进度条信息
    23                                 vv_bar.setMax(maxx);
    24                                 vv_bar.setProgress(progress);
    25 
    26                                 //得到时间轴字符串
    27                                 String strtime=String.format("时间轴为:%02d:%02d/%02d:%02d", (progress % 3600000) / 60000,(progress % 60000 ) / 1000, (maxx % 3600000) / 60000,(maxx % 60000 ) / 1000);
    28                                 //显示时间轴信息
    29                                 vv_starttime.setText(strtime);
    30 
    31                             }
    32                         }
    33                     });
    34                     }
    35 
    36                 }
    37  }).start();
    View Code

    视频播放进阶

    利用FrameLayout的层叠效果,实现视频控件面板在视频层之上显示,利用视频控件的点击事件,实现视频点击监听然后改变视频控制面板的隐藏和显示。其他的视频播放控制代码基本以上相似

                                                                                 

     布局文件改变:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:tools="http://schemas.android.com/tools"
     4     android:layout_width="match_parent"
     5     android:layout_height="match_parent"
     6     android:paddingBottom="0dp"
     7     android:paddingLeft="0dp"
     8     android:paddingRight="0dp"
     9     android:orientation="vertical"
    10     android:paddingTop="0dp"
    11     tools:context="com.example.videodong.MainActivity">
    12 
    13     <TextView
    14         android:layout_width="wrap_content"
    15         android:layout_height="wrap_content"
    16         android:text="视频播放器:
    "
    17         android:textSize="15dp"
    18         android:id="@+id/textView" />
    19     <FrameLayout
    20         android:layout_width="match_parent"
    21         android:background="@color/colorBlack"
    22         android:layout_height="230dp">
    23        <VideoView
    24         android:layout_width="match_parent"
    25         android:layout_gravity="center"
    26         android:layout_height="230dp"
    27         android:id="@+id/videoView"
    28         />
    29         <FrameLayout
    30             android:layout_width="match_parent"
    31             android:layout_gravity="bottom"
    32             android:id="@+id/vv_framel"
    33             android:layout_height="wrap_content">
    34             <ImageView
    35                 android:layout_width="match_parent"
    36                 android:background="@color/colorWhite"
    37                 android:alpha="0.5"
    38                 android:layout_height="match_parent" />
    39         <LinearLayout
    40             android:layout_width="match_parent"
    41             android:orientation="vertical"
    42 
    43             android:layout_height="wrap_content">
    44             <ProgressBar
    45                 android:id="@+id/vv_bar"
    46                 style="?android:attr/progressBarStyleHorizontal"
    47                 android:layout_width="match_parent"
    48                 android:layout_height="wrap_content"/>
    49             <LinearLayout
    50                 android:layout_width="match_parent"
    51                 android:orientation="horizontal"
    52                 android:layout_gravity="center"
    53                 android:layout_height="wrap_content">
    54                 <TextView
    55                     android:layout_width="wrap_content"
    56                     android:text="时间轴为:0.00/000"
    57                     android:id="@+id/vv_starttime"
    58                     android:layout_weight="1"
    59                     android:layout_height="wrap_content" />
    60                 <Button
    61                     android:layout_width="wrap_content"
    62                     android:text="开始"
    63                     style="?android:attr/buttonStyleSmall"
    64                     android:id="@+id/vv_start"
    65                     android:layout_height="wrap_content" />
    66                 <Button
    67                     android:layout_width="wrap_content"
    68                     android:text="暂停"
    69                     android:id="@+id/vv_pause"
    70                     style="?android:attr/buttonStyleSmall"
    71                     android:layout_height="wrap_content" />
    72                 <Button
    73                     android:layout_width="wrap_content"
    74                     android:text="重播"
    75                     style="?android:attr/buttonStyleSmall"
    76                     android:id="@+id/vv_restart"
    77                     android:layout_height="wrap_content" />
    78                 <Button
    79                     android:layout_width="wrap_content"
    80                     android:text="下一个"
    81                     style="?android:attr/buttonStyleSmall"
    82                     android:id="@+id/vv_next"
    83                     android:layout_height="wrap_content" />
    84 
    85             </LinearLayout>
    86         </LinearLayout>
    87         </FrameLayout>
    88 
    89         <TextView
    90             android:layout_width="wrap_content"
    91             android:layout_height="wrap_content"
    92             android:textSize="15dp"
    93             android:text="点击播放"
    94             android:textColor="@color/colorWhite"
    95             android:id="@+id/vv_text"
    96             android:layout_gravity="center" />
    97     </FrameLayout>
    98 </LinearLayout>
    View Code

    寻找播放控件标签:

    vv_framel=(FrameLayout)findViewById(R.id.vv_framel);

    设置视频播放控件点击事件监听: 

     1 vv.setOnClickListener(new View.OnClickListener() {
     2     @Override
     3     public void onClick(View v) {
     4         //判断是否是显示
     5         if(vv_framel.getVisibility()==View.VISIBLE)
     6 
     7             //隐藏视频播放控件
     8             vv_framel.setVisibility(View.INVISIBLE);
     9 
    10         else
    11 
    12             //显示视频播放控件
    13             vv_framel.setVisibility(View.VISIBLE);
    14 
    15     }
    16 });

    内容补充:

    视频播放时间轴时间计算:

    如果只知道毫秒数,如何转换为对应的时、分、秒,因为1秒为1000毫秒,1分钟为60秒,1小时为60分,所以如果求秒则需要去掉分钟的值,如果求分钟则需要去掉小时的值。

    得到秒:【(t % (60*1000) ) / 1000】

    得到分:【(t % (60*60*1000)) / (60*1000)】

    得到时:【(t / (60*60*1000))】

    源码资源下载:点我下载


     参考:

    https://www.jianshu.com/p/0c3ef72c20d1?from=timeline&isappinstalled=0

    https://www.cnblogs.com/tangs/articles/5463347.html

    https://blog.csdn.net/qq_30983519/article/details/54407122

    https://blog.csdn.net/qq_29272491/article/details/80475788

  • 相关阅读:
    rpm包的管理
    多态应用实例--制作饮品
    纯虚函数和抽象类
    rpm包的管理
    动态监控进程
    封装继承和多态
    计网面试题
    模拟浏览器加载页面时的版本下载
    xpath中extract()使用
    MVC+EF CODE FIRST的使用
  • 原文地址:https://www.cnblogs.com/dongxiaodong/p/10289347.html
Copyright © 2020-2023  润新知