Android vitamo 实现横竖屏的切换和页面内部的网络视频
来源:互联网 发布:淘宝认证 编辑:程序博客网 时间:2024/05/16 14:17
最近有一个需求,要实现一个播放器,然后可以实现横竖屏的播放,然后可以在页面内部实现网络视频的切换。尝试了几种方式,记录一下:
首先,实现横竖屏的思路,开始实现是通过新建两个布局 ,也就是在layout_land 和layout_port 两个文件夹里建立相应的布局,然后视频切换时候通过传递记录视频信息的对象来实现播放,每次执行都会执行oncreate 方法,然后调用之前的播放状态,通过seekto 跳转到之前的播放位置。这样做基本是可以实现连续播放的,但是需要进行管理的状态有点多,包括视频是否暂停的状态,home键以及back之后需要处理的东西,很琐碎,另外,视频播放进度并不是实时的,seekto方法也并不能跳到指定的位置(总会有一点小偏差),所以这种实现实际是不太现实的。 实现思路二 ,直接使用代码进行横屏 ,通过在manifists文件中的activity 中使用:
<activity android:name=".Activity.VideoActivity" android:launchMode="singleTask" android:configChanges="keyboardHidden|orientation|keyboard|screenSize" /><activity然后调用横竖屏的代码,通过对部分布局进行隐藏,实现横竖屏切换:
//设置横屏 private void setFullScreen() { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //这样mVideoView会自己充满全屏 fullScreen.setImageResource(R.mipmap.min_screen); videoHeadbar.setVisibility(View.GONE); mListView.setVisibility(View.GONE); isPortrit = false; } //设置竖屏操作 private void setLittle() { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); fullScreen.setImageResource(R.mipmap.max_screen); videoHeadbar.setVisibility(View.VISIBLE); mListView.setVisibility(View.VISIBLE); isPortrit = true; }
通过这种方式,videoview会自动的执行横屏的动作,播放的位置也是对的,这应该是横竖屏最简便的实现的方式了。
项目还有一个需求,是通过当前activity 进行视频的切换,通过vitamo的videoview我并没有找到合适的办法,切换时候总会卡着,切换url也并没有任何的效果,后来去stackoverflow 上看到有人通过mediaplayer 实现切换 ,所以我也改变了视频的实现的方式,通过vitamo的mediaplayer + surfaceView 的方式实现当前界面的网络视频切换:
切换视频代码:
//开始播放 private void setplay(String url) { releaseMediaPlayer(); try { mProgres.setVisibility(View.VISIBLE); mMediaPlayer = new MediaPlayer(this); mMediaPlayer.setDataSource(url); mMediaPlayer.setDisplay(holder); mMediaPlayer.prepareAsync(); mMediaPlayer.setOnBufferingUpdateListener(this); mMediaPlayer.setOnCompletionListener(this); mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnVideoSizeChangedListener(this); setVolumeControlStream(AudioManager.STREAM_MUSIC); } catch (IOException ex) { } }
总体思路就这点,全部代码:
布局文件:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout 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" android:background="#000000" > <FrameLayout android:id="@+id/video_camera" android:layout_width="1dp" android:layout_height="1dp" ></FrameLayout> <RelativeLayout android:id="@+id/vid_container" android:layout_width="match_parent" android:layout_height="300dp" android:layout_below="@+id/video_head" > <io.vov.vitamio.widget.CenterLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <SurfaceView android:id="@+id/video_surface" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" > </SurfaceView> </io.vov.vitamio.widget.CenterLayout> <ImageView android:id="@+id/video_coverImage" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/dark" android:scaleType="fitXY" /> <RelativeLayout android:id="@+id/vid_control" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:id="@+id/vid_mid_image" android:layout_width="55dp" android:layout_height="55dp" android:layout_centerInParent="true" android:src="@mipmap/vido_pause" /> <ProgressBar android:id="@+id/vid_progress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="gone" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="100dp" android:layout_alignParentBottom="true" > <SeekBar android:id="@+id/progressBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginEnd="5dp" android:layout_marginStart="5dp" android:foregroundGravity="center" android:minHeight="25dp" android:visibility="visible" /> <RelativeLayout android:id="@+id/vid_text" android:layout_width="match_parent" android:layout_height="20dp" android:layout_below="@id/progressBar" > <TextView android:id="@+id/play_time" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" android:layout_marginStart="10dp" android:text="00:00" android:textColor="#ffffff" android:textSize="12sp" /> <TextView android:id="@+id/alltime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginEnd="10dp" android:text="00:00" android:textColor="#ffffff" android:textSize="12sp" /> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="55dp" android:layout_alignParentBottom="true" android:orientation="horizontal" > <RelativeLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:scaleType="fitXY" android:src="@mipmap/next" /> </RelativeLayout> <RelativeLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" > <ImageView android:id="@+id/vid_begin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:scaleType="fitXY" android:src="@mipmap/play" /> </RelativeLayout> <RelativeLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:scaleType="fitXY" android:src="@mipmap/next" /> <ImageView android:id="@+id/vid_bigscreen" android:layout_width="30dp" android:layout_height="30dp" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginEnd="10dp" android:scaleType="fitXY" android:src="@mipmap/max_screen" /> </RelativeLayout> </LinearLayout> </RelativeLayout> </RelativeLayout> </RelativeLayout> <RelativeLayout android:id="@+id/video_head" android:layout_width="match_parent" android:layout_height="46dp" android:layout_alignParentTop="true" android:background="@color/darkgray" > <ImageButton android:id="@+id/headbar_back" style="@style/Widget.AppCompat.Button.Borderless" android:layout_width="40dp" android:layout_height="match_parent" android:src="@mipmap/titlebar_back" /> <TextView android:id="@+id/headbar_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="理论学习" android:textColor="@color/white" /> </RelativeLayout> <ListView android:id="@+id/video_lv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/vid_container" android:divider="#00000000" android:dividerHeight="1dp" > </ListView></RelativeLayout>主要的视频部分代码,包含了实现了一个定时进行无预览拍照的部分代码:
package com.post.posttime.Activity;import android.app.AlertDialog;import android.app.ProgressDialog;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.ActivityInfo;import android.content.res.Configuration;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Matrix;import android.graphics.PixelFormat;import android.hardware.Camera;import android.media.AudioManager;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.widget.AdapterView;import android.widget.FrameLayout;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import android.widget.RelativeLayout;import android.widget.SeekBar;import android.widget.TextView;import com.google.gson.Gson;import com.post.posttime.Adapters.VideoPageListAdapter;import com.post.posttime.BaseClass.BaseActivity;import com.post.posttime.BaseClass.BaseData;import com.post.posttime.Bean.Net.TheoVideoExaminBean;import com.post.posttime.Bean.Net.VideoListBean;import com.post.posttime.R;import com.post.posttime.Utils.GetIPlocation;import com.post.posttime.Utils.ImagePostUtils;import com.post.posttime.Utils.NetUtils;import com.post.posttime.Utils.SystemUtil;import com.post.posttime.View.CameraPreview;import org.xutils.common.Callback;import org.xutils.ex.HttpException;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import io.vov.vitamio.MediaPlayer;import io.vov.vitamio.Vitamio;import io.vov.vitamio.utils.StringUtils;//显示视频的activitypublic class VideoActivity extends BaseActivity implements SurfaceHolder.Callback, MediaPlayer.OnCompletionListener, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnVideoSizeChangedListener { //视频控件 SurfaceView surface; private SurfaceHolder holder; MediaPlayer mMediaPlayer; SeekBar mProgressBar; //进度条 TextView playTime; //播放时间 TextView alltime; //所有时间 UpDateSeekBar update; // 更新seekbar 的线程 ImageView begin; //开始按钮 ImageView fullScreen; //全屏按钮 boolean isPortrit = true; //是否竖屏 RelativeLayout containder; ImageView midView; //中间大的播放按钮 boolean isPlay = false; //是否播放 RelativeLayout controler; //包括了播放控制的布局 long lastPosition = 0; //视频播放位置 String TAG = "videoactivity"; boolean isFinish = false; // 是否播放完成 ListView mListView; //展示所有章节 //播放数据 VideoListBean videodata; //传过来的播放的内容 int thispostion; //listview的点击位置 最好的方式是通过视频点击之后获取的videoid 获取到播放位置的 现在是根据位置,需要修改一下 VideoPageListAdapter adapter; RelativeLayout videoHeadbar; //顶部的bar 显示标题 ImageView coverImg; //相机 private Camera mCamera; private CameraPreview mCameraPreview; FrameLayout container; SystemUtil su; boolean isBegin = true; TheoVideoExaminBean recordData; int lesson_id; int learnRecordId; //学时id int currentPositon = 0; //记录拍照时候的视频播放位置 int lastClickPositon; //点击listivew之前记录的position ProgressBar mProgres; AlertDialog.Builder errorDialog; AlertDialog.Builder creatRcordDialog; ProgressDialog mDialog; @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_video); Vitamio.isInitialized(this); initData(); init(); initMedia(); } private void init() { su = new SystemUtil(this); errorDialog = new AlertDialog.Builder(this); creatRcordDialog = new AlertDialog.Builder(this); playTime = (TextView) findViewById(R.id.play_time); alltime = (TextView) findViewById(R.id.alltime); midView = (ImageView) findViewById(R.id.vid_mid_image); update = new UpDateSeekBar(); container = (FrameLayout) findViewById(R.id.video_camera); begin = (ImageView) findViewById(R.id.vid_begin); mProgressBar = (SeekBar) findViewById(R.id.progressBar); fullScreen = (ImageView) findViewById(R.id.vid_bigscreen); containder = (RelativeLayout) findViewById(R.id.vid_container); controler = (RelativeLayout) findViewById(R.id.vid_control); videoHeadbar = (RelativeLayout) findViewById(R.id.video_head); mProgres = (ProgressBar) findViewById(R.id.vid_progress); coverImg = (ImageView) findViewById(R.id.video_coverImage); containder.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { controler.setVisibility(View.VISIBLE); showControl(); } }); fullScreen.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (isPortrit) { setFullScreen(); } else { setLittle(); } } }); findViewById(R.id.headbar_back).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onBackPressed(); } }); begin.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { beginToPause(); } }); midView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { beginToPause(); } }); errorDialog.setTitle("验证失败").setMessage("是否重新验证").setPositiveButton("继续验证", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startExamImage(); } }).setNegativeButton("放弃验证", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { thispostion = lastClickPositon; } }); creatRcordDialog.setTitle("尚未创建学时").setMessage("是否创建学时").setPositiveButton("创建", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startExamImage(); } }).setNegativeButton("不创建", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { thispostion = lastClickPositon; } }); } //初始化播放器 private void initMedia() { surface = (SurfaceView) findViewById(R.id.video_surface); holder = surface.getHolder(); holder.addCallback(this); holder.setFormat(PixelFormat.RGBA_8888); holder.setSizeFromLayout(); } //访问人脸识别界面 重新获取学时 private void startExamImage() { Intent intent = new Intent(this, CameraActivity.class); startActivityForResult(intent, 14); } //开始播放 private void setplay(String url) { releaseMediaPlayer(); try { mProgres.setVisibility(View.VISIBLE); mMediaPlayer = new MediaPlayer(this); mMediaPlayer.setDataSource(url); mMediaPlayer.setDisplay(holder); mMediaPlayer.prepareAsync(); mMediaPlayer.setOnBufferingUpdateListener(this); mMediaPlayer.setOnCompletionListener(this); mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnVideoSizeChangedListener(this); setVolumeControlStream(AudioManager.STREAM_MUSIC); } catch (IOException ex) { } } //释放视频播放器 private void releaseMediaPlayer() { if (mMediaPlayer != null) { if (mMediaPlayer.isPlaying()) mMediaPlayer.stop(); mMediaPlayer.release(); mMediaPlayer = null; } } //横竖屏时候调用 @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); } //设置定时器 完成progressbar 的前进 Handler mHandler = new Handler() { public void handleMessage(Message msg) { int s = msg.what; if (s == 1) { if (mMediaPlayer == null) { return; } playTime.setText(StringUtils.generateTime(mMediaPlayer .getCurrentPosition() == 547442232540l ? 0 : mMediaPlayer .getCurrentPosition())); if (mMediaPlayer != null) { seekBar(mMediaPlayer.getCurrentPosition()); } } else if (s == 2) { controler.setVisibility(View.INVISIBLE); } else if (s == 3) { if (mMediaPlayer != null) {//定时调用相机拍照的程序
if (mMediaPlayer.isPlaying() && learnRecordId != -1 && videodata.getData().get(thispostion).getStatus() == 0) { currentPositon = (int) (mMediaPlayer.getCurrentPosition() / 1000); recordData.getData().getOption().get(thispostion).setLastplay(currentPositon); takePic(); } else {// currentPositon=recordData.getData().getOption().get(thispostion).getLastplay(); } } } } }; //拍照方法 private void takePic() { try { if (mCamera != null) { mCamera.startPreview(); mCamera.takePicture(null, null, mPicture); } } catch (Exception e) { e.printStackTrace(); } } //定时调取摄像头拍照 Runnable cameraThread = new Runnable() { @Override public void run() { mHandler.sendEmptyMessage(3); mHandler.postDelayed(cameraThread, BaseData.EXAMIMAGETIME); } }; //照片返回 private Camera.PictureCallback mPicture = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); Matrix matrix = new Matrix(); matrix.preRotate(270); bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); String base64 = ImagePostUtils.bitmapToBase64(bitmap); } }; //获取播放所有的videolist和位置 private void initData() { videodata = (VideoListBean) getIntent().getSerializableExtra("video"); thispostion = getIntent().getIntExtra("postion", 0); lastClickPositon = thispostion; recordData = (TheoVideoExaminBean) getIntent().getSerializableExtra("learnrecord"); lesson_id = getIntent().getIntExtra("lesson_id", 0); mListView = (ListView) findViewById(R.id.video_lv); adapter = new VideoPageListAdapter(videodata.getData(), this); mListView.setAdapter(adapter); adapter.setPostion(thispostion); mListView.smoothScrollToPosition(thispostion); mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //切换视频 lastClickPositon = thispostion; thispostion = position; //点击位置变化 如果成功设置位置,失败的话不改变listviw展示的变化 if (mMediaPlayer != null) { mMediaPlayer.pause(); } setStop(); if (learnRecordId != -1) { //已经创建了学时 adapter.setPostion(position); lastPosition = recordData.getData().getOption().get(position).getLastplay() * 1000; setplay(videodata.getData().get(thispostion).getUrl()); lastClickPositon = thispostion; isFinish = false; } else if (videodata.getData().get(position).getStatus() == 1) { //视频已经完成 重头播放 adapter.setPostion(position); lastPosition = 0; lastClickPositon = thispostion; setplay(videodata.getData().get(thispostion).getUrl());// new Thread(update).start(); isFinish = false; } else { //没有完成,也没有获取过学时 需要拍照获取学时 重新获取到option 然后设置url 和位置 然后再播放 设置listview点击位置 creatRcordDialog.create().show(); } } }); } //获取到播放位置的图片,然后设置成背景图 非常耗时。。。// private void initImage() {// try {// MediaMetadataRetriever mmr = new MediaMetadataRetriever(this);// mmr.setDataSource(this, Uri.parse(videodata.getData().get(thispostion).getUrl()));// Bitmap bitmap;// bitmap = mmr.getFrameAtTime(1);// firstImg.setImageBitmap(bitmap);// firstImg.setVisibility(View.VISIBLE);// mmr.release();// } catch (Exception e) {//// }//// } //定时获取播放进度 class UpDateSeekBar implements Runnable { @Override public void run() { if (!isFinish) { Message msg = mHandler.obtainMessage(); msg.what = 1; mHandler.sendMessage(msg); mHandler.postDelayed(update, 1000); } } } //过一段时间隐藏操作栏 private void showControl() { if (isPlay) { Message msg = mHandler.obtainMessage(); msg.what = 2; mHandler.sendMessageDelayed(msg, 5000); } } //点击事件 private void beginToPause() { if (isBegin) { setplay(videodata.getData().get(thispostion).getUrl()); } else { if (isFinish) { isFinish = false; mMediaPlayer.seekTo(0); mMediaPlayer.start();// new Thread(update).start(); setStart(); } else { if (isPlay) { mMediaPlayer.pause(); setStop(); } else { mMediaPlayer.start(); setStart(); } } } } //运行时设置图片 private void setStart() { begin.setImageResource(R.mipmap.pause); midView.setImageResource(R.mipmap.video_pause_bg); isPlay = true; showControl(); } //设置暂停时图片 private void setStop() { begin.setImageResource(R.mipmap.play); midView.setImageResource(R.mipmap.video_player_bg); isPlay = false; controler.setVisibility(View.VISIBLE); } //开始时候开启摄像头 private void beginCamera() { mCamera = CameraActivity.getCameraInstance(1); if (mCamera != null) { mCameraPreview = new CameraPreview(this, mCamera); container.removeAllViews(); container.addView(mCameraPreview); mHandler.postDelayed(cameraThread, 5000); } else { toast("摄像头权限被禁止,将无法记录学时"); } } //设置seekbar 位置 private void seekBar(long size) { if (mMediaPlayer.isPlaying()) { long mMax = mMediaPlayer.getDuration(); int sMax = mProgressBar.getMax(); mProgressBar.setProgress((int) (size * sMax / mMax)); } } //视频播放完毕 拍照上传 停止视频 改变当前的是否看完的信息 @Override public void onCompletion(MediaPlayer mp) { currentPositon = (int) (mMediaPlayer.getDuration() / 1000); takePic(); isFinish = true; mMediaPlayer.pause(); setStop(); videodata.getData().get(thispostion).setStatus(1); toast("当前视频播放完成"); } @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { } @Override protected void onPause() { super.onPause(); mHandler.removeCallbacks(cameraThread); releaseCamera(); if (mMediaPlayer != null) { mMediaPlayer.pause(); } setStop(); //默认退出界面后 包括home键之后结束计时 否则系统杀死后无法计时// finish(); } @Override protected void onResume() { super.onResume(); //开始运行时开启摄像头 beginCamera(); } @Override protected void onDestroy() { super.onDestroy(); if (mMediaPlayer != null) { releaseMediaPlayer(); } if (mCamera != null) { releaseCamera(); } isFinish = true; isPlay = false; mHandler.removeCallbacks(update); mHandler.removeCallbacks(cameraThread); } //视频准备阶段 执行onstart 方法之后每次都执行这个 @Override public void onPrepared(MediaPlayer mp) { mProgres.setVisibility(View.GONE); controler.setVisibility(View.VISIBLE); new Thread(update).start(); alltime.setText(StringUtils.generateTime(mMediaPlayer.getDuration())); isBegin = false; setStart(); mp.start(); coverImg.setVisibility(View.GONE); } @Override public void onSeekComplete(MediaPlayer mp) { loge("seekto complete"); } //设置横屏 private void setFullScreen() { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //这样mVideoView会自己充满全屏 fullScreen.setImageResource(R.mipmap.min_screen); videoHeadbar.setVisibility(View.GONE); mListView.setVisibility(View.GONE); isPortrit = false; } //设置竖屏操作 private void setLittle() { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); fullScreen.setImageResource(R.mipmap.max_screen); videoHeadbar.setVisibility(View.VISIBLE); mListView.setVisibility(View.VISIBLE); isPortrit = true; } @Override public void onBackPressed() { if (!isPortrit) { setLittle(); } else super.onBackPressed(); } //释放摄像头 private void releaseCamera() { if (mCamera != null) { mCamera.release(); mCamera = null; } } //格式化时间 private String getFormatTime(long time) { Date date = new Date(time); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return format.format(date); } //surface 的变化的listener @Override public void surfaceCreated(SurfaceHolder holder) { } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } //开始的位置跳转通过这个方法调用 @Override public void onVideoSizeChanged(MediaPlayer mp, int width, int height) { if (width == 0 || height == 0) { return; } mp.seekTo(lastPosition); }}
有几个地方是不太满意的,首先在开始时候跳转是通过seekto方法,但是视频准备好之前是不起作用的,先调用Mediaplayer.start 方法之后(而且是需要过一点时间)才能调用seekto,所以这里我在onsurfacechange的方法调用了seekto,然后在onprepared之中直接调用了start这样,其他地方调用mMediaPlayer.prepareAsync() 之后直接就会开始视频,控制上感觉有点不足。
另外surfaceview 开始加载会有穿透的效果,也就是会直接看到之前的一个activity ,这里开始我是通过获取第一帧图片来遮挡实现,但是这个方法执行会减慢进入界面的速度,估计是阻塞了UI线程,所以我是通过直接加载了一个黑色背景实现的,这里总感觉不够好,以后可以尝试更漂亮方法实现。就记录到这里
- Android vitamo 实现横竖屏的切换和页面内部的网络视频
- Android使用VideoView和MediaController播放网络视频(包括横竖排切换的处理)
- Android 实现视频字幕Subtitle和横竖屏切换
- Android视频播放和横竖屏切换
- android(32)(视频横竖屏切换的生命周期)
- Android-->播放视频横竖屏切换的2种方式
- Android 视频播放适配横竖屏切换功能的实现
- android 横竖屏切换属性和播放视频全屏切换
- android 横竖屏切换属性和播放视频全屏切换
- android 横竖屏切换属性和播放视频全屏切换
- android的横竖屏切换
- Android的横竖屏切换
- ios autolayout进阶教程,实现视频播放时,横竖屏的自动切换-适配iOS8 sizeClass 和之前的版本
- android横竖屏切换的生命周期和调用方法
- Android横竖屏切换和灭屏亮屏时Activity的生命周期探究
- android横竖屏切换和布局的问题
- android横竖屏切换和布局的问题
- Android横竖屏切换时,状态和信息的维护
- 【Data_Structure笔记4】排序算法之【交换类排序】
- DirectFB学习之使用devmem驱动
- springboot搭建
- Linux信号(signal) 机制分析
- hdu 2082 找单词(母函数)
- Android vitamo 实现横竖屏的切换和页面内部的网络视频
- 源
- 【安卓学习笔记】JAVA基础Lesson6-关键字static
- Java重要的数据结构Set,List,Map
- [宏]_IO, _IOR, _IOW, _IOWR 宏的用法与解析
- excel录制宏运行规划求解不能运行的问题
- 1、python面向对象之HelloWord
- 刘未鹏 : 数学之美番外篇:平凡而又神奇的贝叶斯方法
- 百练 神奇的幻方(二维数组水题)