Dumpling Video playerDirections for use

The main features

  1. You can fully customize the UI and any functionality
  2. One line of code switching engine, support the video format and protocol depends on the engine, android. Media. The MediaPlayer ijkplayer
  3. Perfect detection list sliding
  4. Can realize full screen play, small window play
  5. It works in full screen mode in multiple nested ListView, ViewPager and ListView, ViewPager and Fragment modes
  6. You can load, pause, play and other states to enter the full screen and exit the full screen
  7. A variety of video screen adaptation, can be spread full screen, can be full screen clipping
  8. Gravity sensor automatically enters full screen
  9. Gestures modify progress and volume after full screen
  10. Home button Exits the interface to pause the playback and return to the interface to continue the playback
  11. WebView nested local video controls
  12. 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