/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.letv.watchball.pip;
import java.io.IOException;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.RelativeLayout.LayoutParams;
import com.letv.watchball.ui.impl.BasePlayActivity;
import com.letv.watchball.utils.LetvUtil;
import com.letv.watchball.utils.LogInfo;
import com.media.NativeInfos;
import com.media.NativePlayer;
import com.media.NativePlayer.OnLoadingPerListener;
/**
* Displays a video file. The VideoView class can load images from various
* sources (such as resources or content providers), takes care of computing its
* measurement from the video so that it can be used in any layout manager, and
* provides various display options such as scaling and tinting.
*/
public class VideoView extends SurfaceView implements MediaPlayerControl {
protected String TAG = "VideoView";
// settable by the client
protected Uri mUri;
protected int mDuration;
protected int mAdDuraction;
// all possible internal states
protected static final int STATE_ERROR = -1;
protected static final int STATE_IDLE = 0;
protected static final int STATE_PREPARING = 1;
protected static final int STATE_PREPARED = 2;
protected static final int STATE_PLAYING = 3;
protected static final int STATE_PAUSED = 4;
protected static final int STATE_PLAYBACK_COMPLETED = 5;
// mCurrentState is a VideoView object's current state.
// mTargetState is the state that a method caller intends to reach.
// For instance, regardless the VideoView object's current state,
// calling pause() intends to bring the object to a target state
// of STATE_PAUSED.
protected int mCurrentState = STATE_IDLE;
protected int mTargetState = STATE_IDLE;
// All the stuff we need for playing and showing a video
protected SurfaceHolder mSurfaceHolder = null;
protected MediaPlayer mMediaPlayer = null;
protected Context mContext;
protected int mVideoWidth;
protected int mVideoHeight;
protected int mSurfaceWidth;
protected int mSurfaceHeight;
protected BaseMediaController mBaseMediaController;
protected OnLoadingPerListener mOnLoadingPerListener;
protected OnCompletionListener mOnCompletionListener;
protected MediaPlayer.OnPreparedListener mOnPreparedListener;
protected int mCurrentBufferPercentage;
protected OnErrorListener mOnErrorListener;
protected boolean fullScreen;// 是否全屏模式
protected String videoTitle;// 视频标题
protected int mSeekWhenPrepared; // recording the seek position while
// preparing
protected boolean mCanPause;
protected boolean mCanSeekBack;
protected boolean mCanSeekForward;
protected boolean isBufferCount = true;// 添加字段,播放统计时需要
protected boolean firstPlay = true;// 当前VideoView所代表的播放器首次进行播放
protected boolean firstInitScreen = true;
protected boolean isOnPause = false;
protected int screenWidth;
protected int screenHeight;
protected boolean isPlayingAd = false;
public VideoView(Context context) {
super(context);
this.mContext = context;
initVideoView();
}
public VideoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
this.mContext = context;
initVideoView();
}
public VideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mContext = context;
initVideoView();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
if (LetvUtil.isDebug()) {
System.out.println("onMeasure.............mVideoWidth:" + mVideoWidth
+ ",mVideoHeight:" + mVideoHeight + ",widthMeasureSpec:" + widthMeasureSpec
+ ",heightMeasureSpec:" + heightMeasureSpec);
}
setMeasuredDimension(width, height);
}
public int resolveAdjustedSize(int desiredSize, int measureSpec) {
int result = desiredSize;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
/*
* Parent says we can be as big as we want. Just don't be larger
* than max size imposed on ourselves.
*/
result = desiredSize;
break;
case MeasureSpec.AT_MOST:
/*
* Parent says we can be as big as we want, up to specSize. Don't be
* larger than specSize, and don't be larger than the max size
* imposed on ourselves.
*/
result = Math.min(desiredSize, specSize);
break;
case MeasureSpec.EXACTLY:
// No choice. Do what we are told.
result = specSize;
break;
}
return result;
}
protected void initVideoView() {
if ((mContext instanceof Activity)) {
Activity activity = (Activity) mContext;
Display display = activity.getWindowManager().getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();
}
mVideoWidth = 0;
mVideoHeight = 0;
getHolder().addCallback(mSHCallback);
if (LetvUtil.isDebug()) {
System.out.println("NativeInfos.ifNativePlayer():" + NativeInfos.ifNativePlayer());
}
if (!NativeInfos.ifNativePlayer()) {
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
// setKeepScreenOn(true);
setFocusable(true);
setFocusableInTouchMode(true);
requestFocus();
mCurrentState = STATE_IDLE;
mTargetState = STATE_IDLE;
}
/**
* 设置播放路径
*
* @param path
*/
public void setVideoPath(String path) {
setVideoURI(Uri.parse(path));
}
/**
* 设置播放地址
*
* @param uri
*/
public void setVideoURI(Uri uri) {
try {
mUri = uri;
mSeekWhenPrepared = 0;
openVideo();
requestLayout();
invalidate();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 停止播放
*/
public synchronized void stopPlayback() {// 改动,加了线程
if (LetvUtil.isDebug()) {
System.out.println("stopPlayback...................mMediaPlayer:" + mMediaPlayer);
}
mCurrentState = STATE_IDLE;
mTargetState = STATE_IDLE;
if (mMediaPlayer != null) {
final MediaPlayer m = mMediaPlayer;
mMediaPlayer = null;
new Thread() {
public void run() {
try {
if (m != null) {
m.stop();
m.release();
LogInfo.log("--------------stopPlayback----------------");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
}
/**
* 打开并初始化播放器
*/
protected synchronized void openVideo() {
if (LetvUtil.isDebug()) {
System.out.println("openVideo.................mSurfaceHolder:" + mSurfaceHolder
+ ",isOnPause:" + isOnPause + ",mCurrentState:" + mCurrentState + ",mUri:"
+ mUri);
}
if (mUri == null || mSurfaceHolder == null || isOnPause) {
// not ready for playback just yet, will try again later
return;
}
// Tell the music playback service to pause
// TODO: these constants need to be published somewhere in the
// framework.
Intent i = new Intent("com.android.music.musicservicecommand");
i.putExtra("command", "pause");
mContext.sendBroadcast(i);
// we shouldn't clear the target state, because somebody might have
// called start() previously
// release(false); 改动,每次开始播放时都是先释放去掉
try {
if (mMediaPlayer == null) {
if (NativeInfos.ifNativePlayer()) {
mMediaPlayer = new NativePlayer();
// 添加如下这段代码,设置监听
((NativePlayer) mMediaPlayer).setOnLoadingPerListener(mLoadingPerListener);
// Log.e("xue", "软解");
} else {
mMediaPlayer = new MediaPlayer();
// Log.e("xue", "系统");
}
if (LetvUtil.isDebug()) {
System.out.println("openVideo...............mMediaPlayer:" + mMediaPlayer);
}
mMediaPlayer.reset();
mMediaPlayer.setOnPreparedListener(mPreparedListener);
mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
mDuration = -1;
mMediaPlayer.setOnCompletionListener(mCompletionListener);
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mCurrentBufferPercentage = 0;
mMediaPlayer.setDataSource(mContext, mUri);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setScreenOnWhilePlaying(true);
mMediaPlayer.prepareAsync();
// we don't set the target state here either, but preserve the
// target state that was there before.
mCurrentState = STATE_PREPARING;
}
// attachMediaController();
} catch (IOException ex) {
ex.printStackTrace();
Log.w(TAG, "Unable to open content: " + mUri, ex);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
Log.w(TAG, "Unable to open content: " + mUri, ex);
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);
return;
}
}
public void setMediaController(BaseMediaController controller) {
if (mBaseMediaController != null) {
mBaseMediaController.hide();
}
mBaseMediaController = controller;
// attachMediaController();
}
/**
* 绑定播放控件
*/
protected void attachMediaController() {
if (mMediaPlayer != null && mBaseMediaController != null) {
mBaseMediaController.setMediaPlayer(this);
View anchorView = this.getParent() instanceof View ? (View) this.getParent() : this;
mBaseMediaController.setAnchorView(anchorView);
mBaseMediaController.setEnabled(isInPlaybackState());
}
}
MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener = new MediaPlayer.OnVideoSizeChangedListener() {
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
if (isInPlaybackState()) {
mVideoWidth = mp.getVideoWidth();
mVideoHeight = mp.getVideoHeight();
}
if (LetvUtil.isDebug()) {
System.out
.println("onVideoSizeChanged............mVideoWidth:" + mVideoWidth
+ ",mVideoHeight:" + mVideoHeight + ",width:" + width + ",height:"
+ height);
}
if (mVideoWidth != 0 && mVideoHeight != 0) {
getHolder().setFixedSize(mVideoWidth, mVideoHeight);
remodelScreen(fullScreen);
// if (firstInitScreen) {
// remodelScreen(false);// 默认情况下为非全屏播放
// firstInitScreen = false;
// }
}
}
};
MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
attachMediaController();
if (mMediaPlayer == null) {
mMediaPlayer = mp;
}
if (LetvUtil.isDebug()) {
System.out.println("OnPreparedListener..........................mCurrentState:"
+ mCurrentState);
}
mCurrentState = STATE_PREPARED;
// // Get the capabilities of the player for this stream
// Metadata data = mp.getMetadata(MediaPlayer.METADATA_ALL,
// MediaPlayer.BYPASS_METADATA_FILTER);
//
// if (data != null) {
// mCanPause = !data.has(Metadata.PAUSE_AVAILABLE)
// || data.getBoolean(Metadata.PAUSE_AVAILABLE);
// mCanSeekBack = !data.has(Metadata.SEEK_BACKWARD_AVAILABLE)
// || data.getBoolean(Metadata.SEEK_BACKWARD_AVAILABLE);
// mCanSeekForward = !data.has(Metadata.SEEK_FORWARD_AVAILABLE)
// || data.getBoolean(Metadata.SEEK_FORWARD_AVAILABLE);
// } else {
// mCanPause = mCanSeekForward = mCanSeekForward = true;
// }
mCanPause = mCanSeekBack = mCanSeekForward = true;
if (mOnPreparedListener != null) {
mOnPreparedListener.onPrepared(mMediaPlayer);
}
if (mBaseMediaController != null) {
mBaseMediaController.setEnabled(true);
}
if (isInPlaybackState()) {
try {
mVideoWidth = mp.getVideoWidth();
mVideoHeight = mp.getVideoHeight();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
int seekToPosition = mSeekWhenPrepared; // mSeekWhenPrepared may be
// changed after seekTo()
// call
if (seekToPosition != 0) {
seekTo(seekToPosition);
}
if (LetvUtil.isDebug()) {
System.out.println("onPrepared............mVideoWidth:" + mVideoWidth
+ ",mVideoHeight:" + mVideoHeight);
}
if (mVideoWidth != 0 && mVideoHeight != 0) {
// Log.i("@@@@", "video size: " + mVideoWidth +"/"+
// mVideoHeight);
getHolder().setFixedSize(mVideoWidth, mVideoHeight);
if (firstInitScreen) {
remodelScreen(false);// 默认情况下为非全屏播放
firstInitScreen = false;
}
if (mSurfaceWidth == mVideoWidth && mSurfaceHeight == mVideoHeight) {
// We didn't actually change the size (it was already at the
// size
// we need), so we won't get a "surface changed" callback,
// so
// start the video here instead of in the callback.
if (mTargetState == STATE_PLAYING) {
start();
/*
* 为了不让开始时显示控制栏而先注释掉 if (mBaseMediaController != null &&
* getWindowToken() != null) {
* mBaseMediaController.show();
*
* }
*/
} else if (!isPlaying() && (seekToPosition != 0 || getCurrentPosition() > 0)) {
/*
* 为了不让开始时显示控制栏而先注释掉 if (mBaseMediaController != null) {
* mBaseMediaController.show(0); }
*/
}
}
} else {
// We don't know the video size yet, but should start anyway.
// The video size might be reported to us later.
if (mTargetState == STATE_PLAYING) {
start();
}
}
if (firstPlay) {
firstPlay = false;
if (mTargetState == STATE_PLAYING) {
start();
}
/*
* 为了不让开始时显示控制栏而先注释掉 if (mBaseMediaController != null &&
* getWindowToken() != null) { mBaseMediaController.show(); }
*/
}
KeyguardManager keyguardManager = (KeyguardManager) getContext().getSystemService(
Context.KEYGUARD_SERVICE);
if (LetvUtil.isDebug()) {
System.out.println("keyguardManager.inKeyguardRestrictedInputMode():"
+ keyguardManager.inKeyguardRestrictedInputMode());
}
if (keyguardManager.inKeyguardRestrictedInputMode()) {
pause();
}
}
};
protected MediaPlayer.OnCompletionListener mCompletionListener = new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
mCurrentState = STATE_PLAYBACK_COMPLETED;
mTargetState = STATE_PLAYBACK_COMPLETED;
if (mBaseMediaController != null) {
mBaseMediaController.hide();
}
if (mOnCompletionListener != null) {
mOnCompletionListener.onCompletion(mMediaPlayer);
}
}
};
protected NativePlayer.OnLoadingPerListener mLoadingPerListener = new NativePlayer.OnLoadingPerListener() {
@Override
public void onLoadingPer(MediaPlayer mp, int per) {
// per即为缓冲比的大小
if (mOnLoadingPerListener != null) {
mOnLoadingPerListener.onLoadingPer(mp, per);
}
}
};
protected MediaPlayer.OnErrorListener mErrorListener = new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
mCurrentState = STATE_ERROR;
mTargetState = STATE_ERROR;
if (mBaseMediaController != null) {
mBaseMediaController.hide();
}
/* If an error handler has been supplied, use it and finish. */
if (mOnErrorListener != null) {
if (mOnErrorListener.onError(mMediaPlayer, framework_err, impl_err)) {
return true;
}
}
/*
* Otherwise, pop up an error dialog so the user knows that
* something bad has happened. Only try and pop up the dialog if
* we're attached to a window. When we're going away and no longer
* have a window, don't bother showing the user an error.
*/
if (getWindowToken() != null) {
// Resources r = mContext.getResources();
// int messageId;
//
// if (framework_err ==
// MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
// messageId =
// com.android.internal.R.string.VideoView_error_text_invalid_progressive_playback;
// } else {
// messageId =
// com.android.internal.R.string.VideoView_error_text_unknown;
// }
//
// new AlertDialog.Builder(mContext)
// .setTitle(com.android.internal.R.string.VideoView_error_title)
// .setMessage(messageId)
// .setPositiveButton(com.android.internal.R.string.VideoView_error_button,
// new DialogInterface.OnClickListener() {
// public void onClick(DialogInterface dialog, int whichButton)
// {
// /* If we get here, there is no onError listener, so
// * at least inform them that the video is over.
// */
// if (mOnCompletionListener != null) {
// mOnCompletionListener.onCompletion(mMediaPlayer);
// }
// }
// })
// .setCancelable(false)
// .show();
}
return true;
}
};
protected MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = new MediaPlayer.OnBufferingUpdateListener() {
public void onBufferingUpdate(MediaPlayer mp, int percent) {
mCurrentBufferPercentage = percent;
}
};
/**
* Register a callback to be invoked when the media file is loaded and ready
* to go.
*
* @param l
* The callback that will be run
*/
public void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
mOnPreparedListener = l;
}
/**
* Register a callback to be invoked when the end of a media file has been
* reached during playback.
*
* @param l
* The callback that will be run
*/
public void setOnCompletionListener(OnCompletionListener l) {
mOnCompletionListener = l;
}
public void setOnLoadingPerListener(OnLoadingPerListener l) {
mOnLoadingPerListener = l;
}
/**
* Register a callback to be invoked when an error occurs during playback or
* setup. If no listener is specified, or if the listener returned false,
* VideoView will inform the user of any errors.
*
* @param l
* The callback that will be run
*/
public void setOnErrorListener(OnErrorListener l) {
mOnErrorListener = l;
}
SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback() {
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (LetvUtil.isDebug()) {
System.out.println("surfaceChanged.....................holder:" + holder + ",w:"
+ w + ",h:" + h);
}
mSurfaceWidth = w;
mSurfaceHeight = h;
boolean isValidState = (mTargetState == STATE_PLAYING);
boolean hasValidSize = (mVideoWidth == w && mVideoHeight == h);
if (mMediaPlayer != null && isValidState && hasValidSize) {
if (mSeekWhenPrepared != 0) {
seekTo(mSeekWhenPrepared);
}
start();
}
}
public void surfaceCreated(SurfaceHolder holder) {
if (LetvUtil.isDebug()) {
System.out.println("surfaceCreated.....................holder:" + holder);
}
try {
mSurfaceHolder = holder;
openVideo();// 改动,只有手动setvideourl才加载视频
} catch (Exception e) {
e.printStackTrace();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (LetvUtil.isDebug()) {
System.out.println("surfaceDestroyed.....................holder:" + holder);
}
// after we return from this we can't use the surface any more
mSurfaceHolder = null;
if (mBaseMediaController != null)
mBaseMediaController.hide();
// release(true);//改动,默认界面消失后,播放停止,去掉后需要手动调用停止方法
}
};
/**
* 释放播放器
*
* @param cleartargetstate
*/
protected synchronized void release(boolean cleartargetstate) {
if (mMediaPlayer != null) {
mMediaPlayer.reset();
mMediaPlayer.release();
mMediaPlayer = null;
mCurrentState = STATE_IDLE;
if (cleartargetstate) {
mTargetState = STATE_IDLE;
}
}
}
@Override
public boolean onTrackballEvent(MotionEvent ev) {
if (isInPlaybackState() && mBaseMediaController != null) {
toggleMediaControlsVisiblity();
}
return false;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
BasePlayActivity ac = null;
if (mContext != null && mContext instanceof BasePlayActivity) {
ac = (BasePlayActivity) mContext;
}
// if (ac != null && !ac.isLock()) {
if (ac != null) {
if (mCurrentState == STATE_PREPARED || mCurrentState == STATE_PLAYING
|| mCurrentState == STATE_PAUSED) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
|| keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
return true;
}
}
boolean isKeyCodeSupported = keyCode != KeyEvent.KEYCODE_BACK
&& keyCode != KeyEvent.KEYCODE_VOLUME_UP
&& keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_MENU
&& keyCode != KeyEvent.KEYCODE_CALL && keyCode != KeyEvent.KEYCODE_ENDCALL;
if (isInPlaybackState() && isKeyCodeSupported && mBaseMediaController != null) {
if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK
|| keyCode == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (mMediaPlayer.isPlaying()) {
pause();
mBaseMediaController.show();
} else {
start();
mBaseMediaController.hide();
}
return true;
}
} else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP && mMediaPlayer.isPlaying()) {
pause();
mBaseMediaController.show();
} else {
toggleMediaControlsVisiblity();
}
}
}
return super.onKeyDown(keyCode, event);
}
/**
* 显示或隐藏播放控制界面
*/
protected void toggleMediaControlsVisiblity() {
if (mBaseMediaController.isShowing()) {
mBaseMediaController.hide();
} else {
mBaseMediaController.show();
}
}
/**
* 开始播放
*/
public synchronized void start() {
if (isInPlaybackState()) {
try {
mMediaPlayer.start();
mCurrentState = STATE_PLAYING;
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
mTargetState = STATE_PLAYING;
}
/**
* 暂停播放
*/
public synchronized void pause() {
if (isInPlaybackState()) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
mCurrentState = STATE_PAUSED;
}
}
mTargetState = STATE_PAUSED;
}
/**
* 根据是否全屏播放来设置播放界面尺寸
*
* @param fullScreen
*/
protected void remodelScreen(boolean fullScreen) {
this.fullScreen = fullScreen;
if (fullScreen) {
int videoWidth = mVideoWidth;
int videoHeight = mVideoHeight;
int mWidth = screenWidth;
int mHeight = screenHeight;
// if (LetvUtil.isDebug()) {
// System.out.println("fullScreen............................");
// System.out.println("videoWidth:" + videoWidth + ",videoHeight:" +
// videoHeight);
// System.out.println("screenWidth:" + screenWidth +
// ",screenHeight:" + screenHeight);
// System.out.println("videoScale:" + ((float) videoWidth /
// videoHeight)
// + ",screenScale:" + ((float) screenWidth / screenHeight));
// }
if (videoWidth > 0 && videoHeight > 0) {
if ((videoWidth * screenHeight) >= (videoHeight * screenWidth)) {
videoHeight = mHeight;
videoWidth = (int) ((float) videoWidth * mHeight / mVideoHeight);
} else {
videoWidth = mWidth;
videoHeight = (int) ((float) videoHeight * mWidth / mVideoWidth);
}
if (LetvUtil.isDebug()) {
System.out.println("finalWidth:" + videoWidth + ",finalHeight:" + videoHeight);
}
setVideoViewScale(videoWidth, videoHeight);
}
} else {
int videoWidth = mVideoWidth;
int videoHeight = mVideoHeight;
int mWidth = screenWidth;
int mHeight = screenHeight;
// if (LetvUtil.isDebug()) {
// System.out.println("normalScreen............................");
// System.out.println("videoWidth:" + videoWidth + ",videoHeight:" +
// videoHeight);
// System.out.println("screenWidth:" + screenWidth +
// ",screenHeight:" + screenHeight);
// System.out.println("videoScale:" + ((float) videoWidth /
// videoHeight)
// + ",screenScale:" + ((float) screenWidth / screenHeight));
// }
if (videoWidth > 0 && videoHeight > 0) {
if ((videoWidth * screenHeight) >= (videoHeight * screenWidth)) {
videoWidth = mWidth;
videoHeight = (int) ((float) videoHeight * mWidth / mVideoWidth);
} else {
videoHeight = mHeight;
videoWidth = (int) ((float) videoWidth * mHeight / mVideoHeight);
}
if (LetvUtil.isDebug()) {
System.out.println("finalWidth:" + videoWidth + ",finalHeight:" + videoHeight);
}
setVideoViewScale(videoWidth, videoHeight);
}
}
}
/**
* 切换全屏和非全屏
*/
public boolean toggleScreen() {
fullScreen = !fullScreen;
remodelScreen(fullScreen);
return fullScreen;
}
/**
* 切换全屏和非全屏
*/
public boolean toggleScreen(boolean fullScreen) {
this.fullScreen = fullScreen;
remodelScreen(this.fullScreen);
return this.fullScreen;
}
/**
* 设置播放器控件的大小
*
* @param width
* @param height
*/
protected void setVideoViewScale(int width, int height) {
LayoutParams lp = (LayoutParams) this.getLayoutParams();
lp.height = height;
lp.width = width;
if (NativeInfos.ifNativePlayer()) {
lp.leftMargin = -1000;
lp.rightMargin = -1000;
lp.topMargin = -1000;
lp.bottomMargin = -1000;
}
setLayoutParams(lp);
}
/**
* 得到播放总时长
*/
public synchronized int getDuration() {
if (isInPlaybackState()) {
if (mDuration > 0) {
return mDuration;
}
mDuration = mMediaPlayer.getDuration() - mAdDuraction * 1000;
return mDuration;
}
mDuration = -1;
return mDuration;
}
/**
* 得到当前播放时长
*/
public synchronized int getCurrentPosition() {
if (isInPlaybackState()) {
int t = (mMediaPlayer.getCurrentPosition() - mAdDuraction * 1000);
if (t > 0) {
isPlayingAd = false;
return t;
} else {
isPlayingAd = true;
return t;
}
}
return 0;
}
private synchronized void seekToAd(int msec) {
if (isInPlaybackState()) {
int adt = mAdDuraction * 1000;
try {
if (adt + msec <= 0) {
msec = 0;
} else {
msec = adt + msec;
}
mMediaPlayer.seekTo(msec);
mSeekWhenPrepared = 0;
} catch (IllegalStateException e) {
e.printStackTrace();
}
} else {
mSeekWhenPrepared = msec;
}
}
public synchronized void seekTo(int msec) {
if (msec < 0) {
seekToAd(msec);
return;
}
if (isInPlaybackState()) {
int adt = mAdDuraction * 1000;
try {
if (msec <= 0) {
msec = 1 * 1000;
}
msec += adt;
mMediaPlayer.seekTo(msec);
mSeekWhenPrepared = 0;
} catch (IllegalStateException e) {
e.printStackTrace();
}
} else {
mSeekWhenPrepared = msec;
}
}
/**
* 播放器是否正在播放
*/
public synchronized boolean isPlaying() {
return isInPlaybackState() && mMediaPlayer.isPlaying();
}
/**
* 播放器是否正在播放
*/
public synchronized boolean isPlayingAd() {
return isPlayingAd;
}
/**
* 得到当前播放缓冲百分比
*/
public int getBufferPercentage() {
if (mMediaPlayer != null) {
return mCurrentBufferPercentage;
}
return 0;
}
/**
* 播放器是否处于播放状态
*
* @return
*/
public synchronized boolean isInPlaybackState() {
return (mMediaPlayer != null && mCurrentState != STATE_ERROR && mCurrentState != STATE_IDLE && mCurrentState != STATE_PREPARING);
}
/**
* 设置视频标题,由于标题在mediaController中显示,所以本方法要在设置mediaController之前调用
*
* @param videoTitle
* 视频标题
*/
public void setVideoTitle(String videoTitle) {
this.videoTitle = videoTitle;
}
public boolean canPause() {
return mCanPause;
}
public boolean canSeekBackward() {
return mCanSeekBack;
}
public boolean canSeekForward() {
return mCanSeekForward;
}
public String getVideoTitle() {
return videoTitle;
}
public void onPause() {
isOnPause = true;
}
public void onResume() {
isOnPause = false;
}
@Override
public int getScreenWidth() {
return screenWidth;
}
@Override
public int getScreenHeight() {
return screenHeight;
}
public int getmAdDuraction() {
return mAdDuraction;
}
public void setmAdDuraction(int mAdDuraction) {
if (mAdDuraction > 0) {
isPlayingAd = true;
}
this.mAdDuraction = mAdDuraction;
}
}