03. Video player Api description

catalogue

  • 01. The simplest play
  • 02. How to switch the video kernel
  • 03. Switch video mode
  • 04. Switch video resolution
  • 05. Monitor video playback
  • 06. Play in the list
  • 07. Play in suspension window
  • 08. Other important function APIS
  • 09. Play multiple videos
  • 10. VideoPlayer related Api
  • 11. The Controller related Api
  • 12. Cache API while playing
  • 13. Similar to Douyin video preloading
  • 14. Video player burial point

00. General framework for video player

  • Basic package video player, can be in ExoPlayer, MediaPlayer, audio network RTC video player kernel, native MediaPlayer can be freely toggle
  • For view state switching and later maintenance expansion, avoid coupling between functions and services. For example, you need to support player UI customization rather than the UI code in the lib library
  • For video playback, audio playback, playback, and live video functions. Simple to use, strong code expansion, good encapsulation, mainly and business completely decoupled, exposed interface monitoring for developers to deal with specific business logic
  • The overall architecture of the player: player kernel (free switching) + video player + play while caching + highly customized PLAYER UI view layer
  • Project address: github.com/yangchong21…
  • About the overall function of the video player: juejin.cn/post/688345…

01. The simplest play

  • The four-step code that must be required is shown below
    // Create basic video player, general player functions
    BasisVideoController controller = new BasisVideoController(this);
    // Set the controller
    mVideoPlayer.setVideoController(controller);
    // Set the video playing link address
    mVideoPlayer.setUrl(url);
    // Start playing
    mVideoPlayer.start();
    Copy the code
  • Start playing
    // Play the video
    videoPlayer.start();
    Copy the code

02. How to switch the video kernel

  • Creating a Video Player
    PlayerFactory playerFactory = IjkPlayerFactory.create();
    IjkVideoPlayer ijkVideoPlayer = (IjkVideoPlayer) playerFactory.createPlayer(this);
    PlayerFactory playerFactory = ExoPlayerFactory.create();
    ExoMediaPlayer exoMediaPlayer = (ExoMediaPlayer) playerFactory.createPlayer(this);
    PlayerFactory playerFactory = MediaPlayerFactory.create();
    AndroidMediaPlayer androidMediaPlayer = (AndroidMediaPlayer) playerFactory.createPlayer(this);
    Copy the code
  • How do I configure the video kernel
    Note: this is the global configuration, for example, the following is the configuration of iJK kernel player
    VideoViewManager.setConfig(VideoPlayerConfig.newBuilder()
            .setLogEnabled(true)// Enable log for debugging
            .setPlayerFactory(IjkPlayerFactory.create())
            .build());
    Copy the code
  • Switch video kernel processing code
    @SuppressLint("SetTextI18n")
    private void setChangeVideoType(@ConstantKeys.PlayerType int type){
        // Switch the playback core. This is not recommended. I wrote this just for testing purposes
        VideoPlayerConfig config = VideoViewManager.getConfig();
        try {
            Field mPlayerFactoryField = config.getClass().getDeclaredField("mPlayerFactory");
            mPlayerFactoryField.setAccessible(true);
            PlayerFactory playerFactory = null;
            switch (type) {
                case ConstantKeys.VideoPlayerType.TYPE_IJK:
                    playerFactory = IjkPlayerFactory.create();
                    mTvTitle.setText(Video Kernel: + " (IjkPlayer)");
                    break;
                case ConstantKeys.VideoPlayerType.TYPE_EXO:
                    playerFactory = ExoPlayerFactory.create();
                    mTvTitle.setText(Video Kernel: + " (ExoPlayer)");
                    break;
                case ConstantKeys.VideoPlayerType.TYPE_NATIVE:
                    playerFactory = MediaPlayerFactory.create();
                    mTvTitle.setText(Video Kernel: + " (MediaPlayer)");
                    break;
                case ConstantKeys.VideoPlayerType.TYPE_RTC:
                    break;
            }
            mPlayerFactoryField.set(config, playerFactory);
        } catch(Exception e) { e.printStackTrace(); }}Copy the code

