为了账号安全,请及时绑定邮箱和手机立即绑定

JiaoZiVideoPlayer使用说明(持续更新中...)

标签:
JavaScript

主要特点

  1. 可以完全自定义UI和任何功能

  2. 一行代码切换播放引擎,支持的视频格式和协议取决于播放引擎,android.media.MediaPlayer ijkplayer

  3. 完美检测列表滑动

  4. 可实现全屏播放,小窗播放

  5. 能在ListView、ViewPager和ListView、ViewPager和Fragment等多重嵌套模式下全屏工作

  6. 可以在加载、暂停、播放等各种状态中正常进入全屏和退出全屏

  7. 多种视频适配屏幕的方式,可铺满全屏,可以全屏剪裁

  8. 重力感应自动进入全屏

  9. 全屏后手势修改进度和音量

  10. Home键退出界面暂停播放,返回界面继续播放

  11. WebView嵌套本地视频控件

  12. demo中添加视频缓存的例子

集成使用

即便是自定义UI,或者对Library有过修改,也是这五步骤来使用播放器。

1.添加类库

compile 'cn.jzvd:jiaozivideoplayer:release'

2.添加布局
<cn.jzvd.JzvdStd
    android:id="@+id/videoplayer"
    android:layout_width="match_parent"
    android:layout_height="200dp"/>
3.设置视频地址、缩略图地址、标题
 MyJzvdStd myJzvdStd= findViewById(R.id.videoplayer);
 myJzvdStd.setUp("http://jzvd.nathen.cn/342a5f7ef6124a4a8faf00e738b8bee4/cf6d9db0bd4d41f59d09ea0a81e918fd-5287d2089db37e62345123a1be272f8b.mp4"
                , "饺子快长大", JzvdStd.SCREEN_WINDOW_NORMAL);
 Glide.with(this).load("http://jzvd-pic.nathen.cn/jzvd-pic/1bb2ebbe-140d-4e2e-abd2-9e7e564f71ac.png").into(myJzvdStd.thumbImageView);
4.在Activity中
 @Override
    protected void onPause() {        super.onPause();
        Jzvd.releaseAllVideos();
    }    @Override
    public void onBackPressed() {        if (Jzvd.backPress()) {            return;
        }        super.onBackPressed();
    }
在AndroidManifest.xml中
<activity
    android:name=".MainActivity"
    android:configChanges="orientation|screenSize|keyboardHidden"
    android:screenOrientation="portrait" /> <!-- or android:screenOrientation="landscape"-->

基本使用

加缩略载图

Glide.with(this).load(Url).into(myJzvdStd.thumbImageView);   //推荐使用Glide

自动播放

1. myJzvdStd.startButton.performClick();
2. myJzvdStd.startVideo();

跳转制定位置播放

//这里只有开始播放时才生效mJzvdStd.seekToInAdvance = 20000;//跳转制定位置播放JZMediaManager.seekTo(30000);

2.播放sd卡下视频

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", "饺子不信",Jzvd.SCREEN_WINDOW_NORMAL, );
这里很多人问为什么播不了,请认真怒url,播不了就是url没怒对

播放assets目录下的视频

       复制Demo中CustomMediaPlayerAssertFolder类到你的项目下
        ----------------------------------------------------------------------------
        JZDataSource jzDataSource = null;        try {
            jzDataSource = new JZDataSource(getAssets().openFd("local_video.mp4"));
            jzDataSource.title = "饺子快长大";
        } 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());//进入此页面修改MediaInterface,让此页面的jzvd正常工作

直接全屏播放

JzvdStd.startFullscreen(this, JzvdStd.class, VideoConstant.videoUrlList[6], "饺子辛苦了");

开启小窗播放

mJzvdStd.startWindowTiny();

列表Item划出开启小窗播放

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);  这是不开启列表划出小窗 同时也是画出屏幕释放JZ 划出暂停
            }
        });2. 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划出屏幕释放JZ,同时也是不开启列表划出显示小窗
    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();
                    }
                }
            }
        });

