add library
1
.gitignore
vendored
@@ -16,3 +16,4 @@
|
||||
/.idea/
|
||||
/app/src/test/java/com/uiui/videoplayer/
|
||||
/app/src/androidTest/java/com/uiui/videoplayer/
|
||||
/library/build/
|
||||
|
||||
31
library/build.gradle
Normal file
@@ -0,0 +1,31 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
buildToolsVersion = '30.0.3'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
versionCode 106
|
||||
versionName "7.6.0"
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility 1.8
|
||||
targetCompatibility 1.8
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "androidx.core:core-ktx:1.3.2"
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
//apply from: '../gradle/build_upload.gradle'
|
||||
6
library/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="cn.jzvd">
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
</manifest>
|
||||
88
library/src/main/java/cn/jzvd/JZDataSource.java
Normal file
@@ -0,0 +1,88 @@
|
||||
package cn.jzvd;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
public class JZDataSource {
|
||||
|
||||
public static final String URL_KEY_DEFAULT = "URL_KEY_DEFAULT";
|
||||
|
||||
public int currentUrlIndex;
|
||||
public LinkedHashMap urlsMap = new LinkedHashMap();
|
||||
public String title = "";
|
||||
public HashMap<String, String> headerMap = new HashMap<>();
|
||||
public boolean looping = false;
|
||||
public Object[] objects;
|
||||
|
||||
public JZDataSource(String url) {
|
||||
urlsMap.put(URL_KEY_DEFAULT, url);
|
||||
currentUrlIndex = 0;
|
||||
}
|
||||
|
||||
public JZDataSource(String url, String title) {
|
||||
urlsMap.put(URL_KEY_DEFAULT, url);
|
||||
this.title = title;
|
||||
currentUrlIndex = 0;
|
||||
}
|
||||
|
||||
public JZDataSource(Object url) {
|
||||
urlsMap.put(URL_KEY_DEFAULT, url);
|
||||
currentUrlIndex = 0;
|
||||
}
|
||||
|
||||
public JZDataSource(LinkedHashMap urlsMap) {
|
||||
this.urlsMap.clear();
|
||||
this.urlsMap.putAll(urlsMap);
|
||||
currentUrlIndex = 0;
|
||||
}
|
||||
|
||||
public JZDataSource(LinkedHashMap urlsMap, String title) {
|
||||
this.urlsMap.clear();
|
||||
this.urlsMap.putAll(urlsMap);
|
||||
this.title = title;
|
||||
currentUrlIndex = 0;
|
||||
}
|
||||
|
||||
public Object getCurrentUrl() {
|
||||
return getValueFromLinkedMap(currentUrlIndex);
|
||||
}
|
||||
|
||||
public Object getCurrentKey() {
|
||||
return getKeyFromDataSource(currentUrlIndex);
|
||||
}
|
||||
|
||||
public String getKeyFromDataSource(int index) {
|
||||
int currentIndex = 0;
|
||||
for (Object key : urlsMap.keySet()) {
|
||||
if (currentIndex == index) {
|
||||
return key.toString();
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getValueFromLinkedMap(int index) {
|
||||
int currentIndex = 0;
|
||||
for (Object key : urlsMap.keySet()) {
|
||||
if (currentIndex == index) {
|
||||
return urlsMap.get(key);
|
||||
}
|
||||
currentIndex++;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean containsTheUrl(Object object) {
|
||||
if (object != null) {
|
||||
return urlsMap.containsValue(object);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public JZDataSource cloneMe() {
|
||||
LinkedHashMap map = new LinkedHashMap();
|
||||
map.putAll(urlsMap);
|
||||
return new JZDataSource(map, title);
|
||||
}
|
||||
}
|
||||
47
library/src/main/java/cn/jzvd/JZMediaInterface.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package cn.jzvd;
|
||||
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.view.Surface;
|
||||
import android.view.TextureView;
|
||||
|
||||
/**
|
||||
* Created by Nathen on 2017/11/7.
|
||||
* 自定义播放器
|
||||
*/
|
||||
public abstract class JZMediaInterface implements TextureView.SurfaceTextureListener {
|
||||
|
||||
public static SurfaceTexture SAVED_SURFACE;
|
||||
public HandlerThread mMediaHandlerThread;
|
||||
public Handler mMediaHandler;
|
||||
public Handler handler;
|
||||
public Jzvd jzvd;
|
||||
|
||||
|
||||
public JZMediaInterface(Jzvd jzvd) {
|
||||
this.jzvd = jzvd;
|
||||
}
|
||||
|
||||
public abstract void start();
|
||||
|
||||
public abstract void prepare();
|
||||
|
||||
public abstract void pause();
|
||||
|
||||
public abstract boolean isPlaying();
|
||||
|
||||
public abstract void seekTo(long time);
|
||||
|
||||
public abstract void release();
|
||||
|
||||
public abstract long getCurrentPosition();
|
||||
|
||||
public abstract long getDuration();
|
||||
|
||||
public abstract void setVolume(float leftVolume, float rightVolume);
|
||||
|
||||
public abstract void setSpeed(float speed);
|
||||
|
||||
public abstract void setSurface(Surface surface);
|
||||
}
|
||||
203
library/src/main/java/cn/jzvd/JZMediaSystem.java
Normal file
@@ -0,0 +1,203 @@
|
||||
package cn.jzvd;
|
||||
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.media.PlaybackParams;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.view.Surface;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Nathen on 2017/11/8.
|
||||
* 实现系统的播放引擎
|
||||
*/
|
||||
public class JZMediaSystem extends JZMediaInterface implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnBufferingUpdateListener, MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnErrorListener, MediaPlayer.OnInfoListener, MediaPlayer.OnVideoSizeChangedListener {
|
||||
|
||||
public MediaPlayer mediaPlayer;
|
||||
|
||||
public JZMediaSystem(Jzvd jzvd) {
|
||||
super(jzvd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
release();
|
||||
mMediaHandlerThread = new HandlerThread("JZVD");
|
||||
mMediaHandlerThread.start();
|
||||
mMediaHandler = new Handler(mMediaHandlerThread.getLooper());//主线程还是非主线程,就在这里
|
||||
handler = new Handler();
|
||||
|
||||
mMediaHandler.post(() -> {
|
||||
try {
|
||||
mediaPlayer = new MediaPlayer();
|
||||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||
mediaPlayer.setLooping(jzvd.jzDataSource.looping);
|
||||
mediaPlayer.setOnPreparedListener(JZMediaSystem.this);
|
||||
mediaPlayer.setOnCompletionListener(JZMediaSystem.this);
|
||||
mediaPlayer.setOnBufferingUpdateListener(JZMediaSystem.this);
|
||||
mediaPlayer.setScreenOnWhilePlaying(true);
|
||||
mediaPlayer.setOnSeekCompleteListener(JZMediaSystem.this);
|
||||
mediaPlayer.setOnErrorListener(JZMediaSystem.this);
|
||||
mediaPlayer.setOnInfoListener(JZMediaSystem.this);
|
||||
mediaPlayer.setOnVideoSizeChangedListener(JZMediaSystem.this);
|
||||
Class<MediaPlayer> clazz = MediaPlayer.class;
|
||||
//如果不用反射,没有url和header参数的setDataSource函数
|
||||
Method method = clazz.getDeclaredMethod("setDataSource", String.class, Map.class);
|
||||
method.invoke(mediaPlayer, jzvd.jzDataSource.getCurrentUrl().toString(), jzvd.jzDataSource.headerMap);
|
||||
mediaPlayer.prepareAsync();
|
||||
mediaPlayer.setSurface(new Surface(SAVED_SURFACE));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
mMediaHandler.post(() -> mediaPlayer.start());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
mMediaHandler.post(() -> mediaPlayer.pause());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPlaying() {
|
||||
return mediaPlayer.isPlaying();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seekTo(long time) {
|
||||
mMediaHandler.post(() -> {
|
||||
try {
|
||||
mediaPlayer.seekTo((int) time);
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {//not perfect change you later
|
||||
if (mMediaHandler != null && mMediaHandlerThread != null && mediaPlayer != null) {//不知道有没有妖孽
|
||||
HandlerThread tmpHandlerThread = mMediaHandlerThread;
|
||||
MediaPlayer tmpMediaPlayer = mediaPlayer;
|
||||
JZMediaInterface.SAVED_SURFACE = null;
|
||||
|
||||
mMediaHandler.post(() -> {
|
||||
tmpMediaPlayer.setSurface(null);
|
||||
tmpMediaPlayer.release();
|
||||
tmpHandlerThread.quit();
|
||||
});
|
||||
mediaPlayer = null;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO 测试这种问题是否在threadHandler中是否正常,所有的操作mediaplayer是否不需要thread,挨个测试,是否有问题
|
||||
@Override
|
||||
public long getCurrentPosition() {
|
||||
if (mediaPlayer != null) {
|
||||
return mediaPlayer.getCurrentPosition();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDuration() {
|
||||
if (mediaPlayer != null) {
|
||||
return mediaPlayer.getDuration();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVolume(float leftVolume, float rightVolume) {
|
||||
if (mMediaHandler == null) return;
|
||||
mMediaHandler.post(() -> {
|
||||
if (mediaPlayer != null) mediaPlayer.setVolume(leftVolume, rightVolume);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpeed(float speed) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
PlaybackParams pp = mediaPlayer.getPlaybackParams();
|
||||
pp.setSpeed(speed);
|
||||
mediaPlayer.setPlaybackParams(pp);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepared(MediaPlayer mediaPlayer) {
|
||||
handler.post(() -> jzvd.onPrepared());//如果是mp3音频,走这里
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompletion(MediaPlayer mediaPlayer) {
|
||||
handler.post(() -> jzvd.onCompletion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBufferingUpdate(MediaPlayer mediaPlayer, final int percent) {
|
||||
handler.post(() -> jzvd.setBufferProgress(percent));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSeekComplete(MediaPlayer mediaPlayer) {
|
||||
handler.post(() -> jzvd.onSeekComplete());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onError(MediaPlayer mediaPlayer, final int what, final int extra) {
|
||||
handler.post(() -> jzvd.onError(what, extra));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInfo(MediaPlayer mediaPlayer, final int what, final int extra) {
|
||||
handler.post(() -> jzvd.onInfo(what, extra));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVideoSizeChanged(MediaPlayer mediaPlayer, int width, int height) {
|
||||
handler.post(() -> jzvd.onVideoSizeChanged(width, height));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSurface(Surface surface) {
|
||||
mediaPlayer.setSurface(surface);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||
if (SAVED_SURFACE == null) {
|
||||
SAVED_SURFACE = surface;
|
||||
prepare();
|
||||
} else {
|
||||
jzvd.textureView.setSurfaceTexture(SAVED_SURFACE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
|
||||
|
||||
}
|
||||
}
|
||||
161
library/src/main/java/cn/jzvd/JZTextureView.java
Normal file
@@ -0,0 +1,161 @@
|
||||
package cn.jzvd;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* <p>参照Android系统的VideoView的onMeasure方法
|
||||
* <br>注意!relativelayout中无法全屏,要嵌套一个linearlayout</p>
|
||||
* <p>Referring Android system Video View of onMeasure method
|
||||
* <br>NOTE! Can not fullscreen relativelayout, to nest a linearlayout</p>
|
||||
* Created by Nathen
|
||||
* On 2016/06/02 00:01
|
||||
*/
|
||||
public class JZTextureView extends TextureView {
|
||||
protected static final String TAG = "JZResizeTextureView";
|
||||
|
||||
public int currentVideoWidth = 0;
|
||||
public int currentVideoHeight = 0;
|
||||
|
||||
public JZTextureView(Context context) {
|
||||
super(context);
|
||||
currentVideoWidth = 0;
|
||||
currentVideoHeight = 0;
|
||||
}
|
||||
|
||||
public JZTextureView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
currentVideoWidth = 0;
|
||||
currentVideoHeight = 0;
|
||||
}
|
||||
|
||||
public void setVideoSize(int currentVideoWidth, int currentVideoHeight) {
|
||||
if (this.currentVideoWidth != currentVideoWidth || this.currentVideoHeight != currentVideoHeight) {
|
||||
this.currentVideoWidth = currentVideoWidth;
|
||||
this.currentVideoHeight = currentVideoHeight;
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotation(float rotation) {
|
||||
if (rotation != getRotation()) {
|
||||
super.setRotation(rotation);
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
Log.i(TAG, "onMeasure " + " [" + this.hashCode() + "] ");
|
||||
int viewRotation = (int) getRotation();
|
||||
int videoWidth = currentVideoWidth;
|
||||
int videoHeight = currentVideoHeight;
|
||||
|
||||
|
||||
int parentHeight = ((View) getParent()).getMeasuredHeight();
|
||||
int parentWidth = ((View) getParent()).getMeasuredWidth();
|
||||
if (parentWidth != 0 && parentHeight != 0 && videoWidth != 0 && videoHeight != 0) {
|
||||
if (Jzvd.VIDEO_IMAGE_DISPLAY_TYPE == Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_PARENT) {
|
||||
if (viewRotation == 90 || viewRotation == 270) {
|
||||
int tempSize = parentWidth;
|
||||
parentWidth = parentHeight;
|
||||
parentHeight = tempSize;
|
||||
}
|
||||
/**强制充满**/
|
||||
videoHeight = videoWidth * parentHeight / parentWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果判断成立,则说明显示的TextureView和本身的位置是有90度的旋转的,所以需要交换宽高参数。
|
||||
if (viewRotation == 90 || viewRotation == 270) {
|
||||
int tempMeasureSpec = widthMeasureSpec;
|
||||
widthMeasureSpec = heightMeasureSpec;
|
||||
heightMeasureSpec = tempMeasureSpec;
|
||||
}
|
||||
|
||||
int width = getDefaultSize(videoWidth, widthMeasureSpec);
|
||||
int height = getDefaultSize(videoHeight, heightMeasureSpec);
|
||||
if (videoWidth > 0 && videoHeight > 0) {
|
||||
|
||||
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
|
||||
|
||||
Log.i(TAG, "widthMeasureSpec [" + MeasureSpec.toString(widthMeasureSpec) + "]");
|
||||
Log.i(TAG, "heightMeasureSpec [" + MeasureSpec.toString(heightMeasureSpec) + "]");
|
||||
|
||||
if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) {
|
||||
// the size is fixed
|
||||
width = widthSpecSize;
|
||||
height = heightSpecSize;
|
||||
// for compatibility, we adjust size based on aspect ratio
|
||||
if (videoWidth * height < width * videoHeight) {
|
||||
width = height * videoWidth / videoHeight;
|
||||
} else if (videoWidth * height > width * videoHeight) {
|
||||
height = width * videoHeight / videoWidth;
|
||||
}
|
||||
} else if (widthSpecMode == MeasureSpec.EXACTLY) {
|
||||
// only the width is fixed, adjust the height to match aspect ratio if possible
|
||||
width = widthSpecSize;
|
||||
height = width * videoHeight / videoWidth;
|
||||
if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
|
||||
// couldn't match aspect ratio within the constraints
|
||||
height = heightSpecSize;
|
||||
width = height * videoWidth / videoHeight;
|
||||
}
|
||||
} else if (heightSpecMode == MeasureSpec.EXACTLY) {
|
||||
// only the height is fixed, adjust the width to match aspect ratio if possible
|
||||
height = heightSpecSize;
|
||||
width = height * videoWidth / videoHeight;
|
||||
if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
|
||||
// couldn't match aspect ratio within the constraints
|
||||
width = widthSpecSize;
|
||||
height = width * videoHeight / videoWidth;
|
||||
}
|
||||
} else {
|
||||
// neither the width nor the height are fixed, try to use actual video size
|
||||
width = videoWidth;
|
||||
height = videoHeight;
|
||||
if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
|
||||
// too tall, decrease both width and height
|
||||
height = heightSpecSize;
|
||||
width = height * videoWidth / videoHeight;
|
||||
}
|
||||
if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
|
||||
// too wide, decrease both width and height
|
||||
width = widthSpecSize;
|
||||
height = width * videoHeight / videoWidth;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no size yet, just adopt the given spec sizes
|
||||
}
|
||||
if (parentWidth != 0 && parentHeight != 0 && videoWidth != 0 && videoHeight != 0) {
|
||||
if (Jzvd.VIDEO_IMAGE_DISPLAY_TYPE == Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_ORIGINAL) {
|
||||
/**原图**/
|
||||
height = videoHeight;
|
||||
width = videoWidth;
|
||||
} else if (Jzvd.VIDEO_IMAGE_DISPLAY_TYPE == Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_SCROP) {
|
||||
if (viewRotation == 90 || viewRotation == 270) {
|
||||
int tempSize = parentWidth;
|
||||
parentWidth = parentHeight;
|
||||
parentHeight = tempSize;
|
||||
}
|
||||
/**充满剪切**/
|
||||
if (((double) videoHeight / videoWidth) > ((double) parentHeight / parentWidth)) {
|
||||
height = (int) (((double) parentWidth / (double) width * (double) height));
|
||||
width = parentWidth;
|
||||
} else if (((double) videoHeight / videoWidth) < ((double) parentHeight / parentWidth)) {
|
||||
width = (int) (((double) parentHeight / (double) height * (double) width));
|
||||
height = parentHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
setMeasuredDimension(width, height);
|
||||
}
|
||||
}
|
||||
199
library/src/main/java/cn/jzvd/JZUtils.java
Normal file
@@ -0,0 +1,199 @@
|
||||
package cn.jzvd;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Resources;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkInfo;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.util.Formatter;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Created by Nathen
|
||||
* On 2016/02/21 12:25
|
||||
*/
|
||||
public class JZUtils {
|
||||
public static final String TAG = "JZVD";
|
||||
public static int SYSTEM_UI = 0;
|
||||
|
||||
public static String stringForTime(long timeMs) {
|
||||
if (timeMs <= 0 || timeMs >= 24 * 60 * 60 * 1000) {
|
||||
return "00:00";
|
||||
}
|
||||
long totalSeconds = timeMs / 1000;
|
||||
int seconds = (int) (totalSeconds % 60);
|
||||
int minutes = (int) ((totalSeconds / 60) % 60);
|
||||
int hours = (int) (totalSeconds / 3600);
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
Formatter mFormatter = new Formatter(stringBuilder, Locale.getDefault());
|
||||
if (hours > 0) {
|
||||
return mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString();
|
||||
} else {
|
||||
return mFormatter.format("%02d:%02d", minutes, seconds).toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method requires the caller to hold the permission ACCESS_NETWORK_STATE.
|
||||
*
|
||||
* @param context context
|
||||
* @return if wifi is connected,return true
|
||||
*/
|
||||
public static boolean isWifiConnected(Context context) {
|
||||
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
|
||||
return networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get activity from context object
|
||||
*
|
||||
* @param context context
|
||||
* @return object of Activity or null if it is not Activity
|
||||
*/
|
||||
public static Activity scanForActivity(Context context) {
|
||||
if (context == null) return null;
|
||||
|
||||
if (context instanceof Activity) {
|
||||
return (Activity) context;
|
||||
} else if (context instanceof ContextWrapper) {
|
||||
return scanForActivity(((ContextWrapper) context).getBaseContext());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void setRequestedOrientation(Context context, int orientation) {
|
||||
if (JZUtils.scanForActivity(context) != null) {
|
||||
JZUtils.scanForActivity(context).setRequestedOrientation(
|
||||
orientation);
|
||||
} else {
|
||||
JZUtils.scanForActivity(context).setRequestedOrientation(
|
||||
orientation);
|
||||
}
|
||||
}
|
||||
|
||||
public static Window getWindow(Context context) {
|
||||
if (JZUtils.scanForActivity(context) != null) {
|
||||
return JZUtils.scanForActivity(context).getWindow();
|
||||
} else {
|
||||
return JZUtils.scanForActivity(context).getWindow();
|
||||
}
|
||||
}
|
||||
|
||||
public static int dip2px(Context context, float dpValue) {
|
||||
final float scale = context.getResources().getDisplayMetrics().density;
|
||||
return (int) (dpValue * scale + 0.5f);
|
||||
}
|
||||
|
||||
public static void saveProgress(Context context, Object url, long progress) {
|
||||
if (!Jzvd.SAVE_PROGRESS) return;
|
||||
Log.i(TAG, "saveProgress: " + progress);
|
||||
if (progress < 5000) {
|
||||
progress = 0;
|
||||
}
|
||||
SharedPreferences spn = context.getSharedPreferences("JZVD_PROGRESS",
|
||||
Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = spn.edit();
|
||||
editor.putLong("newVersion:" + url.toString(), progress).apply();
|
||||
}
|
||||
|
||||
public static long getSavedProgress(Context context, Object url) {
|
||||
if (!Jzvd.SAVE_PROGRESS) return 0;
|
||||
SharedPreferences spn = context.getSharedPreferences("JZVD_PROGRESS",
|
||||
Context.MODE_PRIVATE);
|
||||
return spn.getLong("newVersion:" + url.toString(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* if url == null, clear all progress
|
||||
*
|
||||
* @param context context
|
||||
* @param url if url!=null clear this url progress
|
||||
*/
|
||||
public static void clearSavedProgress(Context context, Object url) {
|
||||
if (url == null) {
|
||||
SharedPreferences spn = context.getSharedPreferences("JZVD_PROGRESS",
|
||||
Context.MODE_PRIVATE);
|
||||
spn.edit().clear().apply();
|
||||
} else {
|
||||
SharedPreferences spn = context.getSharedPreferences("JZVD_PROGRESS",
|
||||
Context.MODE_PRIVATE);
|
||||
spn.edit().putLong("newVersion:" + url.toString(), 0).apply();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
public static void showStatusBar(Context context) {
|
||||
if (Jzvd.TOOL_BAR_EXIST) {
|
||||
JZUtils.getWindow(context).clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
//如果是沉浸式的,全屏前就没有状态栏
|
||||
@SuppressLint("RestrictedApi")
|
||||
public static void hideStatusBar(Context context) {
|
||||
if (Jzvd.TOOL_BAR_EXIST) {
|
||||
JZUtils.getWindow(context).setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public static void hideSystemUI(Context context) {
|
||||
int uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
|
||||
;
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
|
||||
uiOptions |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
|
||||
}
|
||||
SYSTEM_UI = JZUtils.getWindow(context).getDecorView().getSystemUiVisibility();
|
||||
JZUtils.getWindow(context).getDecorView().setSystemUiVisibility(uiOptions);
|
||||
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public static void showSystemUI(Context context) {
|
||||
int uiOptions = View.SYSTEM_UI_FLAG_VISIBLE;
|
||||
JZUtils.getWindow(context).getDecorView().setSystemUiVisibility(SYSTEM_UI);
|
||||
}
|
||||
|
||||
//获取状态栏的高度
|
||||
public static int getStatusBarHeight(Context context) {
|
||||
Resources resources = context.getResources();
|
||||
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
|
||||
int height = resources.getDimensionPixelSize(resourceId);
|
||||
return height;
|
||||
}
|
||||
|
||||
//获取NavigationBar的高度
|
||||
public static int getNavigationBarHeight(Context context) {
|
||||
boolean var1 = ViewConfiguration.get(context).hasPermanentMenuKey();
|
||||
int var2;
|
||||
return (var2 = context.getResources().getIdentifier("navigation_bar_height", "dimen", "android")) > 0 && !var1 ? context.getResources().getDimensionPixelSize(var2) : 0;
|
||||
}
|
||||
|
||||
//获取屏幕的宽度
|
||||
public static int getScreenWidth(Context context) {
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
return dm.widthPixels;
|
||||
}
|
||||
|
||||
//获取屏幕的高度
|
||||
public static int getScreenHeight(Context context) {
|
||||
DisplayMetrics dm = context.getResources().getDisplayMetrics();
|
||||
return dm.heightPixels;
|
||||
}
|
||||
|
||||
}
|
||||
1135
library/src/main/java/cn/jzvd/Jzvd.java
Normal file
979
library/src/main/java/cn/jzvd/JzvdStd.java
Normal file
@@ -0,0 +1,979 @@
|
||||
package cn.jzvd;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Color;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Date;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* Created by Nathen
|
||||
* On 2016/04/18 16:15
|
||||
*/
|
||||
public class JzvdStd extends Jzvd {
|
||||
|
||||
public static long LAST_GET_BATTERYLEVEL_TIME = 0;
|
||||
public static int LAST_GET_BATTERYLEVEL_PERCENT = 70;
|
||||
protected static Timer DISMISS_CONTROL_VIEW_TIMER;
|
||||
|
||||
public ImageView backButton;
|
||||
public ProgressBar bottomProgressBar, loadingProgressBar;
|
||||
public TextView titleTextView;
|
||||
public ImageView posterImageView;
|
||||
public ImageView tinyBackImageView;
|
||||
public LinearLayout batteryTimeLayout;
|
||||
public ImageView batteryLevel;
|
||||
public TextView videoCurrentTime;
|
||||
public TextView replayTextView;
|
||||
public TextView clarity;
|
||||
public PopupWindow clarityPopWindow;
|
||||
public TextView mRetryBtn;
|
||||
public LinearLayout mRetryLayout;
|
||||
public BroadcastReceiver battertReceiver = new BroadcastReceiver() {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
|
||||
int level = intent.getIntExtra("level", 0);
|
||||
int scale = intent.getIntExtra("scale", 100);
|
||||
int percent = level * 100 / scale;
|
||||
LAST_GET_BATTERYLEVEL_PERCENT = percent;
|
||||
setBatteryLevel();
|
||||
try {
|
||||
jzvdContext.unregisterReceiver(battertReceiver);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
protected DismissControlViewTimerTask mDismissControlViewTimerTask;
|
||||
protected Dialog mProgressDialog;
|
||||
protected ProgressBar mDialogProgressBar;
|
||||
protected TextView mDialogSeekTime;
|
||||
protected TextView mDialogTotalTime;
|
||||
protected ImageView mDialogIcon;
|
||||
protected Dialog mVolumeDialog;
|
||||
protected ProgressBar mDialogVolumeProgressBar;
|
||||
protected TextView mDialogVolumeTextView;
|
||||
protected ImageView mDialogVolumeImageView;
|
||||
protected Dialog mBrightnessDialog;
|
||||
protected ProgressBar mDialogBrightnessProgressBar;
|
||||
protected TextView mDialogBrightnessTextView;
|
||||
protected boolean mIsWifi;
|
||||
public BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
|
||||
boolean isWifi = JZUtils.isWifiConnected(context);
|
||||
if (mIsWifi == isWifi) return;
|
||||
mIsWifi = isWifi;
|
||||
if (!mIsWifi && !WIFI_TIP_DIALOG_SHOWED && state == STATE_PLAYING) {
|
||||
startButton.performClick();
|
||||
showWifiDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
protected ArrayDeque<Runnable> delayTask = new ArrayDeque<>();
|
||||
|
||||
public JzvdStd(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public JzvdStd(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
super.init(context);
|
||||
batteryTimeLayout = findViewById(R.id.battery_time_layout);
|
||||
bottomProgressBar = findViewById(R.id.bottom_progress);
|
||||
titleTextView = findViewById(R.id.title);
|
||||
backButton = findViewById(R.id.back);
|
||||
posterImageView = findViewById(R.id.poster);
|
||||
loadingProgressBar = findViewById(R.id.loading);
|
||||
tinyBackImageView = findViewById(R.id.back_tiny);
|
||||
batteryLevel = findViewById(R.id.battery_level);
|
||||
videoCurrentTime = findViewById(R.id.video_current_time);
|
||||
replayTextView = findViewById(R.id.replay_text);
|
||||
clarity = findViewById(R.id.clarity);
|
||||
mRetryBtn = findViewById(R.id.retry_btn);
|
||||
mRetryLayout = findViewById(R.id.retry_layout);
|
||||
|
||||
if (batteryTimeLayout == null) {
|
||||
batteryTimeLayout = new LinearLayout(context);
|
||||
}
|
||||
if (bottomProgressBar == null) {
|
||||
bottomProgressBar = new ProgressBar(context);
|
||||
}
|
||||
if (titleTextView == null) {
|
||||
titleTextView = new TextView(context);
|
||||
}
|
||||
if (backButton == null) {
|
||||
backButton = new ImageView(context);
|
||||
}
|
||||
if (posterImageView == null) {
|
||||
posterImageView = new ImageView(context);
|
||||
}
|
||||
if (loadingProgressBar == null) {
|
||||
loadingProgressBar = new ProgressBar(context);
|
||||
}
|
||||
if (tinyBackImageView == null) {
|
||||
tinyBackImageView = new ImageView(context);
|
||||
}
|
||||
if (batteryLevel == null) {
|
||||
batteryLevel = new ImageView(context);
|
||||
}
|
||||
if (videoCurrentTime == null) {
|
||||
videoCurrentTime = new TextView(context);
|
||||
}
|
||||
if (replayTextView == null) {
|
||||
replayTextView = new TextView(context);
|
||||
}
|
||||
if (clarity == null) {
|
||||
clarity = new TextView(context);
|
||||
}
|
||||
if (mRetryBtn == null) {
|
||||
mRetryBtn = new TextView(context);
|
||||
}
|
||||
if (mRetryLayout == null) {
|
||||
mRetryLayout = new LinearLayout(context);
|
||||
}
|
||||
|
||||
posterImageView.setOnClickListener(this);
|
||||
backButton.setOnClickListener(this);
|
||||
tinyBackImageView.setOnClickListener(this);
|
||||
clarity.setOnClickListener(this);
|
||||
mRetryBtn.setOnClickListener(this);
|
||||
}
|
||||
|
||||
public void setUp(JZDataSource jzDataSource, int screen, Class mediaInterfaceClass) {
|
||||
if ((System.currentTimeMillis() - gobakFullscreenTime) < 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((System.currentTimeMillis() - gotoFullscreenTime) < 200) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
super.setUp(jzDataSource, screen, mediaInterfaceClass);
|
||||
titleTextView.setText(jzDataSource.title);
|
||||
setScreen(screen);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeUrl(JZDataSource jzDataSource, long seekToInAdvance) {
|
||||
super.changeUrl(jzDataSource, seekToInAdvance);
|
||||
titleTextView.setText(jzDataSource.title);
|
||||
}
|
||||
|
||||
public void changeStartButtonSize(int size) {
|
||||
ViewGroup.LayoutParams lp = startButton.getLayoutParams();
|
||||
lp.height = size;
|
||||
lp.width = size;
|
||||
lp = loadingProgressBar.getLayoutParams();
|
||||
lp.height = size;
|
||||
lp.width = size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLayoutId() {
|
||||
return R.layout.jz_layout_std;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateNormal() {
|
||||
super.onStateNormal();
|
||||
changeUiToNormal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatePreparing() {
|
||||
super.onStatePreparing();
|
||||
changeUiToPreparing();
|
||||
}
|
||||
|
||||
public void onStatePreparingPlaying() {
|
||||
super.onStatePreparingPlaying();
|
||||
changeUIToPreparingPlaying();
|
||||
}
|
||||
|
||||
public void onStatePreparingChangeUrl() {
|
||||
super.onStatePreparingChangeUrl();
|
||||
changeUIToPreparingChangeUrl();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatePlaying() {
|
||||
super.onStatePlaying();
|
||||
changeUiToPlayingClear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatePause() {
|
||||
super.onStatePause();
|
||||
changeUiToPauseShow();
|
||||
cancelDismissControlViewTimer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateError() {
|
||||
super.onStateError();
|
||||
changeUiToError();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateAutoComplete() {
|
||||
super.onStateAutoComplete();
|
||||
changeUiToComplete();
|
||||
cancelDismissControlViewTimer();
|
||||
bottomProgressBar.setProgress(100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startVideo() {
|
||||
super.startVideo();
|
||||
registerWifiListener(getApplicationContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* 双击
|
||||
*/
|
||||
protected GestureDetector gestureDetector = new GestureDetector(getContext().getApplicationContext(), new GestureDetector.SimpleOnGestureListener() {
|
||||
@Override
|
||||
public boolean onDoubleTap(MotionEvent e) {
|
||||
if (state == STATE_PLAYING || state == STATE_PAUSE) {
|
||||
Log.d(TAG, "doublClick [" + this.hashCode() + "] ");
|
||||
startButton.performClick();
|
||||
}
|
||||
return super.onDoubleTap(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(MotionEvent e) {
|
||||
if (!mChangePosition && !mChangeVolume) {
|
||||
onClickUiToggle();
|
||||
}
|
||||
return super.onSingleTapConfirmed(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent e) {
|
||||
super.onLongPress(e);
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
int id = v.getId();
|
||||
if (id == R.id.surface_container) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
startDismissControlViewTimer();
|
||||
if (mChangePosition) {
|
||||
long duration = getDuration();
|
||||
int progress = (int) (mSeekTimePosition * 100 / (duration == 0 ? 1 : duration));
|
||||
bottomProgressBar.setProgress(progress);
|
||||
}
|
||||
break;
|
||||
}
|
||||
gestureDetector.onTouchEvent(event);
|
||||
} else if (id == R.id.bottom_seek_progress) {
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
cancelDismissControlViewTimer();
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
startDismissControlViewTimer();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onTouch(v, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
super.onClick(v);
|
||||
int i = v.getId();
|
||||
if (i == R.id.poster) {
|
||||
clickPoster();
|
||||
} else if (i == R.id.surface_container) {
|
||||
clickSurfaceContainer();
|
||||
if (clarityPopWindow != null) {
|
||||
clarityPopWindow.dismiss();
|
||||
}
|
||||
} else if (i == R.id.back) {
|
||||
clickBack();
|
||||
} else if (i == R.id.back_tiny) {
|
||||
clickBackTiny();
|
||||
} else if (i == R.id.clarity) {
|
||||
clickClarity();
|
||||
} else if (i == R.id.retry_btn) {
|
||||
clickRetryBtn();
|
||||
}
|
||||
}
|
||||
|
||||
protected void clickRetryBtn() {
|
||||
if (jzDataSource.urlsMap.isEmpty() || jzDataSource.getCurrentUrl() == null) {
|
||||
Toast.makeText(jzvdContext, getResources().getString(R.string.no_url), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if (!jzDataSource.getCurrentUrl().toString().startsWith("file") && !
|
||||
jzDataSource.getCurrentUrl().toString().startsWith("/") &&
|
||||
!JZUtils.isWifiConnected(jzvdContext) && !WIFI_TIP_DIALOG_SHOWED) {
|
||||
showWifiDialog();
|
||||
return;
|
||||
}
|
||||
seekToInAdvance = mCurrentPosition;
|
||||
startVideo();
|
||||
}
|
||||
|
||||
protected void clickClarity() {
|
||||
onCLickUiToggleToClear();
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) jzvdContext
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
final LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.jz_layout_clarity, null);
|
||||
|
||||
OnClickListener mQualityListener = v1 -> {
|
||||
int index = (int) v1.getTag();
|
||||
|
||||
// this.seekToInAdvance = getCurrentPositionWhenPlaying();
|
||||
jzDataSource.currentUrlIndex = index;
|
||||
// onStatePreparingChangeUrl();
|
||||
|
||||
changeUrl(jzDataSource, getCurrentPositionWhenPlaying());
|
||||
|
||||
clarity.setText(jzDataSource.getCurrentKey().toString());
|
||||
for (int j = 0; j < layout.getChildCount(); j++) {//设置点击之后的颜色
|
||||
if (j == jzDataSource.currentUrlIndex) {
|
||||
((TextView) layout.getChildAt(j)).setTextColor(Color.parseColor("#fff85959"));
|
||||
} else {
|
||||
((TextView) layout.getChildAt(j)).setTextColor(Color.parseColor("#ffffff"));
|
||||
}
|
||||
}
|
||||
if (clarityPopWindow != null) {
|
||||
clarityPopWindow.dismiss();
|
||||
}
|
||||
};
|
||||
|
||||
for (int j = 0; j < jzDataSource.urlsMap.size(); j++) {
|
||||
String key = jzDataSource.getKeyFromDataSource(j);
|
||||
TextView clarityItem = (TextView) View.inflate(jzvdContext, R.layout.jz_layout_clarity_item, null);
|
||||
clarityItem.setText(key);
|
||||
clarityItem.setTag(j);
|
||||
layout.addView(clarityItem, j);
|
||||
clarityItem.setOnClickListener(mQualityListener);
|
||||
if (j == jzDataSource.currentUrlIndex) {
|
||||
clarityItem.setTextColor(Color.parseColor("#fff85959"));
|
||||
}
|
||||
}
|
||||
|
||||
clarityPopWindow = new PopupWindow(layout, JZUtils.dip2px(jzvdContext, 240), LayoutParams.MATCH_PARENT, true);
|
||||
clarityPopWindow.setContentView(layout);
|
||||
clarityPopWindow.setAnimationStyle(R.style.pop_animation);
|
||||
clarityPopWindow.showAtLocation(textureViewContainer, Gravity.END, 0, 0);
|
||||
// int offsetX = clarity.getMeasuredWidth() / 3;
|
||||
// int offsetY = clarity.getMeasuredHeight() / 3;
|
||||
// clarityPopWindow.update(clarity, -offsetX, -offsetY, Math.round(layout.getMeasuredWidth() * 2), layout.getMeasuredHeight());
|
||||
}
|
||||
|
||||
protected void clickBackTiny() {
|
||||
clearFloatScreen();
|
||||
}
|
||||
|
||||
protected void clickBack() {
|
||||
backPress();
|
||||
}
|
||||
|
||||
protected void clickSurfaceContainer() {
|
||||
startDismissControlViewTimer();
|
||||
}
|
||||
|
||||
protected void clickPoster() {
|
||||
if (jzDataSource == null || jzDataSource.urlsMap.isEmpty() || jzDataSource.getCurrentUrl() == null) {
|
||||
Toast.makeText(jzvdContext, getResources().getString(R.string.no_url), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
if (state == STATE_NORMAL) {
|
||||
if (!jzDataSource.getCurrentUrl().toString().startsWith("file") &&
|
||||
!jzDataSource.getCurrentUrl().toString().startsWith("/") &&
|
||||
!JZUtils.isWifiConnected(jzvdContext) && !WIFI_TIP_DIALOG_SHOWED) {
|
||||
showWifiDialog();
|
||||
return;
|
||||
}
|
||||
startVideo();
|
||||
} else if (state == STATE_AUTO_COMPLETE) {
|
||||
onClickUiToggle();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScreenNormal() {
|
||||
super.setScreenNormal();
|
||||
fullscreenButton.setImageResource(R.drawable.jz_enlarge);
|
||||
backButton.setVisibility(View.GONE);
|
||||
tinyBackImageView.setVisibility(View.INVISIBLE);
|
||||
changeStartButtonSize((int) getResources().getDimension(R.dimen.jz_start_button_w_h_normal));
|
||||
batteryTimeLayout.setVisibility(View.GONE);
|
||||
clarity.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScreenFullscreen() {
|
||||
super.setScreenFullscreen();
|
||||
//进入全屏之后要保证原来的播放状态和ui状态不变,改变个别的ui
|
||||
fullscreenButton.setImageResource(R.drawable.jz_shrink);
|
||||
backButton.setVisibility(View.VISIBLE);
|
||||
tinyBackImageView.setVisibility(View.INVISIBLE);
|
||||
batteryTimeLayout.setVisibility(View.VISIBLE);
|
||||
if (jzDataSource.urlsMap.size() == 1) {
|
||||
clarity.setVisibility(GONE);
|
||||
} else {
|
||||
clarity.setText(jzDataSource.getCurrentKey().toString());
|
||||
clarity.setVisibility(View.VISIBLE);
|
||||
}
|
||||
changeStartButtonSize((int) getResources().getDimension(R.dimen.jz_start_button_w_h_fullscreen));
|
||||
setSystemTimeAndBattery();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setScreenTiny() {
|
||||
super.setScreenTiny();
|
||||
tinyBackImageView.setVisibility(View.VISIBLE);
|
||||
setAllControlsVisiblity(View.INVISIBLE, View.INVISIBLE, View.INVISIBLE,
|
||||
View.INVISIBLE, View.INVISIBLE, View.INVISIBLE, View.INVISIBLE);
|
||||
batteryTimeLayout.setVisibility(View.GONE);
|
||||
clarity.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showWifiDialog() {
|
||||
super.showWifiDialog();
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(jzvdContext);
|
||||
builder.setMessage(getResources().getString(R.string.tips_not_wifi));
|
||||
builder.setPositiveButton(getResources().getString(R.string.tips_not_wifi_confirm), (dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
WIFI_TIP_DIALOG_SHOWED = true;
|
||||
if (state == STATE_PAUSE) {
|
||||
startButton.performClick();
|
||||
} else {
|
||||
startVideo();
|
||||
}
|
||||
|
||||
});
|
||||
builder.setNegativeButton(getResources().getString(R.string.tips_not_wifi_cancel), (dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
releaseAllVideos();
|
||||
clearFloatScreen();
|
||||
});
|
||||
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog) {
|
||||
dialog.dismiss();
|
||||
releaseAllVideos();
|
||||
clearFloatScreen();
|
||||
}
|
||||
});
|
||||
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
super.onStartTrackingTouch(seekBar);
|
||||
cancelDismissControlViewTimer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
super.onStopTrackingTouch(seekBar);
|
||||
startDismissControlViewTimer();
|
||||
}
|
||||
|
||||
public void onClickUiToggle() {//这是事件
|
||||
if (bottomContainer.getVisibility() != View.VISIBLE) {
|
||||
setSystemTimeAndBattery();
|
||||
clarity.setText(jzDataSource.getCurrentKey().toString());
|
||||
}
|
||||
if (state == STATE_PREPARING) {
|
||||
changeUiToPreparing();
|
||||
if (bottomContainer.getVisibility() == View.VISIBLE) {
|
||||
} else {
|
||||
setSystemTimeAndBattery();
|
||||
}
|
||||
} else if (state == STATE_PLAYING) {
|
||||
if (bottomContainer.getVisibility() == View.VISIBLE) {
|
||||
changeUiToPlayingClear();
|
||||
} else {
|
||||
changeUiToPlayingShow();
|
||||
}
|
||||
} else if (state == STATE_PAUSE) {
|
||||
if (bottomContainer.getVisibility() == View.VISIBLE) {
|
||||
changeUiToPauseClear();
|
||||
} else {
|
||||
changeUiToPauseShow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setSystemTimeAndBattery() {
|
||||
SimpleDateFormat dateFormater = new SimpleDateFormat("HH:mm");
|
||||
Date date = new Date();
|
||||
videoCurrentTime.setText(dateFormater.format(date));
|
||||
if ((System.currentTimeMillis() - LAST_GET_BATTERYLEVEL_TIME) > 30000) {
|
||||
LAST_GET_BATTERYLEVEL_TIME = System.currentTimeMillis();
|
||||
jzvdContext.registerReceiver(
|
||||
battertReceiver,
|
||||
new IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
||||
);
|
||||
} else {
|
||||
setBatteryLevel();
|
||||
}
|
||||
}
|
||||
|
||||
public void setBatteryLevel() {
|
||||
int percent = LAST_GET_BATTERYLEVEL_PERCENT;
|
||||
if (percent < 15) {
|
||||
batteryLevel.setBackgroundResource(R.drawable.jz_battery_level_10);
|
||||
} else if (percent >= 15 && percent < 40) {
|
||||
batteryLevel.setBackgroundResource(R.drawable.jz_battery_level_30);
|
||||
} else if (percent >= 40 && percent < 60) {
|
||||
batteryLevel.setBackgroundResource(R.drawable.jz_battery_level_50);
|
||||
} else if (percent >= 60 && percent < 80) {
|
||||
batteryLevel.setBackgroundResource(R.drawable.jz_battery_level_70);
|
||||
} else if (percent >= 80 && percent < 95) {
|
||||
batteryLevel.setBackgroundResource(R.drawable.jz_battery_level_90);
|
||||
} else if (percent >= 95 && percent <= 100) {
|
||||
batteryLevel.setBackgroundResource(R.drawable.jz_battery_level_100);
|
||||
}
|
||||
}
|
||||
|
||||
//** 和onClickUiToggle重复,要干掉
|
||||
public void onCLickUiToggleToClear() {
|
||||
if (state == STATE_PREPARING) {
|
||||
if (bottomContainer.getVisibility() == View.VISIBLE) {
|
||||
changeUiToPreparing();
|
||||
} else {
|
||||
}
|
||||
} else if (state == STATE_PLAYING) {
|
||||
if (bottomContainer.getVisibility() == View.VISIBLE) {
|
||||
changeUiToPlayingClear();
|
||||
} else {
|
||||
}
|
||||
} else if (state == STATE_PAUSE) {
|
||||
if (bottomContainer.getVisibility() == View.VISIBLE) {
|
||||
changeUiToPauseClear();
|
||||
} else {
|
||||
}
|
||||
} else if (state == STATE_AUTO_COMPLETE) {
|
||||
if (bottomContainer.getVisibility() == View.VISIBLE) {
|
||||
changeUiToComplete();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(int progress, long position, long duration) {
|
||||
super.onProgress(progress, position, duration);
|
||||
if (progress != 0) bottomProgressBar.setProgress(progress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBufferProgress(int bufferProgress) {
|
||||
super.setBufferProgress(bufferProgress);
|
||||
if (bufferProgress != 0) bottomProgressBar.setSecondaryProgress(bufferProgress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetProgressAndTime() {
|
||||
super.resetProgressAndTime();
|
||||
bottomProgressBar.setProgress(0);
|
||||
bottomProgressBar.setSecondaryProgress(0);
|
||||
}
|
||||
|
||||
public void changeUiToNormal() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.VISIBLE, View.INVISIBLE, View.VISIBLE,
|
||||
View.INVISIBLE, View.VISIBLE, View.INVISIBLE, View.INVISIBLE);
|
||||
updateStartImage();
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void changeUiToPreparing() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.INVISIBLE, View.INVISIBLE, View.INVISIBLE,
|
||||
View.VISIBLE, View.VISIBLE, View.INVISIBLE, View.INVISIBLE);
|
||||
updateStartImage();
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void changeUIToPreparingPlaying() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.VISIBLE, View.VISIBLE, View.INVISIBLE,
|
||||
View.VISIBLE, View.INVISIBLE, View.INVISIBLE, View.INVISIBLE);
|
||||
updateStartImage();
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void changeUIToPreparingChangeUrl() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.INVISIBLE, View.INVISIBLE, View.INVISIBLE,
|
||||
View.VISIBLE, View.VISIBLE, View.INVISIBLE, View.INVISIBLE);
|
||||
updateStartImage();
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void changeUiToPlayingShow() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.VISIBLE, View.VISIBLE, View.VISIBLE,
|
||||
View.INVISIBLE, View.INVISIBLE, View.INVISIBLE, View.INVISIBLE);
|
||||
updateStartImage();
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void changeUiToPlayingClear() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.INVISIBLE, View.INVISIBLE, View.INVISIBLE,
|
||||
View.INVISIBLE, View.INVISIBLE, View.VISIBLE, View.INVISIBLE);
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void changeUiToPauseShow() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.VISIBLE, View.VISIBLE, View.VISIBLE,
|
||||
View.INVISIBLE, View.INVISIBLE, View.INVISIBLE, View.INVISIBLE);
|
||||
updateStartImage();
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void changeUiToPauseClear() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.INVISIBLE, View.INVISIBLE, View.INVISIBLE,
|
||||
View.INVISIBLE, View.INVISIBLE, View.VISIBLE, View.INVISIBLE);
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void changeUiToComplete() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.VISIBLE, View.INVISIBLE, View.VISIBLE,
|
||||
View.INVISIBLE, View.VISIBLE, View.INVISIBLE, View.INVISIBLE);
|
||||
updateStartImage();
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void changeUiToError() {
|
||||
switch (screen) {
|
||||
case SCREEN_NORMAL:
|
||||
setAllControlsVisiblity(View.INVISIBLE, View.INVISIBLE, View.VISIBLE,
|
||||
View.INVISIBLE, View.INVISIBLE, View.INVISIBLE, View.VISIBLE);
|
||||
updateStartImage();
|
||||
break;
|
||||
case SCREEN_FULLSCREEN:
|
||||
setAllControlsVisiblity(View.VISIBLE, View.INVISIBLE, View.VISIBLE,
|
||||
View.INVISIBLE, View.INVISIBLE, View.INVISIBLE, View.VISIBLE);
|
||||
updateStartImage();
|
||||
break;
|
||||
case SCREEN_TINY:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setAllControlsVisiblity(int topCon, int bottomCon, int startBtn, int loadingPro,
|
||||
int posterImg, int bottomPro, int retryLayout) {
|
||||
topContainer.setVisibility(topCon);
|
||||
bottomContainer.setVisibility(bottomCon);
|
||||
startButton.setVisibility(startBtn);
|
||||
loadingProgressBar.setVisibility(loadingPro);
|
||||
posterImageView.setVisibility(posterImg);
|
||||
bottomProgressBar.setVisibility(bottomPro);
|
||||
mRetryLayout.setVisibility(retryLayout);
|
||||
}
|
||||
|
||||
public void updateStartImage() {
|
||||
if (state == STATE_PLAYING) {
|
||||
startButton.setVisibility(VISIBLE);
|
||||
startButton.setImageResource(R.drawable.jz_click_pause_selector);
|
||||
replayTextView.setVisibility(GONE);
|
||||
} else if (state == STATE_ERROR) {
|
||||
startButton.setVisibility(INVISIBLE);
|
||||
replayTextView.setVisibility(GONE);
|
||||
} else if (state == STATE_AUTO_COMPLETE) {
|
||||
startButton.setVisibility(VISIBLE);
|
||||
startButton.setImageResource(R.drawable.jz_click_replay_selector);
|
||||
replayTextView.setVisibility(VISIBLE);
|
||||
} else {
|
||||
startButton.setImageResource(R.drawable.jz_click_play_selector);
|
||||
replayTextView.setVisibility(GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showProgressDialog(float deltaX, String seekTime, long seekTimePosition, String totalTime, long totalTimeDuration) {
|
||||
super.showProgressDialog(deltaX, seekTime, seekTimePosition, totalTime, totalTimeDuration);
|
||||
if (mProgressDialog == null) {
|
||||
View localView = LayoutInflater.from(jzvdContext).inflate(R.layout.jz_dialog_progress, null);
|
||||
mDialogProgressBar = localView.findViewById(R.id.duration_progressbar);
|
||||
mDialogSeekTime = localView.findViewById(R.id.tv_current);
|
||||
mDialogTotalTime = localView.findViewById(R.id.tv_duration);
|
||||
mDialogIcon = localView.findViewById(R.id.duration_image_tip);
|
||||
mProgressDialog = createDialogWithView(localView);
|
||||
}
|
||||
if (!mProgressDialog.isShowing()) {
|
||||
mProgressDialog.show();
|
||||
}
|
||||
|
||||
mDialogSeekTime.setText(seekTime);
|
||||
mDialogTotalTime.setText(" / " + totalTime);
|
||||
mDialogProgressBar.setProgress(totalTimeDuration <= 0 ? 0 : (int) (seekTimePosition * 100 / totalTimeDuration));
|
||||
if (deltaX > 0) {
|
||||
mDialogIcon.setBackgroundResource(R.drawable.jz_forward_icon);
|
||||
} else {
|
||||
mDialogIcon.setBackgroundResource(R.drawable.jz_backward_icon);
|
||||
}
|
||||
onCLickUiToggleToClear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissProgressDialog() {
|
||||
super.dismissProgressDialog();
|
||||
if (mProgressDialog != null) {
|
||||
mProgressDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showVolumeDialog(float deltaY, int volumePercent) {
|
||||
super.showVolumeDialog(deltaY, volumePercent);
|
||||
if (mVolumeDialog == null) {
|
||||
View localView = LayoutInflater.from(jzvdContext).inflate(R.layout.jz_dialog_volume, null);
|
||||
mDialogVolumeImageView = localView.findViewById(R.id.volume_image_tip);
|
||||
mDialogVolumeTextView = localView.findViewById(R.id.tv_volume);
|
||||
mDialogVolumeProgressBar = localView.findViewById(R.id.volume_progressbar);
|
||||
mVolumeDialog = createDialogWithView(localView);
|
||||
}
|
||||
if (!mVolumeDialog.isShowing()) {
|
||||
mVolumeDialog.show();
|
||||
}
|
||||
if (volumePercent <= 0) {
|
||||
mDialogVolumeImageView.setBackgroundResource(R.drawable.jz_close_volume);
|
||||
} else {
|
||||
mDialogVolumeImageView.setBackgroundResource(R.drawable.jz_add_volume);
|
||||
}
|
||||
if (volumePercent > 100) {
|
||||
volumePercent = 100;
|
||||
} else if (volumePercent < 0) {
|
||||
volumePercent = 0;
|
||||
}
|
||||
mDialogVolumeTextView.setText(volumePercent + "%");
|
||||
mDialogVolumeProgressBar.setProgress(volumePercent);
|
||||
onCLickUiToggleToClear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissVolumeDialog() {
|
||||
super.dismissVolumeDialog();
|
||||
if (mVolumeDialog != null) {
|
||||
mVolumeDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showBrightnessDialog(int brightnessPercent) {
|
||||
super.showBrightnessDialog(brightnessPercent);
|
||||
if (mBrightnessDialog == null) {
|
||||
View localView = LayoutInflater.from(jzvdContext).inflate(R.layout.jz_dialog_brightness, null);
|
||||
mDialogBrightnessTextView = localView.findViewById(R.id.tv_brightness);
|
||||
mDialogBrightnessProgressBar = localView.findViewById(R.id.brightness_progressbar);
|
||||
mBrightnessDialog = createDialogWithView(localView);
|
||||
}
|
||||
if (!mBrightnessDialog.isShowing()) {
|
||||
mBrightnessDialog.show();
|
||||
}
|
||||
if (brightnessPercent > 100) {
|
||||
brightnessPercent = 100;
|
||||
} else if (brightnessPercent < 0) {
|
||||
brightnessPercent = 0;
|
||||
}
|
||||
mDialogBrightnessTextView.setText(brightnessPercent + "%");
|
||||
mDialogBrightnessProgressBar.setProgress(brightnessPercent);
|
||||
onCLickUiToggleToClear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissBrightnessDialog() {
|
||||
super.dismissBrightnessDialog();
|
||||
if (mBrightnessDialog != null) {
|
||||
mBrightnessDialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
public Dialog createDialogWithView(View localView) {
|
||||
Dialog dialog = new Dialog(jzvdContext, R.style.jz_style_dialog_progress);
|
||||
dialog.setContentView(localView);
|
||||
Window window = dialog.getWindow();
|
||||
window.addFlags(Window.FEATURE_ACTION_BAR);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
|
||||
window.setLayout(-2, -2);
|
||||
WindowManager.LayoutParams localLayoutParams = window.getAttributes();
|
||||
localLayoutParams.gravity = Gravity.CENTER;
|
||||
window.setAttributes(localLayoutParams);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
public void startDismissControlViewTimer() {
|
||||
cancelDismissControlViewTimer();
|
||||
DISMISS_CONTROL_VIEW_TIMER = new Timer();
|
||||
mDismissControlViewTimerTask = new DismissControlViewTimerTask();
|
||||
DISMISS_CONTROL_VIEW_TIMER.schedule(mDismissControlViewTimerTask, 2500);
|
||||
}
|
||||
|
||||
public void cancelDismissControlViewTimer() {
|
||||
if (DISMISS_CONTROL_VIEW_TIMER != null) {
|
||||
DISMISS_CONTROL_VIEW_TIMER.cancel();
|
||||
}
|
||||
if (mDismissControlViewTimerTask != null) {
|
||||
mDismissControlViewTimerTask.cancel();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCompletion() {
|
||||
super.onCompletion();
|
||||
cancelDismissControlViewTimer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
super.reset();
|
||||
cancelDismissControlViewTimer();
|
||||
unregisterWifiListener(getApplicationContext());
|
||||
}
|
||||
|
||||
public void dissmissControlView() {
|
||||
if (state != STATE_NORMAL
|
||||
&& state != STATE_ERROR
|
||||
&& state != STATE_AUTO_COMPLETE) {
|
||||
post(() -> {
|
||||
bottomContainer.setVisibility(View.INVISIBLE);
|
||||
topContainer.setVisibility(View.INVISIBLE);
|
||||
startButton.setVisibility(View.INVISIBLE);
|
||||
|
||||
if (screen != SCREEN_TINY) {
|
||||
bottomProgressBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
cancelProgressTimer();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void registerWifiListener(Context context) {
|
||||
if (context == null) return;
|
||||
mIsWifi = JZUtils.isWifiConnected(context);
|
||||
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
context.registerReceiver(wifiReceiver, intentFilter);
|
||||
}
|
||||
|
||||
public void unregisterWifiListener(Context context) {
|
||||
if (context == null) return;
|
||||
try {
|
||||
context.unregisterReceiver(wifiReceiver);
|
||||
} catch (IllegalArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public class DismissControlViewTimerTask extends TimerTask {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
dissmissControlView();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
37
library/src/main/java/org/jzvd/jzvideo/JZVideoA.kt
Normal file
@@ -0,0 +1,37 @@
|
||||
package org.jzvd.jzvideo
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.widget.RelativeLayout
|
||||
|
||||
const val TAG = "JZVD"
|
||||
|
||||
|
||||
open class JZVideoA : RelativeLayout {
|
||||
|
||||
enum class State {
|
||||
IDLE, NORMAL, PREPARING, PREPARING_CHANGE_URL, PREPARING_PLAYING,
|
||||
PREPARED, PLAYING, PAUSE, COMPLETE, ERROR
|
||||
}
|
||||
|
||||
enum class Screen {
|
||||
NORMAL, FULLSCREEN, TINY
|
||||
}
|
||||
|
||||
lateinit var state: State
|
||||
|
||||
|
||||
constructor(ctx: Context) : super(ctx) {
|
||||
}
|
||||
|
||||
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun releaseAllVideos() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
6
library/src/main/res/anim/pop_from_bottom_anim_in.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="200"
|
||||
android:fromXDelta="100%"
|
||||
android:toXDelta="0" />
|
||||
5
library/src/main/res/anim/pop_from_bottom_anim_out.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<translate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="200"
|
||||
android:fromXDelta="0"
|
||||
android:toXDelta="100%" />
|
||||
BIN
library/src/main/res/drawable-xhdpi/jz_add_volume.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_back_normal.png
Normal file
|
After Width: | Height: | Size: 625 B |
BIN
library/src/main/res/drawable-xhdpi/jz_back_pressed.png
Normal file
|
After Width: | Height: | Size: 378 B |
BIN
library/src/main/res/drawable-xhdpi/jz_back_tiny_normal.png
Normal file
|
After Width: | Height: | Size: 531 B |
BIN
library/src/main/res/drawable-xhdpi/jz_back_tiny_pressed.png
Normal file
|
After Width: | Height: | Size: 486 B |
BIN
library/src/main/res/drawable-xhdpi/jz_backward_icon.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_battery_level_10.png
Normal file
|
After Width: | Height: | Size: 176 B |
BIN
library/src/main/res/drawable-xhdpi/jz_battery_level_100.png
Normal file
|
After Width: | Height: | Size: 169 B |
BIN
library/src/main/res/drawable-xhdpi/jz_battery_level_30.png
Normal file
|
After Width: | Height: | Size: 169 B |
BIN
library/src/main/res/drawable-xhdpi/jz_battery_level_50.png
Normal file
|
After Width: | Height: | Size: 168 B |
BIN
library/src/main/res/drawable-xhdpi/jz_battery_level_70.png
Normal file
|
After Width: | Height: | Size: 169 B |
BIN
library/src/main/res/drawable-xhdpi/jz_battery_level_90.png
Normal file
|
After Width: | Height: | Size: 168 B |
BIN
library/src/main/res/drawable-xhdpi/jz_brightness_video.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 469 B |
BIN
library/src/main/res/drawable-xhdpi/jz_close_volume.png
Normal file
|
After Width: | Height: | Size: 717 B |
BIN
library/src/main/res/drawable-xhdpi/jz_enlarge.png
Normal file
|
After Width: | Height: | Size: 164 B |
BIN
library/src/main/res/drawable-xhdpi/jz_forward_icon.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_loading_bg.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_pause_normal.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_pause_pressed.png
Normal file
|
After Width: | Height: | Size: 958 B |
BIN
library/src/main/res/drawable-xhdpi/jz_play_normal.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_play_pressed.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_restart_normal.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_restart_pressed.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_share_normal.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_share_pressed.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
BIN
library/src/main/res/drawable-xhdpi/jz_shrink.png
Normal file
|
After Width: | Height: | Size: 224 B |
BIN
library/src/main/res/drawable-xhdpi/jz_volume_icon.png
Normal file
|
After Width: | Height: | Size: 922 B |
BIN
library/src/main/res/drawable/jz_bottom_bg.9.png
Normal file
|
After Width: | Height: | Size: 946 B |
28
library/src/main/res/drawable/jz_bottom_progress.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<solid android:color="#a5ffffff" />
|
||||
<size android:height="4dp" />
|
||||
<corners android:radius="1dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:id="@android:id/secondaryProgress">
|
||||
<clip>
|
||||
<shape>
|
||||
<solid android:color="#ffe0e0e0" />
|
||||
<size android:height="4dp" />
|
||||
<corners android:radius="1dp" />
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
<item android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<solid android:color="#fff85959" />
|
||||
<size android:height="4dp" />
|
||||
<corners android:radius="1dp" />
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
</layer-list>
|
||||
5
library/src/main/res/drawable/jz_bottom_seek_poster.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/jz_seek_poster_pressed" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/jz_seek_poster_normal" />
|
||||
</selector>
|
||||
28
library/src/main/res/drawable/jz_bottom_seek_progress.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<solid android:color="#a5ffffff" />
|
||||
<size android:height="1dp" />
|
||||
<corners android:radius="1.5dip" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:id="@android:id/secondaryProgress">
|
||||
<clip>
|
||||
<shape>
|
||||
<solid android:color="#ffffffff" />
|
||||
<size android:height="1dp" />
|
||||
<corners android:radius="1.5dip" />
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
<item android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<solid android:color="#fff85959" />
|
||||
<size android:height="1dp" />
|
||||
<corners android:radius="1.5dip" />
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
</layer-list>
|
||||
BIN
library/src/main/res/drawable/jz_clarity_popwindow_bg.9.png
Normal file
|
After Width: | Height: | Size: 470 B |
5
library/src/main/res/drawable/jz_click_back_selector.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/jz_back_pressed" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/jz_back_normal" />
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/jz_back_tiny_pressed" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/jz_back_tiny_normal" />
|
||||
</selector>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/jz_pause_pressed" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/jz_pause_normal" />
|
||||
|
||||
</selector>
|
||||
5
library/src/main/res/drawable/jz_click_play_selector.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/jz_play_pressed" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/jz_play_normal" />
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/jz_restart_pressed" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/jz_restart_normal" />
|
||||
</selector>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/jz_share_pressed" android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/jz_share_normal" />
|
||||
</selector>
|
||||
17
library/src/main/res/drawable/jz_dialog_progress.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<solid android:color="#ffffffff" />
|
||||
<corners android:radius="2dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:id="@android:id/progress">
|
||||
<clip>
|
||||
<shape>
|
||||
<solid android:color="#fff85959" />
|
||||
<corners android:radius="2dp" />
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
</layer-list>
|
||||
9
library/src/main/res/drawable/jz_dialog_progress_bg.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#cc000000" />
|
||||
<corners
|
||||
android:bottomLeftRadius="6dp"
|
||||
android:bottomRightRadius="6dp"
|
||||
android:topLeftRadius="6dp"
|
||||
android:topRightRadius="6dp" />
|
||||
</shape>
|
||||
7
library/src/main/res/drawable/jz_loading.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:drawable="@drawable/jz_loading_bg"
|
||||
android:fromDegrees="0.0"
|
||||
android:pivotX="50.0%"
|
||||
android:pivotY="50.0%"
|
||||
android:toDegrees="360.0" />
|
||||
7
library/src/main/res/drawable/jz_retry.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<corners android:radius="7dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@android:color/white" />
|
||||
</shape>
|
||||
8
library/src/main/res/drawable/jz_seek_poster_normal.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="#ffffffff" />
|
||||
<size
|
||||
android:width="15dp"
|
||||
android:height="15dp" />
|
||||
</shape>
|
||||
8
library/src/main/res/drawable/jz_seek_poster_pressed.xml
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="#fff0f0f0" />
|
||||
<size
|
||||
android:width="15dp"
|
||||
android:height="15dp" />
|
||||
</shape>
|
||||
BIN
library/src/main/res/drawable/jz_title_bg.9.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
19
library/src/main/res/drawable/jz_volume_progress_bg.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@android:id/background">
|
||||
<shape>
|
||||
<solid android:color="#ffffffff" />
|
||||
<corners android:radius="2dp" />
|
||||
</shape>
|
||||
</item>
|
||||
<item android:id="@android:id/progress">
|
||||
<clip
|
||||
android:clipOrientation="vertical"
|
||||
android:gravity="bottom">
|
||||
<shape>
|
||||
<solid android:color="#fff85959" />
|
||||
<corners android:radius="2dp" />
|
||||
</shape>
|
||||
</clip>
|
||||
</item>
|
||||
</layer-list>
|
||||
43
library/src/main/res/layout/jz_dialog_brightness.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/jz_dialog_progress_bg"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="155dp"
|
||||
android:layout_height="120dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="20dp"
|
||||
android:src="@drawable/jz_brightness_video" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_brightness"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="12dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="#ffffffff"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/brightness_progressbar"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="3dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginLeft="24dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="24dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:max="100"
|
||||
android:progressDrawable="@drawable/jz_dialog_progress" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
56
library/src/main/res/layout/jz_dialog_progress.xml
Normal file
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/jz_dialog_progress_bg"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="152dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/duration_image_tip"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="27dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="20dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_current"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#fff85959"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_duration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="#ffffffff"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/duration_progressbar"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="4dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:max="100"
|
||||
android:progressDrawable="@drawable/jz_dialog_progress" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
43
library/src/main/res/layout/jz_dialog_volume.xml
Normal file
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/jz_dialog_progress_bg"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="155dp"
|
||||
android:layout_height="120dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/volume_image_tip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="20dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_volume"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="12dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="#ffffffff"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/volume_progressbar"
|
||||
style="@android:style/Widget.ProgressBar.Horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="3dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginLeft="24dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="24dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:max="100"
|
||||
android:progressDrawable="@drawable/jz_dialog_progress" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
10
library/src/main/res/layout/jz_layout_clarity.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/video_quality_wrapper_area"
|
||||
android:layout_width="240dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#88000000"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="16dp" />
|
||||
11
library/src/main/res/layout/jz_layout_clarity_item.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/video_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp"
|
||||
android:textColor="#FFF"
|
||||
android:textSize="18sp" />
|
||||
246
library/src/main/res/layout/jz_layout_std.xml
Normal file
@@ -0,0 +1,246 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black"
|
||||
android:descendantFocusability="afterDescendants">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/surface_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/poster"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:adjustViewBounds="true"
|
||||
android:background="#000000"
|
||||
android:scaleType="fitXY" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_bottom"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@drawable/jz_bottom_bg"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="invisible">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/current"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="14dp"
|
||||
android:text="00:00"
|
||||
android:textColor="#ffffff" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/bottom_seek_progress"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_weight="1.0"
|
||||
android:background="@null"
|
||||
android:max="100"
|
||||
android:maxHeight="1dp"
|
||||
android:minHeight="1dp"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingRight="12dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:progressDrawable="@drawable/jz_bottom_seek_progress"
|
||||
android:thumb="@drawable/jz_bottom_seek_poster" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/total"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="00:00"
|
||||
android:textColor="#ffffff" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/clarity"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:paddingLeft="20dp"
|
||||
android:text="clarity"
|
||||
|
||||
android:textAlignment="center"
|
||||
android:textColor="#ffffff" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/fullscreen"
|
||||
android:layout_width="52.5dp"
|
||||
android:layout_height="fill_parent"
|
||||
android:paddingLeft="14dp"
|
||||
android:paddingRight="14dp"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/jz_enlarge" />
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/bottom_progress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1.5dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:max="100"
|
||||
android:progressDrawable="@drawable/jz_bottom_progress" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/back_tiny"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:background="@drawable/jz_click_back_tiny_selector"
|
||||
android:visibility="gone" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/layout_top"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="@drawable/jz_title_bg"
|
||||
android:paddingStart="10dp"
|
||||
android:paddingLeft="10dp"
|
||||
android:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/back"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginTop="12dp"
|
||||
android:padding="3dp"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/jz_click_back_selector" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:layout_toLeftOf="@+id/battery_time_layout"
|
||||
android:layout_toEndOf="@+id/back"
|
||||
android:layout_toRightOf="@+id/back"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="18sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/battery_time_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="14dp"
|
||||
android:layout_marginRight="14dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
android:visibility="invisible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/battery_level"
|
||||
android:layout_width="23dp"
|
||||
android:layout_height="10dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:background="@drawable/jz_battery_level_10" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/video_current_time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:textColor="#ffffffff"
|
||||
android:textSize="12.0sp" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading"
|
||||
android:layout_width="@dimen/jz_start_button_w_h_normal"
|
||||
android:layout_height="@dimen/jz_start_button_w_h_normal"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:indeterminateDrawable="@drawable/jz_loading"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/start_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/start"
|
||||
android:layout_width="@dimen/jz_start_button_w_h_normal"
|
||||
android:layout_height="@dimen/jz_start_button_w_h_normal"
|
||||
android:src="@drawable/jz_click_play_selector" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/replay_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/start_layout"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="@string/replay"
|
||||
android:textColor="#ffffff"
|
||||
android:textSize="12sp"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/retry_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:visibility="invisible">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/video_loading_failed"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/retry_btn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="15dp"
|
||||
android:background="@drawable/jz_retry"
|
||||
android:paddingLeft="9dp"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingRight="9dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:text="@string/click_to_restart"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
10
library/src/main/res/values-es/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="tips_not_wifi">Estás conectado a una red móvil, el reproductor utilizará tus datos si continuas</string>
|
||||
<string name="tips_not_wifi_confirm">Reproducir</string>
|
||||
<string name="tips_not_wifi_cancel">Cancelar</string>
|
||||
<string name="no_url">No hay vídeo</string>
|
||||
<string name="replay">Volver a ver</string>
|
||||
<string name="click_to_restart">Haga clic para volver a intentarlo</string>
|
||||
<string name="video_loading_failed">Error de carga de video</string>
|
||||
</resources>
|
||||
10
library/src/main/res/values-ja-rJP/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="tips_not_wifi">あなたは現在、モバイルネットワークを使用しています</string>
|
||||
<string name="tips_not_wifi_confirm">ビデオを再開する</string>
|
||||
<string name="tips_not_wifi_cancel">ビデオを止める</string>
|
||||
<string name="no_url">URLエラー</string>
|
||||
<string name="replay">リプレイ</string>
|
||||
<string name="click_to_restart">再度試してください</string>
|
||||
<string name="video_loading_failed">エラーが発生しました</string>
|
||||
</resources>
|
||||
10
library/src/main/res/values-ko-rKR/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="tips_not_wifi">현재 모바일 네트워크를 사용 중이면 계속 플레이어가 트래픽을 소비합니다</string>
|
||||
<string name="tips_not_wifi_confirm">재생 다시 시작</string>
|
||||
<string name="tips_not_wifi_cancel">재생을 중지</string>
|
||||
<string name="no_url">재생 주소 없음</string>
|
||||
<string name="replay">재생 다시 시작</string>
|
||||
<string name="click_to_restart">다시 시도 하십시오</string>
|
||||
<string name="video_loading_failed">버퍼링 실패</string>
|
||||
</resources>
|
||||
10
library/src/main/res/values-pt/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="tips_not_wifi">Você está usando a rede móvel, você deseja mesmo ver o vídeo?</string>
|
||||
<string name="tips_not_wifi_confirm">Continuar</string>
|
||||
<string name="tips_not_wifi_cancel">Parar</string>
|
||||
<string name="no_url">Sem vídeo</string>
|
||||
<string name="replay">Replay</string>
|
||||
<string name="click_to_restart">Clique para tentar novamente</string>
|
||||
<string name="video_loading_failed">O carregamento de vídeo falhou</string>
|
||||
</resources>
|
||||
10
library/src/main/res/values-tr/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="tips_not_wifi">Şu anda mobil veriyi kullanıyorsunuz, yüksek veri kaybına yol açabilir</string>
|
||||
<string name="tips_not_wifi_confirm">Devam Et</string>
|
||||
<string name="tips_not_wifi_cancel">Durdur</string>
|
||||
<string name="no_url">URL Bulunamadı</string>
|
||||
<string name="replay">Tekrar</string>
|
||||
<string name="click_to_restart">Tekrar denemek için tıklayın</string>
|
||||
<string name="video_loading_failed">Video yüklenemedi</string>
|
||||
</resources>
|
||||
10
library/src/main/res/values-zh/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="tips_not_wifi">您当前正在使用移动网络,继续播放将消耗流量</string>
|
||||
<string name="tips_not_wifi_confirm">继续播放</string>
|
||||
<string name="tips_not_wifi_cancel">停止播放</string>
|
||||
<string name="no_url">播放地址无效</string>
|
||||
<string name="replay">重播</string>
|
||||
<string name="click_to_restart">点击重试</string>
|
||||
<string name="video_loading_failed">视频加载失败</string>
|
||||
</resources>
|
||||
4
library/src/main/res/values/dimens.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
<dimen name="jz_start_button_w_h_normal">45dp</dimen>
|
||||
<dimen name="jz_start_button_w_h_fullscreen">62dp</dimen>
|
||||
</resources>
|
||||
23
library/src/main/res/values/ids.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<item type="id" name="layout_bottom"/>
|
||||
<item type="id" name="current"/>
|
||||
<item type="id" name="bottom_seek_progress"/>
|
||||
<item type="id" name="total"/>
|
||||
<item type="id" name="clarity"/>
|
||||
<item type="id" name="fullscreen"/>
|
||||
<item type="id" name="back_tiny"/>
|
||||
<item type="id" name="layout_top"/>
|
||||
<item type="id" name="back"/>
|
||||
<item type="id" name="title"/>
|
||||
<item type="id" name="battery_time_layout"/>
|
||||
<item type="id" name="battery_level"/>
|
||||
<item type="id" name="video_current_time"/>
|
||||
<item type="id" name="retry_layout"/>
|
||||
<item type="id" name="retry_btn"/>
|
||||
<item type="id" name="replay_text"/>
|
||||
<item type="id" name="bottom_progress"/>
|
||||
<item type="id" name="loading"/>
|
||||
<item type="id" name="start_layout"/>
|
||||
<item type="id" name="start"/>
|
||||
</resources>
|
||||
10
library/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="tips_not_wifi">You are currently using the mobile network, the player will continue to consume traffic</string>
|
||||
<string name="tips_not_wifi_confirm">Resume</string>
|
||||
<string name="tips_not_wifi_cancel">Stop play</string>
|
||||
<string name="no_url">No url</string>
|
||||
<string name="replay">Replay</string>
|
||||
<string name="click_to_restart">Click to try again</string>
|
||||
<string name="video_loading_failed">Video loading failed</string>
|
||||
</resources>
|
||||
21
library/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="jz_style_dialog_progress" parent="@android:style/Theme.Dialog">
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowAnimationStyle">@style/jz_popup_toast_anim</item>
|
||||
<item name="android:backgroundDimEnabled">false</item>
|
||||
</style>
|
||||
|
||||
<style name="jz_popup_toast_anim" parent="@android:style/Animation">
|
||||
<item name="android:windowEnterAnimation">@android:anim/fade_in</item>
|
||||
<item name="android:windowExitAnimation">@android:anim/fade_out</item>
|
||||
</style>
|
||||
|
||||
<style name="pop_animation">
|
||||
<item name="android:windowEnterAnimation">@anim/pop_from_bottom_anim_in</item>
|
||||
<item name="android:windowExitAnimation">@anim/pop_from_bottom_anim_out</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
4
library/src/main/res/xml/jz_network_security_config.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<base-config cleartextTrafficPermitted="true" />
|
||||
</network-security-config>
|
||||