03. Switch video mode

  • About the full screen mode API
    // Go to full screen
    mVideoPlayer.startFullScreen();
    // Exit full screen
    mVideoPlayer.stopFullScreen();
    Copy the code
  • About small window play related API
    // Enable the small screen
    mVideoPlayer.startTinyScreen();
    // Exit the small screen
    mVideoPlayer.stopTinyScreen();
    Copy the code

04. Switch video resolution

05. Monitor video playback

  • This is divided into two parts: the first part is the playback mode listener, the second part is the playback state listener, exposed to the developer. It is not recommended to use 0,1 here, because it is very inconvenient and concise.
    MVideoPlayer. SetOnStateChangeListener (new OnVideoStateListener () {/ * * * * play pattern mode, small window mode, Normal mode One of the three modes * MODE_NORMAL Normal mode * MODE_FULL_SCREEN mode * MODE_TINY_WINDOW small screen mode * @param playerState Playing mode */ @override public void onPlayerStateChanged(int playerState) { switch (playerState) { case ConstantKeys.PlayMode.MODE_NORMAL: // Normal mode break; Case ConstantKeys. PlayMode. MODE_FULL_SCREEN: / / break full-screen mode; Case ConstantKeys. PlayMode. MODE_TINY_WINDOW: / / break small screen mode; }} /** ** Playing status * -1 playing error * 0 Playing not started * 1 Playing ready * 2 Playing ready * 3 Playing * 4 Pausing * 5 Buffering (when the player is playing and the buffer data is insufficient, buffering, Resume playing after buffer data is enough) * 6 pause buffer (when player is playing, buffer data is insufficient, pause player, continue buffering, resume pause after buffer data is enough * 7 finish playing * 8 start playing stop * @param playState playState, */ @override public void onPlayStateChanged(int playState) {switch (playState) {case ConstantKeys. CurrentState. STATE_IDLE: / / play did not start, initialization break; Case ConstantKeys. CurrentState. STATE_START_ABORT: / / start playing to suspend the break; Case ConstantKeys. CurrentState. STATE_PREPARING: / / play to break; Case ConstantKeys. CurrentState. STATE_PREPARED: / / play ready break; Case ConstantKeys. CurrentState. STATE_ERROR: false break / / play. Case ConstantKeys. CurrentState. STATE_BUFFERING_PLAYING: / / are buffer break; Case ConstantKeys. CurrentState. STATE_PLAYING: / / there is break; Case ConstantKeys. CurrentState. STATE_PAUSED: play/pause/break; Case ConstantKeys. CurrentState. STATE_BUFFERING_PAUSED: / / suspended buffer break; Case ConstantKeys. CurrentState. STATE_COMPLETED: / / play complete break; }}});Copy the code

06. Play it in a list

  • Step 1: initialize the VideoPlayer and create the VideoPlayer object
    mVideoView = new VideoPlayer(context);
    mVideoView.setOnStateChangeListener(new VideoPlayer.SimpleOnStateChangeListener() {
        @Override
        public void onPlayStateChanged(int playState) {
            // Listen for the Release of VideoViewManager and reset the state
            if (playState == ConstantKeys.CurrentState.STATE_IDLE) {
                PlayerUtils.removeViewFormParent(mVideoView);
                mLastPos = mCurPos;
                mCurPos = -1; }}}); mController =new BasisVideoController(context);
    mVideoView.setController(mController);
    Copy the code
  • Step 2: Set up RecyclerView and Adapter
    mAdapter.setOnItemChildClickListener(new OnItemChildClickListener() { @Override public void onItemChildClick(int Position) {// Click item to play video startPlay(position); }}); mRecyclerView.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() { @Override public  void onChildViewAttachedToWindow(@NonNull View view) { } @Override public void onChildViewDetachedFromWindow(@NonNull View view) { FrameLayout playerContainer = view.findViewById(R.id.player_container); View v = playerContainer.getChildAt(0); if (v ! = null && v == mVideoView && ! Mvideoview.isfullscreen ()) {// Destroy video releaseVideoView(); }}});Copy the code
  • Step 3: Play video and destroy video logic code
    /** * start playing *@paramPosition List position */
    protected void startPlay(int position) {
        if (mCurPos == position) return;
        if(mCurPos ! = -1) {
            releaseVideoView();
        }
        VideoInfoBean videoBean = mVideos.get(position);
        mVideoView.setUrl(videoBean.getVideoUrl());
        View itemView = mLinearLayoutManager.findViewByPosition(position);
        if (itemView == null) return;
        VideoRecyclerViewAdapter.VideoHolder viewHolder = (VideoRecyclerViewAdapter.VideoHolder) itemView.getTag();
        // Add the PrepareView from the list to the controller. Note that isPrivate can only be true.
        mController.addControlComponent(viewHolder.mPrepareView, true);
        PlayerUtils.removeViewFormParent(mVideoView);
        viewHolder.mPlayerContainer.addView(mVideoView, 0);
        // Add VideoView to VideoViewManager before playing so that you can manipulate it on other pages
        VideoViewManager.instance().add(mVideoView, "list");
        mVideoView.start();
        mCurPos = position;
    }
    
    private void releaseVideoView(a) {
        mVideoView.release();
        if (mVideoView.isFullScreen()) {
            mVideoView.stopFullScreen();
        }
        if(getActivity().getRequestedOrientation() ! = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } mCurPos = -1;
    }
    Copy the code

08. Other important function APIS

  • Set the video player background and video title.
    BasisVideoController (BasisVideoController
    // Set the video background
    ImageView thumb = controller.getThumb();
    Glide.with(this).load(R.drawable.image_default).into(controller.getThumb());
    // Set the video title
    controller.setTitle("Video Title");
    Copy the code
  • Check whether the screen is locked
    // Determine whether to lock the screen
    boolean locked = controller.isLocked();
    // Set whether to lock the screen
    controller.setLocked(true);
    Copy the code
  • Set the zoom type for playing a video. Borrowed from the web blog, similar to picture zooming. The 16:9 type is recommended
    mVideoPlayer.setScreenScaleType(ConstantKeys.PlayerScreenScaleType.SCREEN_SCALE_16_9);
    mVideoPlayer.setScreenScaleType(ConstantKeys.PlayerScreenScaleType.SCREEN_SCALE_DEFAULT);
    mVideoPlayer.setScreenScaleType(ConstantKeys.PlayerScreenScaleType.SCREEN_SCALE_4_3);
    mVideoPlayer.setScreenScaleType(ConstantKeys.PlayerScreenScaleType.SCREEN_SCALE_MATCH_PARENT);
    mVideoPlayer.setScreenScaleType(ConstantKeys.PlayerScreenScaleType.SCREEN_SCALE_ORIGINAL);
    mVideoPlayer.setScreenScaleType(ConstantKeys.PlayerScreenScaleType.SCREEN_SCALE_CENTER_CROP);
    Copy the code

09. Play multiple videos

  • Here is an example, for example, playing two videos at the same time, of course, this situation may be less in the app
    // Must be set
    player1.setUrl(VOD_URL_1);
    VideoPlayerBuilder.Builder builder = VideoPlayerBuilder.newBuilder();
    builder.setEnableAudioFocus(false);
    VideoPlayerBuilder videoPlayerBuilder = new VideoPlayerBuilder(builder);
    player1.setVideoBuilder(videoPlayerBuilder);
    BasisVideoController controller1 = new BasisVideoController(this);
    player1.setController(controller1);
    mVideoViews.add(player1);
    
    // Must be set
    player2.setUrl(VOD_URL_2);
    VideoPlayerBuilder.Builder builder2 = VideoPlayerBuilder.newBuilder();
    builder.setEnableAudioFocus(false);
    VideoPlayerBuilder videoPlayerBuilder2 = new VideoPlayerBuilder(builder2);
    player2.setVideoBuilder(videoPlayerBuilder2);
    BasisVideoController controller2 = new BasisVideoController(this);
    player2.setController(controller2);
    mVideoViews.add(player2);
    Copy the code
  • So if the page switches to background, how to handle multiple video pause function? As follows:
    @Override
    protected void onPause(a) {
        super.onPause();
        for(VideoPlayer vv : mVideoViews) { vv.pause(); }}@Override
    protected void onResume(a) {
        super.onResume();
        for(VideoPlayer vv : mVideoViews) { vv.pause(); }}@Override
    protected void onDestroy(a) {
        super.onDestroy();
        for(VideoPlayer vv : mVideoViews) { vv.release(); }}@Override
    public void onBackPressed(a) {
        for (VideoPlayer vv : mVideoViews) {
            if (vv.onBackPressed())
                return;
        }
        super.onBackPressed();
    }
    Copy the code

10. VideoPlayer related Api

  • The apis for video playback are shown below
    // Pause the playback
    mVideoPlayer.pause();
    // Call back when the video is buffered and ready to play
    mVideoPlayer.onPrepared();
    // Rerun
    mVideoPlayer.replay(true);
    // Continue playing
    mVideoPlayer.resume();
    // Adjust the playback progress
    mVideoPlayer.seekTo(100);
    // Play in a loop. By default, no loop is played
    mVideoPlayer.setLooping(true);
    // Set the playback speed
    mVideoPlayer.setSpeed(1.1 f);
    // Set the volume between 0.0f and 1.0f
    mVideoPlayer.setVolume(1.1);
    // Start playing
    mVideoPlayer.start();
    Copy the code
  • API about video switching playback mode
    // Check whether the screen is in full screen state
    boolean fullScreen = mVideoPlayer.isFullScreen();
    // Whether it is small window mode
    boolean tinyScreen = mVideoPlayer.isTinyScreen();
    // Go to full screen
    mVideoPlayer.startFullScreen();
    // Exit full screen
    mVideoPlayer.stopFullScreen();
    // Enable the small screen
    mVideoPlayer.startTinyScreen();
    // Exit the small screen
    mVideoPlayer.stopTinyScreen();
    Copy the code
  • About other apis such as getting speed, volume, setting properties
    / / VideoPlayer related
    VideoPlayerBuilder.Builder builder = VideoPlayerBuilder.newBuilder();
    VideoPlayerBuilder videoPlayerBuilder = new VideoPlayerBuilder(builder);
    // Set the background color of the video player
    builder.setPlayerBackgroundColor(Color.BLACK);
    // Set the width and height of the small screen
    int[] mTinyScreenSize = {0.0};
    builder.setTinyScreenSize(mTinyScreenSize);
    // Whether to enable AudioFocus listening. This function is enabled by default
    builder.setEnableAudioFocus(false);
    mVideoPlayer.setVideoBuilder(videoPlayerBuilder);
    / / screenshots
    Bitmap bitmap = mVideoPlayer.doScreenShot();
    // Remove all playback status listeners
    mVideoPlayer.clearOnStateChangeListeners();
    // Get the current buffer percentage
    int bufferedPercentage = mVideoPlayer.getBufferedPercentage();
    // Get the current player status
    int currentPlayerState = mVideoPlayer.getCurrentPlayerState();
    // Get the current playback status
    int currentPlayState = mVideoPlayer.getCurrentPlayState();
    // Get the current playing position
    long currentPosition = mVideoPlayer.getCurrentPosition();
    // Get the total video duration
    long duration = mVideoPlayer.getDuration();
    // Get the double speed
    float speed = mVideoPlayer.getSpeed();
    // Get the buffer speed
    long tcpSpeed = mVideoPlayer.getTcpSpeed();
    // Get the video width and height
    int[] videoSize = mVideoPlayer.getVideoSize();
    // Whether to mute
    boolean mute = mVideoPlayer.isMute();
    Copy the code

11. The Controller related Api

  • Controller This section describes the APIS of controllers
    // Set the video background
    ImageView thumb = controller.getThumb();
    Glide.with(this).load(R.drawable.image_default).into(controller.getThumb());
    // Set the video title
    controller.setTitle("Video Title");
    // Add a custom view. Each view added is the top level of the mode hierarchy tree
    CustomErrorView customErrorView = new CustomErrorView(this);
    controller.addControlComponent(customErrorView);
    // Remove the control component
    controller.removeControlComponent(customErrorView);
    // Remove all components
    controller.removeAllControlComponent();
    // Hide the play view
    controller.hide();
    // Displays the playback view
    controller.show();
    // Whether to enable full screen entry/exit based on screen orientation
    controller.setEnableOrientation(true);
    // Display mobile network playback prompt
    controller.showNetWarning();
    // The height of the fringe
    int cutoutHeight = controller.getCutoutHeight();
    // Whether there are bangs
    boolean b = controller.hasCutout();
    // Set whether to fit the bangs screen
    controller.setAdaptCutout(true);
    // Stop the refresh progress
    controller.stopProgress();
    // Start to refresh the progress. Note that you need to invoke STATE_PLAYING to start refreshing the progress
    controller.startProgress();
    // Determine whether to lock the screen
    boolean locked = controller.isLocked();
    // Set whether to lock the screen
    controller.setLocked(true);
    // Cancel the timer
    controller.stopFadeOut();
    // Start the timer
    controller.startFadeOut();
    // Set the playback view to automatically hide timeout
    controller.setDismissTimeout(8);
    / / destroy
    controller.destroy();
    Copy the code

12. Cache API while playing

  • As shown below.
    controller = new BasisVideoController(this);
    // Set the video background
    Glide.with(this).load(R.drawable.image_default).into(controller.getThumb());
    // Set the controller
    mVideoPlayer.setController(controller);
    HttpProxyCacheServer server = new HttpProxyCacheServer(this);
    String proxyVideoUrl = server.getProxyUrl(URL_AD);
    mVideoPlayer.setUrl(proxyUrl);
    mVideoPlayer.start();
    Copy the code

13. Similar to Douyin video preloading

  • As shown below, this is for ViewPager
    // Get the PreloadManager preloaded manager object
    mPreloadManager = PreloadManager.getInstance(this);
    // While the video is playing
    String playUrl = mPreloadManager.getPlayUrl(url);
    VideoLogUtils.i("startPlay: " + "position: " + position + " url: " + playUrl);
    mVideoPlayer.setUrl(playUrl);
    // While the page is scrolling
    mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageScrollStateChanged(int state) {
            super.onPageScrollStateChanged(state);
            if (state == VerticalViewPager.SCROLL_STATE_IDLE) {
                mPreloadManager.resumePreload(mCurPos, mIsReverseScroll);
            } else{ mPreloadManager.pausePreload(mCurPos, mIsReverseScroll); }}});Copy the code
  • As shown below, this is for RecyclerView
    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        /** * Whether to reverse slide */
        private boolean mIsReverseScroll;
    
        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if (dy>0) {// indicates a slide
                mIsReverseScroll = false;
            } else {
                // indicates slide up
                mIsReverseScroll = true; }}@Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            if (newState == VerticalViewPager.SCROLL_STATE_IDLE) {
                mPreloadManager.resumePreload(mCurPos, mIsReverseScroll);
            } else{ mPreloadManager.pausePreload(mCurPos, mIsReverseScroll); }}});Copy the code

14. Video player burial point

  • BuriedPointEvent (BuriedPointEvent) You can bury video playback times, playback progress, click video advertising, convenient unified management
public class BuriedPointEventImpl implements BuriedPointEvent {

    /** * Enter video playback *@paramUrl Video URL */
    @Override
    public void playerIn(String url) {}/** * Exit the video *@paramUrl Video URL */
    @Override
    public void playerDestroy(String url) {}/** * The video has finished playing *@paramUrl Video URL */
    @Override
    public void playerCompletion(String url) {}/** * Abnormal video playback *@paramUrl Video URL *@paramIsNetError Whether the network is abnormal */
    @Override
    public void onError(String url, boolean isNetError) {}/** * Click on the video AD *@paramUrl Video URL */
    @Override
    public void clickAd(String url) {}/** * Exit the playback progress of the video@paramUrl Video URL *@paramProgress Video progress, calculate percentage [exit progress/total progress] */
    @Override
    public void playerOutProgress(String url, float progress) {}/** * Video switch audio *@paramUrl Video URL */
    @Override
    public void videoToMedia(String url) {}}Copy the code

15. Player sample display diagram