add library

This commit is contained in:
2021-03-01 10:01:53 +08:00
parent 67727032eb
commit b50f6d22e4
77 changed files with 3596 additions and 0 deletions

1
.gitignore vendored
View File

@@ -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
View 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'

View 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>

View 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);
}
}

View 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);
}

View 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) {
}
}

View 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);
}
}

View 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;
}
}

File diff suppressed because it is too large Load Diff

View 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();
}
}
}

View 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() {
}
}
}

View 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" />

View 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%" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 469 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 717 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 922 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

View 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>

View 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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

View 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>

View 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_tiny_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/jz_back_tiny_normal" />
</selector>

View File

@@ -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>

View 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>

View 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_restart_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/jz_restart_normal" />
</selector>

View 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_share_pressed" android:state_pressed="true" />
<item android:drawable="@drawable/jz_share_normal" />
</selector>

View 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>

View 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>

View 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" />

View 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>

View 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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View 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>

View 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>

View 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>

View 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>

View 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" />

View 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" />

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View 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>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>