android 播放视频常见问题
2018-03-22 00:19
483 查看
在android 开发中常见到视频播放的问题,在常规的视频中 有直接用videoView + MediaController 或者 mediaController + serfercie holder常见的问题1 在播放中如何处理播放器的横屏切换 和 播放器上的文案显示的布局变化在activity 中 设置
这样在旋转中,activity 就不会重建重写系统方法
2
3
4
5
6
7
8
9
通过 判断 newConfig.orientation 来判断 当前是横屏还是竖屏, 这个是在看视频的过程中去判断是不是横屏还是竖屏,在我门一开始播放视频的时候,也可以去判断,具体的处理方法是
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在具体变化播放器上的布局的时候我们可以动态的去更换
2
3
4
5
6
7
8
9
10
11
12
13
这是竖屏处理
2
3
4
5
6
7
8
9
10
11
12
13
14
这是横屏处理我门知道 系统的videoView 控件 自带有播放,暂停 等进度条这是MediaContronller 当我们手点击的时候 进度条会显示,手离开界面的时候,会不显示,这是videoView 中的方法
2
3
4
5
6
7
再朝下看
2
3
4
5
6
7
最终调的是 mMediaController.hide(); 和 mMediaController.show(),所以我门在自己的播放器界面要是实现自己的布局和播放器进度条 重写hide() 和 show() 方法即可2 在视频播放的过程中经常会出现播放异常的情况,比如弹出无法播放视频的弹框,当然我门是不想让它弹的,于是我门的处理方式为:
2
3
4
5
6
让onError 直接返回为true 这样能阻止异常框的弹出 同时什么都不做,原理是
2
3
4
5
6
7
8
9
这里error_was_handled 为true 这样就不走进mOnCompletionListener.onCompletion(mMediaPlayer);
了。3 视频上线发现 在部分小米机型和魅族等机器上横屏 视频没有办法横屏。解决方案为在布局中
2
3
4
5
6
7
8
9
10
11
嵌套RelativeLayout;在代码中处理
2
3
4
5
6
7
8
4 在视频开发中,回发现window Leacked 问题,看了下
MediaController 的show 方法
2
3
4
5
6
7
8
9
10
11
在不停的向view 中加布局,在MediaContrller 中方法了 中hide
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
讲view remove 因此 我门在activity 的industry 的生命周期的回调中 执行 hide() 方法即可
2
3
4
5
6
7
8
9
10
其实screenOrientation还可以设置成很多值:android:screenOrientation=
[“unspecified” | “behind” |”landscape” | “portrait”|”reverseLandscape”|”reversePortrait” |”sensorLandscape” | “sensorPortrait” |”userLandscape” | “userPortrait” |”sensor” | “fullSensor” | “nosensor” |”user” | “fullUser” | “locked”]
1
2
其中sensorLandscape就是横屏根据重力切换,sensorPortrait竖屏根据重力切换。播放视频全屏切换:
1.Demo:@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE) {
getWindow().getDecorView().setSystemUiVisibility(View.INVISIBLE);
}else if (this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT) {
// this.requestWindowFeature(Window.f);// 去掉标题栏
// this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN);// 去掉信息栏
Log.i(“info”, “portrait”); // 竖屏}View类提供了setSystemUiVisibility和getSystemUiVisibility方法,这两个方法实现对状态栏的动态显示或隐藏的操作,以及获取状态栏当前可见性。setSystemUiVisibility(int visibility)方法可传入的实参为:View.SYSTEM_UI_FLAG_VISIBLE:显示状态栏,Activity不全屏显示(恢复到有状态的正常情况)。
View.INVISIBLE:隐藏状态栏,同时Activity会伸展全屏显示。
View.SYSTEM_UI_FLAG_FULLSCREEN:Activity全屏显示,且状态栏被隐藏覆盖掉。
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:Activity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住。
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
View.SYSTEM_UI_LAYOUT_FLAGS:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION:隐藏虚拟按键(导航栏)。有些手机会用虚拟按键来代替物理按键。
View.SYSTEM_UI_FLAG_LOW_PROFILE:状态栏显示处于低能显示状态(low profile模式),状态栏上一些图标显示会被隐藏。
2.
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attrs);
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
2.解压文件,将其中的vitamio导入到as中 ,打开AS,File -> New -> Import Moudle,选择刚才解压文件夹下的 vitamio 文件. 并且在app的gradle中添加该包的依赖
3.按照app目录下的build.gradle配置vitamio目录下的build.gradle(注意不是vitamio文件夹下app下的)(2)使用1.mainfest文件
return;1.布局中<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.gbf.livingdemo.VitamioActivity"
android:orientation="vertical">
<io.vov.vitamio.widget.VideoView
android:id="@+id/vitamio_videoview"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</LinearLayout>
2.activitypublic class VitamioActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener{
private VideoView mVideoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//检查vitamio框架是否可用
if (!io.vov.vitamio.LibsChecker.checkVitamioLibs(this))
return;
setContentView(R.layout.activity_vitamio);
//一定要初始化
Vitamio.initialize(this);
initView();
initData();
}
private void initData() {
mVideoView.setVideoURI(Uri.parse("http://qiubai-video.qiushibaike.com/91B2TEYP9D300XXH_3g.mp4"));
// mVideoView.setVideoURI(Uri.parse("http://alcdn.hls.xiaoka.tv/2017427/14b/7b3/Jzq08Sl8BbyELNTo/index.m3u8"));
mVideoView.setMediaController(new MediaController(this));
//设置监听
mVideoView.setOnPreparedListener(this);
mVideoView.setOnErrorListener(this);
mVideoView.setOnCompletionListener(this);
}
private void initView() {
mVideoView=findViewById(R.id.vitamio_videoview);
}
@Override
public void onPrepared(MediaPlayer mp) {
Toast.makeText(this,"准备好了", Toast.LENGTH_LONG).show();
mVideoView.start();
}
@Override
public void onCompletion(MediaPlayer mp) {
Toast.makeText(this,"播放完成", Toast.LENGTH_LONG).show();
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(this,"Error", Toast.LENGTH_LONG).show();
// 返回 true
return true;
}
}别忘记@Override
protected void onDestroy() {
mVideoView.stopPlayback();
super.onDestroy();
}
效果如下:竖屏:
正常情况下来,进度条应该是在视频的底部,而不是在手机屏幕的底部修改如下:(1)xml布局,在videoview外面添加一层布局如下:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.gbf.livingdemo.VitamioActivity"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/rela"
android:layout_width="match_parent"
android:layout_height="260dp">
<io.vov.vitamio.widget.VideoView
android:id="@+id/vitamio_videoview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
</LinearLayout>
(2)MediaController添加构造函数public MediaController(Context context, boolean isFromXml, View container) {
super(context);
initController(context);
mFromXml = isFromXml;
mRoot = makeControllerView();
if(container instanceof RelativeLayout)
{
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
p.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
mRoot.setLayoutParams(p);
((RelativeLayout)container).addView(mRoot);
}
} public MediaController(Context context) {
super(context);
if (!mFromXml && initController(context))
initFloatingWindow();
}(3)activity中实例化MediaController// mVideoView.setMediaController(new MediaController(this));
mVideoView.setMediaController(new MediaController(this,true,mRelatviLayout));效果如下:
竖屏显示正常~~
横屏幕:
解决办法:(1)清单文件中当前activity设置如下:android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"(2)判断屏幕是否是横屏或者竖屏@Override
public void onConfigurationChanged(Configuration newConfig) {
//屏幕切换时,设置全屏
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
Log.d("haha","切换横屏");
setFullScreen();
}
else
{
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
600);
mRelatviLayout.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
mVideoView.setLayoutParams(layoutParams1);
}
super.onConfigurationChanged(newConfig);
}
private void setFullScreen() {
Log.d("haha","调用设置全屏");
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
mRelatviLayout.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
mVideoView.setLayoutParams(layoutParams1);
}
效果:
像一个正常的播放器了~~
android:configChanges="orientation|screenSize"1
这样在旋转中,activity 就不会重建重写系统方法
public void onConfigurationChanged(Configuration newConfig) { // TODO Auto-generated method stub super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { initVideoLandLayout(); } else { initVideoPortLayout(); } }1
2
3
4
5
6
7
8
9
通过 判断 newConfig.orientation 来判断 当前是横屏还是竖屏, 这个是在看视频的过程中去判断是不是横屏还是竖屏,在我门一开始播放视频的时候,也可以去判断,具体的处理方法是
private void initVideoPlayerLayout() { DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); width = dm.widthPixels; heigh = dm.heightPixels; if (width / heigh > 0) { // 横屏 initVideoLandLayout(); fullscreen = true; } if (width / heigh == 0) { //竖屏 initVideoPortLayout(); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在具体变化播放器上的布局的时候我们可以动态的去更换
private void initVideoPortLayout() { RelativeLayout.LayoutParams videoLp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); videoLp.addRule(RelativeLayout.CENTER_IN_PARENT); videoView.setLayoutParams(videoLp); videoView.start(); RelativeLayout.LayoutParams hotelInfoLp = new RelativeLayout.LayoutParams(DeviceInfoUtil.getPixelFromDip(200), DeviceInfoUtil.getPixelFromDip(55)); hotelInfoLp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); hotelInfoLp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); hotelInfoLp.rightMargin = DeviceInfoUtil.getPixelFromDip(8); hotelInfoLp.bottomMargin = DeviceInfoUtil.getPixelFromDip(90); mHotelInfoLayout.setLayoutParams(hotelInfoLp); }1
2
3
4
5
6
7
8
9
10
11
12
13
这是竖屏处理
private void initVideoLandLayout() { RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); videoView.setLayoutParams(layoutParams); RelativeLayout.LayoutParams hotelInfoLp = new RelativeLayout.LayoutParams(DeviceInfoUtil.getPixelFromDip(200), DeviceInfoUtil.getPixelFromDip(55)); hotelInfoLp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); hotelInfoLp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); hotelInfoLp.rightMargin = DeviceInfoUtil.getPixelFromDip(8); hotelInfoLp.bottomMargin = DeviceInfoUtil.getPixelFromDip(95); mHotelInfoLayout.setLayoutParams(hotelInfoLp); }1
2
3
4
5
6
7
8
9
10
11
12
13
14
这是横屏处理我门知道 系统的videoView 控件 自带有播放,暂停 等进度条这是MediaContronller 当我们手点击的时候 进度条会显示,手离开界面的时候,会不显示,这是videoView 中的方法
@Override public boolean onTouchEvent(MotionEvent ev) { if (isInPlaybackState() && mMediaController != null) { toggleMediaControlsVisiblity(); } return false; }1
2
3
4
5
6
7
再朝下看
private void toggleMediaControlsVisiblity() { if (mMediaController.isShowing()) { mMediaController.hide(); } else { mMediaController.show(); } }1
2
3
4
5
6
7
最终调的是 mMediaController.hide(); 和 mMediaController.show(),所以我门在自己的播放器界面要是实现自己的布局和播放器进度条 重写hide() 和 show() 方法即可2 在视频播放的过程中经常会出现播放异常的情况,比如弹出无法播放视频的弹框,当然我门是不想让它弹的,于是我门的处理方式为:
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { return true; } });1
2
3
4
5
6
让onError 直接返回为true 这样能阻止异常框的弹出 同时什么都不做,原理是
Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")"); boolean error_was_handled = false; if (mOnErrorListener != null) { error_was_handled = mOnErrorListener.onError(mMediaPlayer, msg.arg1, msg.arg2); } if (mOnCompletionListener != null && ! error_was_handled) { mOnCompletionListener.onCompletion(mMediaPlayer); } stayAwake(false);1
2
3
4
5
6
7
8
9
这里error_was_handled 为true 这样就不走进mOnCompletionListener.onCompletion(mMediaPlayer);
了。3 视频上线发现 在部分小米机型和魅族等机器上横屏 视频没有办法横屏。解决方案为在布局中
<RelativeLayout android:id="@+id/videoView_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <VideoView android:id="@+id/video" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone" /> </RelativeLayout>1
2
3
4
5
6
7
8
9
10
11
嵌套RelativeLayout;在代码中处理
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); mVideoViewLayout.setLayoutParams(layoutParams); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);1
2
3
4
5
6
7
8
4 在视频开发中,回发现window Leacked 问题,看了下
MediaController 的show 方法
if (!mShowing && mAnchor != null) { setProgress(); if (mPauseButton != null) { mPauseButton.requestFocus(); } disableUnsupportedButtons(); updateFloatingWindowLayout(); mWindowManager.addView(mDecor, mDecorLayoutParams); mShowing = true; } updatePausePlay();1
2
3
4
5
6
7
8
9
10
11
在不停的向view 中加布局,在MediaContrller 中方法了 中hide
/** * Remove the controller from the screen. */ public void hide() { if (mAnchor == null) return; if (mShowing) { try { mHandler.removeMessages(SHOW_PROGRESS); mWindowManager.removeView(mDecor); } catch (IllegalArgumentException ex) { Log.w("MediaController", "already removed"); } mShowing = false; } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
讲view remove 因此 我门在activity 的industry 的生命周期的回调中 执行 hide() 方法即可
android 横竖屏切换属性和播放视频全屏切换
通常我们的应用只会设计成横屏或者竖屏,锁定横屏或竖屏的方法是在manifest.xml文件中设定属性android:screenOrientation为”landscape”或”portrait”:<activity android:name="com.jooylife.jimei_tablet.base.Main" android:label="@string/app_name" android:screenOrientation="landscape"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>1
2
3
4
5
6
7
8
9
10
其实screenOrientation还可以设置成很多值:android:screenOrientation=
[“unspecified” | “behind” |”landscape” | “portrait”|”reverseLandscape”|”reversePortrait” |”sensorLandscape” | “sensorPortrait” |”userLandscape” | “userPortrait” |”sensor” | “fullSensor” | “nosensor” |”user” | “fullUser” | “locked”]
1
2
其中sensorLandscape就是横屏根据重力切换,sensorPortrait竖屏根据重力切换。播放视频全屏切换:
1.Demo:@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE) {
getWindow().getDecorView().setSystemUiVisibility(View.INVISIBLE);
}else if (this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT) {
// this.requestWindowFeature(Window.f);// 去掉标题栏
// this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN);// 去掉信息栏
Log.i(“info”, “portrait”); // 竖屏}View类提供了setSystemUiVisibility和getSystemUiVisibility方法,这两个方法实现对状态栏的动态显示或隐藏的操作,以及获取状态栏当前可见性。setSystemUiVisibility(int visibility)方法可传入的实参为:View.SYSTEM_UI_FLAG_VISIBLE:显示状态栏,Activity不全屏显示(恢复到有状态的正常情况)。
View.INVISIBLE:隐藏状态栏,同时Activity会伸展全屏显示。
View.SYSTEM_UI_FLAG_FULLSCREEN:Activity全屏显示,且状态栏被隐藏覆盖掉。
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN:Activity全屏显示,但状态栏不会被隐藏覆盖,状态栏依然可见,Activity顶端布局部分会被状态遮住。
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
View.SYSTEM_UI_LAYOUT_FLAGS:效果同View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION:隐藏虚拟按键(导航栏)。有些手机会用虚拟按键来代替物理按键。
View.SYSTEM_UI_FLAG_LOW_PROFILE:状态栏显示处于低能显示状态(low profile模式),状态栏上一些图标显示会被隐藏。
2.
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
getWindow().setAttributes(attrs);
getWindow().addFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().setAttributes(attrs);
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
}
android 视频播放器Vitamio踩坑之路
一、Vitamio底层音视频解码原理基于FFmpeg开发,vitamio的优点:(1)Vitamio 能够流畅播放720P甚至1080P高清MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频,(2)可以在 Android 上支持 MMS, RTSP, RTMP, HLS(m3u8) 等常见的多种视频流媒体协议,包括点播与直播。支持 ARMv6 和 ARMv7 两种 ARM CPU,同时对 VFP, VFPv3, NEON 等指令集都做相应优化。二、使用:(1)集成:1.github下载vitamio资源 https://github.com/yixia/VitamioBundle2.解压文件,将其中的vitamio导入到as中 ,打开AS,File -> New -> Import Moudle,选择刚才解压文件夹下的 vitamio 文件. 并且在app的gradle中添加该包的依赖
3.按照app目录下的build.gradle配置vitamio目录下的build.gradle(注意不是vitamio文件夹下app下的)(2)使用1.mainfest文件
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
在自己的AndroidManifest.xm 中添加
<!-- 必须初始化 --><activity android:name="io.vov.vitamio.activity.InitActivity" android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation" android:launchMode="singleTop" android:theme="@android:style/Theme.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden" />2.使用Vitamio库在视频播放的Activity onCreate中 setContentView()之前添加解码监听判断,
//检查vitamio框架是否可用if (!io.vov.vitamio.LibsChecker.checkVitamioLibs(this))
return;1.布局中<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.gbf.livingdemo.VitamioActivity"
android:orientation="vertical">
<io.vov.vitamio.widget.VideoView
android:id="@+id/vitamio_videoview"
android:layout_width="match_parent"
android:layout_height="200dp"/>
</LinearLayout>
2.activitypublic class VitamioActivity extends AppCompatActivity implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener{
private VideoView mVideoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//检查vitamio框架是否可用
if (!io.vov.vitamio.LibsChecker.checkVitamioLibs(this))
return;
setContentView(R.layout.activity_vitamio);
//一定要初始化
Vitamio.initialize(this);
initView();
initData();
}
private void initData() {
mVideoView.setVideoURI(Uri.parse("http://qiubai-video.qiushibaike.com/91B2TEYP9D300XXH_3g.mp4"));
// mVideoView.setVideoURI(Uri.parse("http://alcdn.hls.xiaoka.tv/2017427/14b/7b3/Jzq08Sl8BbyELNTo/index.m3u8"));
mVideoView.setMediaController(new MediaController(this));
//设置监听
mVideoView.setOnPreparedListener(this);
mVideoView.setOnErrorListener(this);
mVideoView.setOnCompletionListener(this);
}
private void initView() {
mVideoView=findViewById(R.id.vitamio_videoview);
}
@Override
public void onPrepared(MediaPlayer mp) {
Toast.makeText(this,"准备好了", Toast.LENGTH_LONG).show();
mVideoView.start();
}
@Override
public void onCompletion(MediaPlayer mp) {
Toast.makeText(this,"播放完成", Toast.LENGTH_LONG).show();
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(this,"Error", Toast.LENGTH_LONG).show();
// 返回 true
return true;
}
}别忘记@Override
protected void onDestroy() {
mVideoView.stopPlayback();
super.onDestroy();
}
效果如下:竖屏:
正常情况下来,进度条应该是在视频的底部,而不是在手机屏幕的底部修改如下:(1)xml布局,在videoview外面添加一层布局如下:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.gbf.livingdemo.VitamioActivity"
android:orientation="vertical">
<RelativeLayout
android:id="@+id/rela"
android:layout_width="match_parent"
android:layout_height="260dp">
<io.vov.vitamio.widget.VideoView
android:id="@+id/vitamio_videoview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
</LinearLayout>
(2)MediaController添加构造函数public MediaController(Context context, boolean isFromXml, View container) {
super(context);
initController(context);
mFromXml = isFromXml;
mRoot = makeControllerView();
if(container instanceof RelativeLayout)
{
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
p.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
mRoot.setLayoutParams(p);
((RelativeLayout)container).addView(mRoot);
}
} public MediaController(Context context) {
super(context);
if (!mFromXml && initController(context))
initFloatingWindow();
}(3)activity中实例化MediaController// mVideoView.setMediaController(new MediaController(this));
mVideoView.setMediaController(new MediaController(this,true,mRelatviLayout));效果如下:
竖屏显示正常~~
横屏幕:
解决办法:(1)清单文件中当前activity设置如下:android:configChanges="orientation|keyboardHidden|screenLayout|screenSize"(2)判断屏幕是否是横屏或者竖屏@Override
public void onConfigurationChanged(Configuration newConfig) {
//屏幕切换时,设置全屏
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
Log.d("haha","切换横屏");
setFullScreen();
}
else
{
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
600);
mRelatviLayout.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
mVideoView.setLayoutParams(layoutParams1);
}
super.onConfigurationChanged(newConfig);
}
private void setFullScreen() {
Log.d("haha","调用设置全屏");
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
mRelatviLayout.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
mVideoView.setLayoutParams(layoutParams1);
}
效果:
像一个正常的播放器了~~
相关文章推荐
- Android 播放视频常见问题小结
- Android开发笔记——视频录制播放常见问题
- android 播放视频常见问题
- Android进阶之视频录制播放常见问题
- Android开发笔记——视频录制播放常见问题
- Android开发笔记——视频录制播放常见问题
- 【转】Android HTML5 Video视频标签自动播放与自动全屏问题解决
- android 视频播放问题,无法播放该视频?
- android Mediaplayer 播放视频 只有声音没有画面的问题
- Android之通过VideoView控件播放一个视频出现的问题以及我的解决办法
- 关于android与Iphone录MP4格式视频播放问题
- 关于android视频播放开发中 播放视频只有声音没有图像的问题解决方案
- html5及android多个视频连续播放问题
- 解决Android中WebView视频无法播放的问题
- Android用Webview播放视频问题
- 关于android视频播放显示区域不正常的问题,一些处理方法
- android 播放assets文件里视频文件的问题
- android播放音视频使用mediaplayer不规范导致的电流过高问题
- 解决vlc-android播放http视频退出问题
- android webView 无法播放视频,无法暂停,继续播放视频问题,无法根据浏览器居中显示内容问题