一、VideoView及其相关组件总结

Android中,播放视频有2种方式,第一种方式是使用MediaPlayer结合SurfaceView来播放,通过MediaPlayer来控制视频的播放、暂停、进度等,而通过SurfaceView来显示视频内容;第二种方式是使用VideoView来播放,这个类其实也是继承了SurfaceView类,并且实现了MediaController.MediaPlayerController这个用于控制媒体播放的接口,另外在VideoView上还有一个用于对媒体播放进行控制的面板,包括快进、快退、播放、暂停按钮以及一个进度条。使用VideoView播放视频的好处是简单因为它已经帮我们实现了SurfaceView以及控制方法,开发过程中只需直接拿来使用就可以了,但它的缺点是不够灵活。而是用MediaPlayer结合SurfaceView来播放视频的话,好处是可以更灵活的对其进行自定义,缺点是难度较大。

1.1通过VideoView播放视频步骤:

1、在界面布局文件中定义VideoView组件,或在程序中创建VideoView组件

2、在Activity中获取布局文件中的组件并设置相应的监听;

3、调用VideoView的如下两个方法来加载指定的视频:

   (1)setVideoPath(String path):加载path文件代表的视频

   (2)setVideoURI(URI uri):加载uri所对应的视频

在使用setVideoURI(URI uri)方法之前要设置网络视频路径

4、调用VideoViewstart()pause()resume()stopPlayback()方法控制视频的播放(开始、暂停、继续、停止)VideoViewgetDuration()可以返回视频的长度,可以结合VideoViewresume()方法进行记忆播放和缓存播放。

1.2 VideoView常用方法

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

 

方法名称

说明

void start()

开始播放

void stopPlayback()

停止播放

void pause()

暂停

void resume()

重新播放

void seekTo(int msec)

从第几毫秒开始播放

int getCurrentPosition()

获取当前播放位置

int getDuration()

获取当前视频总长度

boolean isPlaying()

当前VideoView是否在播放视频

void setVideoPath(String path)

以文件路径的方式设置VideoView播放的视频源

void setVideoURI(URI uri)

Uri的方式设置视频源,可以是网络Uri或本地Uri

setMediaCotroller(MediaController controller)

设置MediaController控制器

 

setOnCompletionListener(MediaPlayer.onCompletionListener l)

监听播放完成的事件

setOnErrorListener(MediaPlayer.OnErrorListener l)

监听播放发生错误时候的事件

setOnPreparedListener(MediaPlayer.OnPreparedListener l)

监听视频装载完成的事件

 

1.3 Media Controller

Media Controller类为我们提供了一个悬浮的操作栏,包含了播放,暂停,快进,快退,上一个,下一个等功能键。还有拖动进度条至某一处也可以实现。在使用前VideoViewMeidaController需要相互指定控件。

 

Mdedia Controller类包含的内置方法有:

 

 

方法名称

说明

boolean isShowing()

当前悬浮控制栏是否显示。

void setMediaPlayer(MediaController.MediaPlayerControl player)

设置控制的组件

void hide()

隐藏MeidaController

void show()

显示MeidaController

void show(int timeout)

设置MidiaController显示的时间,以毫秒计算。如果设置为0则一直到调用hide()方法隐藏

void setPrevNextListeners(View.OnClickListener next,View.OnClickListener prev)

设置上一个视频下一个视频的切换事件

 

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

1.4 视频格式

1.4.1 Android支持的视频编码格式

1.4.2 VideoView支持的影片格式

 

在实际测试中过程中,发现了一些由VideoView发出的Toast警告,内容写着不支持影片格式,以致无法播放。VideoView仅能播放progressive streamable(渐进式流)的影片,一般的mp43gp若不采用progressive streamable模式转文件的影片,是无法被VideoView通过网络播放的,但假如存放在local端(如储存卡)则不在此限。

 

1.5 VideoView的监听处理

开发过程中使用的VideoView监听一共有3个:setOnCompletionListener(MediaPlayer.onCompletionListener l)setOnErrorListener(MediaPlayer.OnErrorListener l)setOnPreparedListener(MediaPlayer.OnPreparedListener l)

1.5.1 setOnCompletionListener(MediaPlayer.onCompletionListener l)

setOnCompletionListener(MediaPlayer.onCompletionListener l)用于监听视频播放完成后的事件

1.5.2 setOnErrorListener(MediaPlayer.OnErrorListener l)

 setOnErrorListener(MediaPlayer.OnErrorListener l)用于监听VideoView在使用过程中出现的各种错误。

错误常数:

  • MEDIA_ERROR_IO 
  • 文件不存在或错误,或网络不可访问错误 
  • : -1004 (0xfffffc14) 
  • MEDIA_ERROR_MALFORMED 
  • 流不符合有关标准或文件的编码规范 
  • : -1007 (0xfffffc11) 
  • MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK 
  • 视频流及其容器不适用于连续播放视频的指标(例如:MOOV原子)不在文件的开始
  • : 200 (0x000000c8) 
  • MEDIA_ERROR_SERVER_DIED 
  • 媒体服务器挂掉了。此时,程序必须释放MediaPlayer 对象,并重新new 一个新的。 
  • : 100 (0x00000064) 
  • MEDIA_ERROR_TIMED_OUT 
  • 一些操作使用了过长的时间,也就是超时了,通常是超过了3-5 
  • : -110 (0xffffff92) 
  • MEDIA_ERROR_UNKNOWN 
  • 未知错误 
  • : 1 (0x00000001) 
  • MEDIA_ERROR_UNSUPPORTED 
  • 比特流符合相关编码标准或文件的规格,但媒体框架不支持此功能 
  • : -1010 (0xfffffc0e) 
  • what int: 标记的错误类型
  • MEDIA_ERROR_UNKNOWN 
  • MEDIA_ERROR_SERVER_DIED 
  • extra int: 标记的错误类型
  • MEDIA_ERROR_IO 
  • MEDIA_ERROR_MALFORMED 
  • MEDIA_ERROR_UNSUPPORTED 
  • MEDIA_ERROR_TIMED_OUT 
  • MEDIA_ERROR_SYSTEM (-2147483648) - low-level system error.

