zoukankan      html  css  js  c++  java
  • Android 视频播放器 (一):使用VideoView播放视频

    一、简介

    作为Android开发,我们不可避免的会接触到视频播放,VideoView做为最简单的播放器,我们是不应该不会的。

    下面简单介绍一下VideoView:

    • VideoView是使用MediaPlayer来对视频文件进行控制的。
    • VideoView只支持mp4、avi、3gp格式的视频,支持格式相对单一,VideoView支持的格式可以参考MediaPlayer。
    • VideoView可以播放网络视频,支持的网络视频的协议为:Http协议和RTSP协议两种。

    二、VideoView常用方法

    Android VideoView类为我们提供了十分方便的视频播放API,其主要方法如下:

    • setVideoPath:设置要播放的视频文件的位置
    • start:开始或继续播放视频
    • pause:暂停播放视频
    • resume:将视频从头开始播放
    • seekTo:从指定的位置开始播放视频
    • isPlaying:判断当前是否正在播放视频
    • getCurrentPosition:获取当前播放的位置
    • getDuration:获取载入的视频文件的时长
    • setVideoPath(String path):以文件路径的方式设置VideoView播放的视频源
    • setVideoURI(Uri uri):以Uri的方式设置视频源,可以是网络Uri或本地Uri
    • setMediaController(MediaController controller):设置MediaController控制器
    • setOnCompletionListener(MediaPlayer.onCompletionListener l):监听播放完成的事件
    • setOnErrorListener(MediaPlayer.OnErrorListener l):监听播放发生错误时候的事件
    • setOnPreparedListener(MediaPlayer.OnPreparedListener l):监听视频装载完成的事件

    除了简单的操作和丰富的API以外,我们在装载视频时,无需进行编码,播放完成后也无需手动回收资源。

    除了播放视频,Media Controller类则为我们提供了一个悬浮的操作栏,包含了播放,暂停,快进,快退,上一个,下一个等功能键。甚至连拖动进度条至某处播放都已经实现。在使用前VideoView和MediController需要相互指定控件。其内置方法有如下:

    • boolean isShowing:当前悬浮控制栏是否显示
    • setMediaPlayer(MediaController.MediaPlayerControl player):设置控制的组件
    • setPrevNextListeners(View.OnClickListener next,View.OnClickListener prev):设置上一个视频、下一个视频的切换事件。

    默认情况下,Media Controller悬浮显示3s后隐藏,触摸响应的VideoView呼出。默认上一个,下一个按钮隐藏。

    三、使用VideoView实现视频播放

    下面我们将展示如何使用VideoView播放香港卫视的视频流:

    1. 声明权限

    需要在AndroidManifest.xml添加两条权限。

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

    两条权限分别为:网络访问权限、访问文件系统的权限。

    2. 编写VideoView布局

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout 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=".MainActivity">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <VideoView
                android:id="@+id/video_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </android.support.constraint.ConstraintLayout>

    3. 编写播放视频代码

    VideoView videoView = findViewById(R.id.video_view);
    videoView.setVideoPath("http://live.hkstv.hk.lxdns.com/live/hks/playlist.m3u8");  // 香港卫视地址
    videoView.start();
    MediaController mediaController = new MediaController(this);
    videoView.setMediaController(mediaController);
    mediaController.setMediaPlayer(videoView);

    4. 效果图

    完成代码编写的工作后启动App应该就能够如上图的香港卫视的视频内容啦。是不是感觉很简单啊,那是因为VideoView封装了MediaPlayer和SurfaceView,所有的生命周期都包装好了,所以使用的时候当然就简单啦。下面我们就解析一下VideoView了解其背后的事情。

    四、VideoView 播放状态说明

    下面的代码是VideoView声明的播放器声明的状态:

    // all possible internal states
    private static final int STATE_ERROR = -1; 
    private static final int STATE_IDLE = 0;    
    private static final int STATE_PREPARING = 1;  
    private static final int STATE_PREPARED = 2; 
    private static final int STATE_PLAYING = 3;
    private static final int STATE_PAUSED = 4;
    private static final int STATE_PLAYBACK_COMPLETED = 5;

    为什么会声明这些状态,这就不得不提到MediaPlayer的生命周期了,看下图,应该就稍微理解了吧:

    在这里我们先不具体针对这个图讲MediaPlayer的生命周期的内容。只是为了证明VideoView的状态的生命是有依据的。

    private int mCurrentState = STATE_IDLE;
    private int mTargetState = STATE_IDLE;

    上面的代码声明了两个状态变量,分别是当前的状态和目标状态。通过这两个变量结合上面提到的常量,我们可以很清楚的知道VideoView类就是围绕这这两个状态来进行相应的操作的。而我们处理一些回调也是基于这些状态之间的变化设计的,如:

    • OnCompletionListener -- STATE_PLAYBACK_COMPLETED
    • OnPreparedListener -- STATE_PREPARED
    • OnErrorListener -- STATE_ERROR

     五、使用VideoView 可能遇到的问题及解决方案

    1. 视频播放时会有短暂的黑屏时间: 

    产生原因:

    视频文件加载到内存中是需要时间,这个时间可能导入VideoView全黑。

    解决方法:

    (1):给VideoView添加MediaPlayer.OnPreparedListener 监听事件,在其onPrepared(MediaPlayer mp) 方法回调中播放视频这个时候视频已经完成了加载。
    (2):在VideoView执行start() 方法时视频的预览图不是立即消失而是延迟几百毫秒之后消失,这是视频已经加载完成,当然体验上有些不好。

    2. 跳转到其他界面回来后视频播放区域黑屏:

    产生原因:

    VideoView被回收掉,而自己没做VideoView的状态保存处理

    解决方法:

    在VideoView所在的Activity或者Fragment的生命周期中处理VideoView视频播放和暂停。(查看VideoView的生命周期相关的方法)

     

  • 相关阅读:
    如何将网格式报表打印成其它样式
    拥有与实力不相称的脾气是种灾难——北漂18年(23)
    8.8.1 Optimizing Queries with EXPLAIN
    mysql 没有rowid 怎么实现根据rowid回表呢?
    secondary index
    8.5.5 Bulk Data Loading for InnoDB Tables 批量数据加载
    mysql 中key 指的是索引
    8.5.4 Optimizing InnoDB Redo Logging 优化InnoDB Redo 日志
    8.5.3 Optimizing InnoDB Read-Only Transactions 优化InnoDB 只读事务
    8.5.1 Optimizing Storage Layout for InnoDB Tables InnoDB表的存储布局优化
  • 原文地址:https://www.cnblogs.com/renhui/p/9267778.html
Copyright © 2011-2022 走看看