小屏播放无声音,全屏有声音

创建一个类继承JzvdStd并在XML设置public class JzvdStdVolumeAfterFullscreen extends JzvdStd {    public JzvdStdVolumeAfterFullscreen(Context context) {        super(context);
    }    public JzvdStdVolumeAfterFullscreen(Context context, AttributeSet attrs) {        super(context, attrs);
    }    @Override
    public void onPrepared() {        super.onPrepared();        if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
            JZMediaManager.instance().jzMediaInterface.setVolume(1f, 1f);
        } else {
            JZMediaManager.instance().jzMediaInterface.setVolume(0f, 0f);
        }
    }    /**
     * 进入全屏模式的时候关闭静音模式
     */
    @Override
    public void startWindowFullscreen() {        super.startWindowFullscreen();
        JZMediaManager.instance().jzMediaInterface.setVolume(1f, 1f);
    }    /**
     * 退出全屏模式的时候开启静音模式
     */
    @Override
    public void playOnThisJzvd() {        super.playOnThisJzvd();
        JZMediaManager.instance().jzMediaInterface.setVolume(0f, 0f);
    }
}

全屏状态播放完成,不退出全屏

创建一个类继承JzvdStd并在XML设置public class JzvdStdAutoCompleteAfterFullscreen extends JzvdStd {    public JzvdStdAutoCompleteAfterFullscreen(Context context) {        super(context);
    }    public JzvdStdAutoCompleteAfterFullscreen(Context context, AttributeSet attrs) {        super(context, attrs);
    }    @Override
    public void startVideo() {        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();
        }

    }
}

全屏模式下显示分享按钮

复制DEMO下的layout文件在 layout_top 布局下 添加你的分享按钮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 int getLayoutId() {        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);
        }
    }
}

小屏状态下不显示标题,全屏模式下显示标题

public class JzvdStdShowTitleAfterFullscreen extends JzvdStd {    public JzvdStdShowTitleAfterFullscreen(Context context) {        super(context);
    }    public JzvdStdShowTitleAfterFullscreen(Context context, AttributeSet attrs) {        super(context, attrs);
    }    @Override
    public void setUp(JZDataSource jzDataSource, int screen) {        super.setUp(jzDataSource, screen);        if (currentScreen == SCREEN_WINDOW_FULLSCREEN) {
            titleTextView.setVisibility(View.VISIBLE);
        } else {
            titleTextView.setVisibility(View.INVISIBLE);
        }
    }
}

播放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 真能能修改ui的方法
    @Override
    public void changeUiToNormal() {        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, "饺子摇摆", Jzvd.SCREEN_WINDOW_NORMAL);
        Glide.with(this)
                .load(VideoConstant.videoThumbs[0][1])
                .into(jzvdStdMp3.thumbImageView);

播放完成不显示预览图

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

}

Home键退出界面暂停播放,返回界面继续播放

  @Override
    protected void onResume() {        super.onResume();        //home back
        JzvdStd.goOnPlayOnResume();
    }    @Override
    protected void onPause() {        super.onPause();   //     Jzvd.clearSavedProgress(this, null);
        //home back
        JzvdStd.goOnPlayOnPause();
    }

边播边缓存和清晰度切换

1. 集成videocache implementation 'com.danikula:videocache:2.7.0',并初始化public class ApplicationDemo extends Application {    @Override
    public void onCreate() {        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() {        return new HttpProxyCacheServer(this);
    }
}2.引用
        LinkedHashMap map = new LinkedHashMap();

        String proxyUrl = ApplicationDemo.getProxy(this).getProxyUrl(VideoConstant.videoUrls[0][9]);

        map.put("高清", proxyUrl);
        map.put("标清", VideoConstant.videoUrls[0][6]);
        map.put("普清", VideoConstant.videoUrlList[0]);
        JZDataSource jzDataSource = new JZDataSource(map, "饺子不信");
        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);