1.5.3 setOnPreparedListener(MediaPlayer.OnPreparedListener l)

setOnPreparedListener(MediaPlayer.OnPreparedListener l)用于监听视频装在完成后的事件

二、视频旋转

在网上查询了众多的关于屏幕旋转的方法。总结起来可以分为4种。在介绍之前要先了解默认情况下Android屏幕旋转机制(当然是在手机本身屏幕旋转功能开启的时候才能实现,自己在开发过程中一直发现开发视频不能随着手机一起旋转,弄了几个小时才发现是自己Android本身自带的旋转按钮没有开启):

默认情况下,当用户的重力感应器打开后,屏幕旋转方向会导致当前activity发生onDestory->onCreate,这样会重新构造当前activity和界面布局,如果是在Camera界面,则表现为卡顿或者黑屏一段时间。如果是在横竖屏UI设计方面,那么想很好的支持屏幕旋转,则建议在res中建立layout-landlayport两个文件夹,把横屏和竖屏的文件分别放入对应的layout文件夹中。

2.1 AndroidMainfest.xml设置

如果单单想设置横屏或者竖屏,那么只需添加横竖屏代码:

优点:即使屏幕旋转,Actiity也不会重新onCreate

缺点:屏幕只有一个方向

2.2 代码动态设置

如果需要动态改变横竖屏设置,只要在代码中调用setRequestedOrientation()函数:

优点:可以随意动态设置,满足人们为改变横竖屏的要求,同时满足横竖屏UI不同的设计需求

缺点:如果改变设置,那么Activity会被销毁,重新构建,即重新onCreate;

2.3 重写onCongigurationChanged

使用此方法可以避免旋转屏幕时Activity被不断的onCreate情况(这种情况下往往造成屏幕切换时的卡顿)。

首先,在AndroidMainfest.xml中添加configChanges

注意:keyboardHidden表示键盘辅助功能隐藏,如果你的开发API等级等于或高于13,还需要设置screenSize,因为screenSize会在屏幕旋转时改变

然后,在Activity中重写onConfigurationChanged方法,这个方法将会在屏幕旋转变化时,进行监听处理:

优点:可以随时监听屏幕旋转变化,并对应做出相应操作

缺点:它只能一次旋转90°,如果一下子旋转180°,onConfigurationChanged函数不会被调用。

2.4 结合OrientationEventListener,自定义旋转监听设置

这种方法由于自定义回掉接口暂时不明白,在这里暂不总结。

可以参考网站:http://www.jb51.net/article/64735.htm

三、误按返回操作

为了防止用户误按返回键而退出播放,可以在程序中重写onKeyDown方法。在这个方法中来处理用户点击返回键的动作:例如只有用户在短时间内点击两次返回键才真正退出播放。

四、设置手机全屏

4.1 最常用的设置全屏方法

 

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置无标题
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 设置全屏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);
}

 

使用上述方法注意:requestWindowFeature()方法一定要在setContentView()前面,否则会报错;

4.2 AndroidManifest中配置

 

利用Android提供的内置的Theme就可以了。

五、设置屏幕显示方向

 

当不定义横竖屏的情况下,这个app会随着手机的转向设置变化而变化,而我们对于横竖屏切换肯定要做相应的事情,可以如下方法去做:

 

if (getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
            // 处理横屏下要做的事
        
        } else {
            // 处理竖屏下要做的事情
            
        }

 

在这个视频软件中我要做到一个点击按钮让手机旋转的功能,就是用到了上面的代码:

 

六、取消全屏的方法

getWindow().clearFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN);

 

七、Android系统自带样式

android:theme="@android:style/Theme.Dialog" 将一个Activity显示为能话框模式 
android:theme="@android:style/Theme.NoTitleBar" 不显示应用程序标题栏 
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" 不显示应用程序标题栏,并全屏 
android:theme="Theme.Light" 背景为白色 
android:theme="Theme.Light.NoTitleBar" 白色背景并无标题栏 
android:theme="Theme.Light.NoTitleBar.Fullscreen" 白色背景,无标题栏,全屏 
android:theme="Theme.Black" 背景黑色 
android:theme="Theme.Black.NoTitleBar" 黑色背景并无标题栏 
android:theme="Theme.Black.NoTitleBar.Fullscreen" 黑色背景,无标题栏,全屏 
android:theme="Theme.Wallpaper" 用系统桌面为应用程序背景 
android:theme="Theme.Wallpaper.NoTitleBar" 用系统桌面为应用程序背景,且无标题栏 
android:theme="Theme.Wallpaper.NoTitleBar.Fullscreen" 用系统桌面为应用程序背景,无标题栏,全屏 
android:theme="Translucent"  透明背景
android:theme="Theme.Translucent.NoTitleBar"  透明背景并无标题
android:theme="Theme.Translucent.NoTitleBar.Fullscreen"  透明背景并无标题,全屏
android:theme="Theme.Panel"   面板风格显示
android:theme="Theme.Light.Panel" 平板风格显示

八、小结:

由于太久的时间没有接触Android开发,很多Android开发的东西都忘记了,代码中具体的方法在这里不做一一总结,而在另外一篇文档中总结说明。

 

 

 

 

posted on 2017-06-02 11:51  龙从一  阅读(4767)  评论(3编辑  收藏  举报