Dumpling Video playerDirections for use
The main features
- You can fully customize the UI and any functionality
- One line of code switching engine, support the video format and protocol depends on the engine, android. Media. The MediaPlayer ijkplayer
- Perfect detection list sliding
- Can realize full screen play, small window play
- It works in full screen mode in multiple nested ListView, ViewPager and ListView, ViewPager and Fragment modes
- You can load, pause, play and other states to enter the full screen and exit the full screen
- A variety of video screen adaptation, can be spread full screen, can be full screen clipping
- Gravity sensor automatically enters full screen
- Gestures modify progress and volume after full screen
- Home button Exits the interface to pause the playback and return to the interface to continue the playback
- WebView nested local video controls
- Example of adding video cache in demo
Integrated use of
Even with a custom UI or modifications to the Library, there are five steps to using the player.
1. Add a class library
compile 'cn.jzvd:jiaozivideoplayer:release'
2. Add layout
<cn.jzvd.JzvdStd
android:id="@+id/videoplayer"
android:layout_width="match_parent"
android:layout_height="200dp"/>
Copy the code
3. Set the video address, thumbnail address, and title
MyJzvdStd myJzvdStd= findViewById(R.id.videoplayer);
myJzvdStd.setUp("http://jzvd.nathen.cn/342a5f7ef6124a4a8faf00e738b8bee4/cf6d9db0bd4d41f59d09ea0a81e918fd-5287d2089db37e62345123a1be272f8 b.mp4"
, "Dumplings grow up.", JzvdStd.SCREEN_WINDOW_NORMAL);
Glide.with(this).load("http://jzvd-pic.nathen.cn/jzvd-pic/1bb2ebbe-140d-4e2e-abd2-9e7e564f71ac.png").into(myJzvdStd.thumbImageView);
Copy the code
4. In the Activity
@Override
protected void onPause() {
super.onPause();
Jzvd.releaseAllVideos();
}
@Override
public void onBackPressed() {
if (Jzvd.backPress()) {
return;
}
super.onBackPressed();
}
Copy the code
In the AndroidManifest. In the XML
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="portrait"/ > <! -- or android:screenOrientation="landscape"-->
Copy the code
The basic use
Add thumbnail images
Glide.with(this).load(Url).into(myJzvdStd.thumbImageView); // Glide is recommendedCopy the code
Automatically play
There are two kinds of automatic playback Choose add a here, 1. MyJzvdStd. StartButton. PerformClick (); 2. myJzvdStd.startVideo();Copy the code
Jump to specify position to play
Mjzvdstd. seekToInAdvance = 20000; // Jump to specify position to play jzMediamanager. seekTo(30000);Copy the code
2. Play the video on the SD card
public void cpAssertVideoToLocalPath() {
try {
InputStream myInput;
OutputStream myOutput = new FileOutputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/local_video.mp4");
myInput = this.getAssets().open("local_video.mp4");
byte[] buffer = new byte[1024];
int length = myInput.read(buffer);
while (length > 0) {
myOutput.write(buffer, 0, length);
length = myInput.read(buffer);
}
myOutput.flush();
myInput.close();
myOutput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
myJzvdStd.setUp(Environment.getExternalStorageDirectory().getAbsolutePath() + "/DCIM/Camera/local_video.mp4"."Dumplings do not believe",Jzvd.SCREEN_WINDOW_NORMAL, ); Here a lot of people ask why can not broadcast, please seriously angry URL, broadcast is url not angry rightCopy the code
Play the video in the assets directory
Copying Demo CustomMediaPlayerAssertFolder class to your project under -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - JZDataSource jzDataSource = null; try { jzDataSource = new JZDataSource(getAssets().openFd("local_video.mp4"));
jzDataSource.title = "Dumplings grow up.";
} catch (IOException e) {
e.printStackTrace();
}
jzvdStd.setUp(jzDataSource, JzvdStd.SCREEN_WINDOW_NORMAL);
Glide.with(this)
.load("http://jzvd-pic.nathen.cn/jzvd-pic/1bb2ebbe-140d-4e2e-abd2-9e7e564f71ac.png") .into(jzvdStd.thumbImageView); Jzvd.setMediaInterface(new CustomMediaPlayerAssertFolder()); // Go to this page to modify MediaInterface to make this page JZVD work properlyCopy the code
Play it in full screen
JzvdStd.startFullscreen(this, JzvdStd.class, VideoConstant.videoUrlList[6], "Dumplings work hard.");
Copy the code
Open the small window to play
mJzvdStd.startWindowTiny();
Copy the code
List Item highlights open small window play
1.Listview
listView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { Jzvd.onScrollAutoTiny(view, firstVisibleItem, visibleItemCount, totalItemCount); // Jzvd.onScrollReleaseAllVideos(view, firstVisibleItem, visibleItemCount, totalItemCount); This is not open list underline small window is also draw screen release JZ underline pause}}); 2. To draw list open a small window RecyclerView RecyclerView. AddOnChildAttachStateChangeListener (new RecyclerView.OnChildAttachStateChangeListener() { @Override public void onChildViewAttachedToWindow(View view) { Jzvd.onChildViewAttachedToWindow(view, R.id.videoplayer); } @Override public void onChildViewDetachedFromWindow(View view) { Jzvd.onChildViewDetachedFromWindow(view); }}); 2.1 RecyclerView draw screen release JZ, is also not open list out show small window RecyclerView addOnChildAttachStateChangeListener (new RecyclerView.OnChildAttachStateChangeListener() {
@Override
public void onChildViewAttachedToWindow(View view) {
}
@Override
public void onChildViewDetachedFromWindow(View view) {
Jzvd jzvd = view.findViewById(R.id.videoplayer);
if(jzvd ! = null && jzvd.jzDataSource.containsTheUrl(JZMediaManager.getCurrentUrl())) { Jzvd currentJzvd = JzvdMgr.getCurrentJzvd();if(currentJzvd ! = null && currentJzvd.currentScreen ! = Jzvd.SCREEN_WINDOW_FULLSCREEN) { Jzvd.releaseAllVideos(); }}}});Copy the code
There is no sound in the small screen but sound in the full screen
Create a class inherits JzvdStd and set in the XML public class JzvdStdVolumeAfterFullscreen extends JzvdStd {public JzvdStdVolumeAfterFullscreen(Context context) { super(context); } public JzvdStdVolumeAfterFullscreen(Context context, AttributeSet attrs) { super(context, attrs); } @Override public voidonPrepared() {
super.onPrepared();
if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
JZMediaManager.instance().jzMediaInterface.setVolume(1f, 1f);
} else{ JZMediaManager.instance().jzMediaInterface.setVolume(0f, 0f); }} /** * Turn off the mute mode when entering full-screen mode */ @override public voidstartWindowFullscreen() { super.startWindowFullscreen(); JZMediaManager.instance().jzMediaInterface.setVolume(1f, 1f); } /** * Enable mute mode when exiting full-screen mode */ @override public voidplayOnThisJzvd() { super.playOnThisJzvd(); JZMediaManager.instance().jzMediaInterface.setVolume(0f, 0f); }}Copy the code
After full screen is played, do not exit full screen
Create a class inherits JzvdStd and set in the XML public class JzvdStdAutoCompleteAfterFullscreen extends JzvdStd {public JzvdStdAutoCompleteAfterFullscreen(Context context) { super(context); } public JzvdStdAutoCompleteAfterFullscreen(Context context, AttributeSet attrs) { super(context, attrs); } @Override public voidstartVideo() {
if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
Log.d(TAG, "startVideo [" + this.hashCode() + "]");
initTextureView();
addTextureView();
AudioManager mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
mAudioManager.requestAudioFocus(onAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
JZUtils.scanForActivity(getContext()).getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
JZMediaManager.setDataSource(jzDataSource);
JZMediaManager.instance().positionInList = positionInList;
onStatePreparing();
} else {
super.startVideo();
}
}
@Override
public void onAutoCompletion() {
if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
onStateAutoComplete();
} else{ super.onAutoCompletion(); }}}Copy the code
The share button is displayed in full-screen mode
Copy the layout under the DEMO files in layout_top layout button to add your sharing public class JzvdStdShowShareButtonAfterFullscreen extends JzvdStd {public ImageView shareButton; public JzvdStdShowShareButtonAfterFullscreen(Context context) { super(context); } public JzvdStdShowShareButtonAfterFullscreen(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void init(Context context) { super.init(context); shareButton = findViewById(R.id.share); shareButton.setOnClickListener(this); } @Override public intgetLayoutId() {
return R.layout.layout_standard_with_share_button;
}
@Override
public void onClick(View v) {
super.onClick(v);
if (v.getId() == R.id.share) {
Toast.makeText(getContext(), "Whatever the icon means", Toast.LENGTH_SHORT).show();
}
}
@Override
public void setUp(JZDataSource jzDataSource, int screen) {
super.setUp(jzDataSource, screen);
if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
shareButton.setVisibility(View.VISIBLE);
} else{ shareButton.setVisibility(View.INVISIBLE); }}}Copy the code
The title is not displayed in the small-screen mode, but is displayed in the full-screen mode
public class JzvdStdShowTitleAfterFullscreen extends JzvdStd { public JzvdStdShowTitleAfterFullscreen(Context context) { super(context); } public JzvdStdShowTitleAfterFullscreen(Context context, AttributeSet attrs) { super(context, attrs); } @Override public voidsetUp(JZDataSource jzDataSource, int screen) {
super.setUp(jzDataSource, screen);
if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
titleTextView.setVisibility(View.VISIBLE);
} else{ titleTextView.setVisibility(View.INVISIBLE); }}}Copy the code
Play MP3
public class JzvdStdMp3 extends JzvdStd {
public JzvdStdMp3(Context context) {
super(context);
}
public JzvdStdMp3(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public int getLayoutId() {
return R.layout.jz_layout_standard_mp3;
}
@Override
public void onClick(View v) {
if (v.getId() == cn.jzvd.R.id.thumb &&
(currentState == CURRENT_STATE_PLAYING ||
currentState == CURRENT_STATE_PAUSE)) {
onClickUiToggle();
} else if (v.getId() == R.id.fullscreen) {
} else{ super.onClick(v); }} //changeUiTo can change the UI @override public voidchangeUiToNormal() {
super.changeUiToNormal();
}
@Override
public void changeUiToPreparing() {
super.changeUiToPreparing();
}
@Override
public void changeUiToPlayingShow() {
super.changeUiToPlayingShow();
thumbImageView.setVisibility(View.VISIBLE);
}
@Override
public void changeUiToPlayingClear() {
super.changeUiToPlayingClear();
thumbImageView.setVisibility(View.VISIBLE);
}
@Override
public void changeUiToPauseShow() {
super.changeUiToPauseShow();
thumbImageView.setVisibility(View.VISIBLE);
}
@Override
public void changeUiToPauseClear() {
super.changeUiToPauseClear();
thumbImageView.setVisibility(View.VISIBLE);
}
@Override
public void changeUiToComplete() {
super.changeUiToComplete();
}
@Override
public void changeUiToError() {
super.changeUiToError();
}
}
jzvdStdMp3 = findViewById(R.id.jz_videoplayer_mp3);
jzvdStdMp3.setUp(URL, "Dumpling Sway", Jzvd.SCREEN_WINDOW_NORMAL);
Glide.with(this)
.load(VideoConstant.videoThumbs[0][1])
.into(jzvdStdMp3.thumbImageView);
Copy the code
The preview is not displayed after playing
public class JzvdStdShowTextureViewAfterAutoComplete extends JzvdStd {
public JzvdStdShowTextureViewAfterAutoComplete(Context context) {
super(context);
}
public JzvdStdShowTextureViewAfterAutoComplete(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void onAutoCompletion() { super.onAutoCompletion(); thumbImageView.setVisibility(View.GONE); }}Copy the code
Home button Exits the interface to pause the playback and return to the interface to continue the playback
@Override
protected void onResume() {
super.onResume();
//home back
JzvdStd.goOnPlayOnResume();
}
@Override
protected void onPause() {
super.onPause();
// Jzvd.clearSavedProgress(this, null);
//home back
JzvdStd.goOnPlayOnPause();
}
Copy the code
Cache and resolution switching while playing
1. Integrate Videocache implementation'com. Danikula: videocache: 2.7.0'Public Class ApplicationDemo extends Application {@override public voidonCreate() {
super.onCreate();
// LeakCanary.install(this);
}
private HttpProxyCacheServer proxy;
public static HttpProxyCacheServer getProxy(Context context) {
ApplicationDemo app = (ApplicationDemo) context.getApplicationContext();
return app.proxy == null ? (app.proxy = app.newProxy()) : app.proxy;
}
private HttpProxyCacheServer newProxy() {
returnnew HttpProxyCacheServer(this); }} 2. Reference LinkedHashMap map = new LinkedHashMap(); String proxyUrl = ApplicationDemo.getProxy(this).getProxyUrl(VideoConstant.videoUrls[0][9]); map.put("高清", proxyUrl);
map.put("Clear", VideoConstant.videoUrls[0][6]);
map.put("PuQing", VideoConstant.videoUrlList[0]);
JZDataSource jzDataSource = new JZDataSource(map, "Dumplings do not believe");
jzDataSource.looping = true;
jzDataSource.currentUrlIndex = 2;
jzDataSource.headerMap.put("key"."value"); //header mJzvdStd.setUp(jzDataSource , JzvdStd.SCREEN_WINDOW_NORMAL); Glide.with(this).load(VideoConstant.videoThumbList[0]).into(mJzvdStd.thumbImageView);Copy the code
Repeats,
Create a class integration JzvdStd and set in the XML public class JZVideoPlayerStandardLoopVideo extends JzvdStd {public JZVideoPlayerStandardLoopVideo (Context context) { super(context); } public JZVideoPlayerStandardLoopVideo (Context context, AttributeSet attrs) { super(context, attrs); } @Override public voidonAutoCompletion() { super.onAutoCompletion(); startVideo(); }} Another way to do this is to switch the clarity loop flag aboveCopy the code
Gravity sensor automatically enters full screen
SensorManager mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Jzvd.JZAutoFullscreenListener mSensorEventListener = new Jzvd.JZAutoFullscreenListener();
@Override
protected void onResume() {
super.onResume();
Sensor accelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(mSensorEventListener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(mSensorEventListener);
}
Copy the code
accelerometer
Jzvd.FULLSCREEN_ORIENTATION=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; Jzvd.NORMAL_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; Two variables control screen orientation before and after full screenCopy the code
The playback progress is not saved
Jzvd.SAVE_PROGRESS = false;
Copy the code
Cancel playback in non-WifiDialog prompt
Jzvd.WIFI_TIP_DIALOG_SHOWED=true;
Copy the code
Clear a URL progress
Jzvd.clearSavedProgress(this, "url");
Copy the code
Switching the playback kernel
Ijk copy the JZMediaIjkplayer class from Demo into the implementation for your project'TV. Danmaku. Ijk. Media: ijkplayer - Java: 0.8.4'
implementation 'TV. Danmaku. Ijk. Media: ijkplayer - armv7a: 0.8.4'Jzvd.setMediaInterface(new JZMediaIjkplayer()); // ijkMediaPlayer Mediaplayer Jzvd.setMediaInterface(new JZMediaSystem()); Exo copy the JZExoPlayer class from Demo into your project implementation'com. Google. Android. Exoplayer: exoplayer: 2.7.1'
Jzvd.setMediaInterface(new JZExoPlayer()); //exo
Copy the code
User buried point statistics
Jzvd.setJzUserAction(new MyUserActionStd()); /** * MyJzvdStd = MyJzvdStd = MyJzvdStd */ class MyUserActionStd implements JZUserActionStd {@override public void onEvent(int)type, Object url, int screen, Object... objects) {
switch (type) {
case JZUserAction.ON_CLICK_START_ICON:
Log.i("USER_EVENT"."ON_CLICK_START_ICON" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_CLICK_START_ERROR:
Log.i("USER_EVENT"."ON_CLICK_START_ERROR" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_CLICK_START_AUTO_COMPLETE:
Log.i("USER_EVENT"."ON_CLICK_START_AUTO_COMPLETE" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_CLICK_PAUSE:
Log.i("USER_EVENT"."ON_CLICK_PAUSE" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_CLICK_RESUME:
Log.i("USER_EVENT"."ON_CLICK_RESUME" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_SEEK_POSITION:
Log.i("USER_EVENT"."ON_SEEK_POSITION" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_AUTO_COMPLETE:
Log.i("USER_EVENT"."ON_AUTO_COMPLETE" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_ENTER_FULLSCREEN:
Log.i("USER_EVENT"."ON_ENTER_FULLSCREEN" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_QUIT_FULLSCREEN:
Log.i("USER_EVENT"."ON_QUIT_FULLSCREEN" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_ENTER_TINYSCREEN:
Log.i("USER_EVENT"."ON_ENTER_TINYSCREEN" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_QUIT_TINYSCREEN:
Log.i("USER_EVENT"."ON_QUIT_TINYSCREEN" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_TOUCH_SCREEN_SEEK_VOLUME:
Log.i("USER_EVENT"."ON_TOUCH_SCREEN_SEEK_VOLUME" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserAction.ON_TOUCH_SCREEN_SEEK_POSITION:
Log.i("USER_EVENT"."ON_TOUCH_SCREEN_SEEK_POSITION" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserActionStd.ON_CLICK_START_THUMB:
Log.i("USER_EVENT"."ON_CLICK_START_THUMB" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
case JZUserActionStd.ON_CLICK_BLANK:
Log.i("USER_EVENT"."ON_CLICK_BLANK" + " title is : " + (objects.length == 0 ? "" : objects[0]) + " url is : " + url + " screen is : " + screen);
break;
default:
Log.i("USER_EVENT"."unknow");
break; }}}Copy the code
##### after inheriting JzvdStd, the parent class mCurrentState can obtain the current playback state.
- CURRENT_STATE_IDLE Unknown state, nothing is done after the charge is new
- CURRENT_STATE_NORMAL Normal state
- CURRENT_STATE_PREPARING Video preparation status
- CURRENT_STATE_PREPARING_CHANGING_URL Toggles the ready state of the URL in play
- CURRENT_STATE_PLAYING Status of playing
- CURRENT_STATE_PAUSE Pause status
- CURRENT_STATE_AUTO_COMPLETE Auto play completion status
- CURRENT_STATE_ERROR Error status
Overrides a function that enters the play state, getting a callback to the play state
- OnStateNormal enters the normal state, usually after setUp
- OnStatePreparing enters the preparing state, that is, loading state
- OnStatePlaying enters the playing state
- OnStatePause pauses
- OnStateError Enters the error state
- OnStateAutoComplete Enters the auto play complete state
Understand the current screen type
Full screen, small window, and non-full screen are different instances. After inheriting JzvdStd, the current screen type is obtained via the mCurrentScreen variable
- SCREEN_WINDOW_NORMAL Normal window (before going to full screen)
- SCREEN_WINDOW_LIST List window (before going to full screen)
- SCREEN_WINDOW_FULLSCREEN full screen
- SCREEN_WINDOW_TINY #### event
- Overwrite the onProgress function to get the progress callback for seekBar at the bottom of each player setup
- Call the changeUrl function to switch urls
- Copy the onClick function to get the click events of various buttons
- Duplicate onTouch function, get full screen after the gesture operation
Some requirements realization (the following implementation is my thinking logic and use for reference some network, not perfect, according to your own project to the actual situation)
1. Member test function first clear steps from the train of thought
- First get the current playback time and the trial time to determine (consider dragging the progress bar beyond the trial time)
- Get a specific field from the background to determine whether to pay
- Popup the end of the trial function Dialog
- Pay back to continue playing (save the payment step) — cancel
Public Class TryToSeeVideo extends JzvdStd {RelativeLayout mRelativeLayout; TextView mExit, mPay, mTryToSee; boolean isNoPay; public TryToSeeVideo(Context context) { super(context); } public TryToSeeVideo(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void init(Context context) { super.init(context); mRelativeLayout = findViewById(R.id.try_to_see_tip); mExit = findViewById(R.id.exit); // Exit button mPay = findViewById(r.id.pai); // Pay button mTryToSee = findViewById(R.id.try_see); MExit. SetOnClickListener (this); mPay.setOnClickListener(this); mTryToSee.setOnClickListener(this); } @Override public intgetLayoutId() {
return R.layout.try_to_see_video_layout;
}
@Override
public void onClick(View v) {
super.onClick(v);
switch (v.getId()) {
caseR.i.d.xit: // Finish The interface recommends calling back the current eventbreak;
caseR.i.pay: // Enter the payment interface after successful payment jzvd.goonPlayonResume (); getContext().startActivity(new Intent(getContext(), ActivityMain.class)); // Simulate the jump to the payment interfacebreak;
caseR.id.try_see: JZMediaManager.seekTo(0); // return to 0 seconds jzvd. goOnPlayOnResume(); progressBar.setProgress(0); mRelativeLayout.setVisibility(GONE);break; }} /** * @param progress percentage * @param position Current time * @param duration Total duration */ @override public void onProgress(int progress, long position, long duration) { super.onProgress(progress, position, duration); long totalSeconds = position / 1000;if (true) {// Here we get a specific field from the server to determine whether to payif(totalSeconds >= 30) {// Consider dragging the progress bar for longer than the trial time without payingif(! IsNoPay) {// Add a flag because this function keeps calling back jzMediamanager.seekto (30000); // return to 30 seconds progressbar.setProgress (30); mRelativeLayout.setVisibility(VISIBLE); // Hide jzvd.goonPlayonPause () when appropriate; // Play startButton.setenabled (when appropriate (after payment is successful)false); // Cancel isNoPay = when appropriatetrue;
}
}
}
}
@Override
public void onStatePlaying() {
super.onStatePlaying();
isNoPay = false;
startButton.setEnabled(true); }}Copy the code
2. Play from the list page to the details page without time difference 3. Play the list automatically 4
Function changeUrl three overloads according to their own situation
- ChangeUrl (String URL, String title, long seekToInAdvance) //seekToInAdvance time
- changeUrl(JZDataSource jzDataSource, long seekToInAdvance)
- ChangeUrl (int urlMapIndex, long seekToInAdvance)
public class AutoPlayNextVideo extends JzvdStd { int UrlIndex = 0; Public AutoPlayNextVideo(Context Context) {super(Context); } public AutoPlayNextVideo(Context context, AttributeSet attrs) { super(context, attrs); } /** * Call the relevant changeUrl */ @override public void if you need to manually select a custom Ui to define the list of episodesonAutoCompletion() {
super.onAutoCompletion();
if (UrlIndex<videoUrlList.length){
UrlIndex++;
changeUrl(videoUrlList[UrlIndex], "The titles of the episodes.", 0); }}}Copy the code
Times the speed of playback
public class JzvdStdSpeed extends JzvdStd {
TextView tvSpeed;
int currentSpeedIndex = 2;
public JzvdStdSpeed(Context context) {
super(context);
}
public JzvdStdSpeed(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void init(Context context) {
super.init(context);
tvSpeed = findViewById(R.id.tv_speed);
tvSpeed.setOnClickListener(this);
}
@Override
public void setUp(JZDataSource jzDataSource, int screen) {
super.setUp(jzDataSource, screen);
if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
tvSpeed.setVisibility(View.VISIBLE);
} else {
tvSpeed.setVisibility(View.GONE);
}
if (jzDataSource.objects == null) {
Object[] object = {2};
jzDataSource.objects = object;
currentSpeedIndex = 2;
} else {
currentSpeedIndex = (int) jzDataSource.objects[0];
}
if (currentSpeedIndex == 2) {
tvSpeed.setText("Times");
} else {
tvSpeed.setText(getSpeedFromIndex(currentSpeedIndex) + "X");
}
}
@Override
public void onClick(View v) {
super.onClick(v);
if(v.g etId () = = R.i which v_speed) {/ / 0.5 0.75 1.0 1.25 1.5 1.75 2.0if (currentSpeedIndex == 6) {
currentSpeedIndex = 0;
} else {
currentSpeedIndex += 1;
}
JZMediaManager.setSpeed(getSpeedFromIndex(currentSpeedIndex));
tvSpeed.setText(getSpeedFromIndex(currentSpeedIndex) + "X");
jzDataSource.objects[0] = currentSpeedIndex;
}
}
@Override
public int getLayoutId() {
return R.layout.layout_std_speed;
}
private float getSpeedFromIndex(int index) {
float ret = 0f;
if(index == 0) {ret = 0.5f; }else if(index == 1) {ret = 0.75f; }else if(index == 2) {ret = 1.0f; }else if(index == 3) {ret = 1.25f; }else if(index == 4) {ret = 1.5f; }else if(index == 5) {ret = 1.75f; }else if(index == 6) {ret = 2.0f; }return ret;
}
Copy the code
## FaQs Video has sound, but no screen
- Enabling Hardware Acceleration
Gets a frame of the video
/** * context context * uri Video address * imageView sets image * frameTimeMicros for a certain time frame */ public static void loadVideoScreenshot(final Context context, String uri, ImageView imageView, long frameTimeMicros) { RequestOptions requestOptions = RequestOptions.frameOf(frameTimeMicros); requestOptions.set(FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST); requestOptions.transform(newBitmapTransformation() {
@Override
protected Bitmap transform(@NonNull BitmapPool pool, @NonNull Bitmap toTransform, int outWidth, int outHeight) {
return toTransform;
}
@Override
public void updateDiskCacheKey(MessageDigest messageDigest) {
try {
messageDigest.update((context.getPackageName() + "RotateTransform").getBytes("utf-8")); } catch (Exception e) { e.printStackTrace(); }}}); Glide.with(context).load(uri).apply(requestOptions).into(imageView); }Copy the code
Video rounded corners
ViewOutlineProvider (ViewOutlineProvider) Public Class JzViewOutlineProvider extends Public Class JzViewOutlineProvider extends public class JzViewOutlineProvider extends public class JzViewOutlineProvider extends ViewOutlineProvider { privatefloat mRadius;
public JzViewOutlineProvider(float radius) {
this.mRadius = radius;
}
@Override
public void getOutline(View view, Outline outline) {
Rect rect = new Rect();
view.getGlobalVisibleRect(rect);
Rect selfRect = new Rect(0, 0,
view.getWeight(),view.getHeight());
outline.setRoundRect(selfRect,mRadius);
}
}
mJzvdStd.setOutlineProvider(new JzViewOutlineProvider(radius));
mJzvdStd.setClipToOutline(true);
Copy the code
Click the full-screen button and blink back, indicating an error null pointer
- Check that the manifest is correctly configured for basic use. Whether an Activity inherits from AppCompatActivity
<activity
android:name=".xxxxxxxActivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="portrait" />
Copy the code
Video width height does not fill the screen, with black edges
Jzvd.setTextureViewRotation(90); / / video rotated 90 degrees According to their own situation. Select a fill Jzvd setVideoImageDisplayType (Jzvd. VIDEO_IMAGE_DISPLAY_TYPE_FILL_PARENT); Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_FILL_SCROP); Jzvd.setVideoImageDisplayType(Jzvd.VIDEO_IMAGE_DISPLAY_TYPE_ORIGINAL); // Original sizeCopy the code
Background Gaussian blur
- Import the project as a module and add an Imageview under the layout of jz_layout_standard.xml
<FrameLayout
android:id="@+id/surface_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<cn.jzvd.ResizableImageView
android:id="@+id/iv"
android:layout_width="match_parent"
android:layout_height="match_parent"/> </FrameLayout> Here I rewrote the Imageview for convenience to make it wide and fill the screen width. How easy is it to fill the screen widthCopy the code
Get the above Imageview control in the init method of the JzvdStd class, and that’s it, and then under the thumbnail set it with a Gaussian blur, so here’s how I do it and you can do it yourself.
myJzvdStd.setUp("http://jzvd.nathen.cn/342a5f7ef6124a4a8faf00e738b8bee4/cf6d9db0bd4d41f59d09ea0a81e918fd-5287d2089db37e62345123a1be272f8 b.mp4"
, "Dumplings grow up.", JzvdStd.SCREEN_WINDOW_NORMAL);
Glide.with(this).load("http://jzvd-pic.nathen.cn/jzvd-pic/1bb2ebbe-140d-4e2e-abd2-9e7e564f71ac.png").into(myJzvdStd.thumbImageView);
Jzvd.setJzUserAction(new MyUserActionStd());
Glide.with(ActivityMain.this)
.load("http://t2.hddhhn.com/uploads/tu/201810/9999/9139710e12.jpg"BitmapTransform (New BlurTransformation(this, 14, 5)).into(myJZVdSTD.mframelayout);Copy the code