重复播放

创建一个类集成JzvdStd并在XML设置public class JZVideoPlayerStandardLoopVideo extends JzvdStd{    public JZVideoPlayerStandardLoopVideo (Context context) {        super(context);
    }    public JZVideoPlayerStandardLoopVideo (Context context, AttributeSet attrs) {        super(context, attrs);
    }    @Override
    public void onAutoCompletion() {        super.onAutoCompletion();
        startVideo();
    }
}
还有一种方法就是上面清晰度切换loop循环标志

重力感应自动进入全屏

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

重力感应

Jzvd.FULLSCREEN_ORIENTATION=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
Jzvd.NORMAL_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
两个变量控制全屏前后的屏幕方向

不保存播放进度

Jzvd.SAVE_PROGRESS = false;

取消播放时在非WIFIDialog提示

Jzvd.WIFI_TIP_DIALOG_SHOWED=true;

清除某个URL进度

 Jzvd.clearSavedProgress(this, "url");

获取视频某一帧

/**
*  context 上下文
*  uri 视频地址
*  imageView 设置image
*  frameTimeMicros 获取某一时间帧
*/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(new BitmapTransformation() {        @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);
}

切换播放内核

ijk
    复制Demo中JZMediaIjkplayer类到你的项目下 
    implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.4'
    implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.4'
    Jzvd.setMediaInterface(new JZMediaIjkplayer());  //  ijkMediaPlayerMediaplayer
    Jzvd.setMediaInterface(new JZMediaSystem());  // exo
    复制Demo中JZExoPlayer类到你的项目下 
    implementation 'com.google.android.exoplayer:exoplayer:2.7.1'
    Jzvd.setMediaInterface(new JZExoPlayer());  //exo

用户埋点统计

    Jzvd.setJzUserAction(new MyUserActionStd());    /**
     * 这只是给埋点统计用户数据用的,不能写和播放相关的逻辑,监听事件请参考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;
            }
        }
    }

相关函数回调,屏幕状态,播放器状态,事件

继承JzvdStd之后,可以通过父类的mCurrentState,取得当前的播放状态。
  • CURRENT_STATE_IDLE 未知状态,指控件被new出来之后什么都没做

  • CURRENT_STATE_NORMAL 普通状态

  • CURRENT_STATE_PREPARING 视频准备状态

  • CURRENT_STATE_PREPARING_CHANGING_URL 播放中切换url的准备状态

  • CURRENT_STATE_PLAYING 播放中状态

  • CURRENT_STATE_PAUSE 暂停状态

  • CURRENT_STATE_AUTO_COMPLETE 自动播放完成状态

  • CURRENT_STATE_ERROR 错误状态

复写进入播放状态的函数,取得播放状态的回调

  • onStateNormal 进入普通状态,通常指setUp之后

  • onStatePreparing 进入准备中状态,就是loading状态

  • onStatePlaying 进入播放状态

  • onStatePause 进入暂停状态

  • onStateError 进入错误状态

  • onStateAutoComplete 进入自动播放完成状态

了解当前屏幕类型

全屏、小窗、非全屏分别是不同的实例,在继承JzvdStd后,通过mCurrentScreen变量,取得当前屏幕类型

  • SCREEN_WINDOW_NORMAL 普通窗口(进入全屏之前的)

  • SCREEN_WINDOW_LIST 列表窗口(进入全屏之前)

  • SCREEN_WINDOW_FULLSCREEN 全屏

  • SCREEN_WINDOW_TINY 小窗

事件

  • 复写onProgress函数,取得每次播放器设置底部seekBar的进度回调

  • 调用changeUrl函数,切换url

  • 复写onClick函数,取得各种按钮的点击事件

  • 复写onTouch函数,取得全屏之后的手势操作

一些需求实现(以下实现都是本人的思考逻辑和借鉴一些网络,不完善,要根据你自己项目实际情况来)

1.会员试看功能
首先从思路上理清步骤

  • 首先拿到当前播放时间和是试看时间做判断(考虑拖动进度条超过试看时间)

  • 从后台拿到特定字段判断是否付费

  • 弹出试看结束功能Dialog

  • 付费完回来继续播放(省去付费步骤)———取消

根据自己项目的实际情况来 ,这里只是简单的测试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);   //退出按钮
        mPay = findViewById(R.id.pay);     //支付按钮
        mTryToSee = findViewById(R.id.try_see);    //重新试看按钮
        mExit.setOnClickListener(this);
        mPay.setOnClickListener(this);
        mTryToSee.setOnClickListener(this);
    }    @Override
    public int getLayoutId() {        return R.layout.try_to_see_video_layout;
    }    @Override
    public void onClick(View v) {        super.onClick(v);        switch (v.getId()) {            case R.id.exit:                //finish界面  建议回调出当前事件
                break;            case R.id.pay:                //进入支付界面  支付成功后 Jzvd.goOnPlayOnResume();
                getContext().startActivity(new Intent(getContext(), ActivityMain.class));  //模拟跳转支付界面
                break;            case R.id.try_see:
                JZMediaManager.seekTo(0);//回到0秒
                Jzvd.goOnPlayOnResume();
                progressBar.setProgress(0);
                mRelativeLayout.setVisibility(GONE);                break;
        }
    }    /**
     * @param progress 百分比
     * @param position 当前时间
     * @param duration 总时长
     */
    @Override
    public void onProgress(int progress, long position, long duration) {        super.onProgress(progress, position, duration);        long totalSeconds = position / 1000;        if (true) {   //这里是从服务器拿到特定字段判断是否付费  这里模拟未付费
            if (totalSeconds >= 30) {   //考虑未付费情况下拖动进度条超过试看时间
                if (!isNoPay) {   //加个标记 因为此函数一直在回调
                    JZMediaManager.seekTo(30000);   //回到30秒
                    progressBar.setProgress(30);
                    mRelativeLayout.setVisibility(VISIBLE);   //在适当的时候隐藏
                    Jzvd.goOnPlayOnPause();           //在适当的时候(支付成功后)播放
                    startButton.setEnabled(false);    //在适当的时候取消
                    isNoPay = true;
                }
            }
        }
    }    @Override
    public void onStatePlaying() {        super.onStatePlaying();
        isNoPay = false;
        startButton.setEnabled(true);
    }
}

2.列表页到详情页无时差播放
3.列表自动播放
4.自动播放下一集剧集

函数 changeUrl  三个重载  根据自己的实际情况来

  • changeUrl(String url, String title, long seekToInAdvance)    //seekToInAdvance 时间

  • changeUrl(JZDataSource jzDataSource, long seekToInAdvance)

  • changeUrl(int urlMapIndex, long seekToInAdvance)
    这里是演示自动播放下一集(如果要自己选集,自定义UI定义出剧集列表,调用上面三个任意一个)

public class AutoPlayNextVideo extends JzvdStd {    int UrlIndex = 0;  //剧集标识
    public AutoPlayNextVideo(Context context) {        super(context);
    }    public AutoPlayNextVideo(Context context, AttributeSet attrs) {        super(context, attrs);
    }    /**
     *    自动播放下一集
     *    若果需要手动选集 自定义Ui定义出剧集列表 调用相关changeUrl
     */
    @Override
    public void onAutoCompletion() {        super.onAutoCompletion();        if (UrlIndex<videoUrlList.length){
            UrlIndex++;
            changeUrl(videoUrlList[UrlIndex], "各剧集的标题", 0);
        }
    }
}



作者:大明小明C
链接:https://www.jianshu.com/p/4c187a09b838


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
JAVA开发工程师
手记
粉丝
205
获赞与收藏
1006

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消