强大的第三方视频播放器。

近来静极思动,决定写一堆博客。

没别的意思,单纯的想****

//小白使用文档

https://shimo.im/docs/xj5F85W1gqEEBXRJ

https://shimo.im/docs/xj5F85W1gqEEBXRJ/read

//简书

https://www.jianshu.com/p/4c187a09b838

//导入依赖  饺子播放器   https://github.com/lipangit/JiaoZiVideoPlayer

//视频播放器
compile 'cn.jzvd:jiaozivideoplayer:6.2.9'

//为了能够带入到项目中使用 需要自定播放器

public class MyJZVideoPlayerStandard extends JZVideoPlayerStandard {
    private Context mContext;
    public MyJZVideoPlayerStandard(Context context) {
        super(context);
        mContext=context;
    }

    public MyJZVideoPlayerStandard(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext=context;
    }

    @Override
    public void init(Context context) {
        super.init(context);
        mContext=context;
    }

    @Override
    public void onClick(View v) {
        super.onClick(v);
    }

    @Override
    public int getLayoutId() {
        return cn.jzvd.R.layout.jz_layout_standard;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return super.onTouch(v, event);
    }

    @Override
    public void startVideo() {
        super.startVideo();
    }

    @Override
    public void onStateNormal() {
        super.onStateNormal();
    }

    @Override
    public void onStatePreparing() {
        super.onStatePreparing();
    }

    @Override
    public void onStatePlaying() {
        super.onStatePlaying();
        if(MusicService.isPlaying){ 
            EventBus.getDefault().postSticky(new MusicData(false,0));
            Intent intent = new Intent(mContext, MusicService.class);
            intent.setAction(MusicService.ACTION_Pause);
            mContext.startService(intent);
        }else{
            Toast.makeText(mContext, "没有在播放", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onStatePause() {
        super.onStatePause();
    }

    @Override
    public void onStateError() {
        super.onStateError();
    }

    @Override
    public void onStateAutoComplete() {
        super.onStateAutoComplete();
    }

    @Override
    public void onInfo(int what, int extra) {
        super.onInfo(what, extra);
    }

    @Override
    public void onError(int what, int extra) {
        super.onError(what, extra);
    }

    @Override
    public void startWindowFullscreen() {
        super.startWindowFullscreen();
    }

    @Override
    public void startWindowTiny() {
        super.startWindowTiny();
    }

}

//xml

 <com.as.apprehendschool.customviews.MyJZVideoPlayerStandard
            android:id="@+id/videoplayer"
            android:layout_width="match_parent"
            android:layout_height="@dimen/x390" />

 


//使用

/**
 * 视频分类  公共适配器  item   video  common
 */
public class SpflRecyclerAdapter extends BaseQuickAdapter<SPfenleiBean.DataBean, BaseViewHolder> {


    public SpflRecyclerAdapter(int layoutResId, @Nullable List<SPfenleiBean.DataBean> data) {
        super(layoutResId, data);
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void convert(BaseViewHolder helper, SPfenleiBean.DataBean item) {
        helper.setText(R.id.tv_Spfl, item.getDescription());
    //  看这里
        final MyJZVideoPlayerStandard videoplayer_Spfl = helper.getView(R.id.videoplayer_Spfl);
        SPfenleiBean.DataBean.VideoBean videoBean = item.getVideo().get(0);
        videoplayer_Spfl.setUp(
                videoBean.getFileurl(), JZVideoPlayer.SCREEN_WINDOW_LIST,
                item.getTitle());
        ImageView thumbImageView = videoplayer_Spfl.thumbImageView;
        GlideLoadImageUtil.load(mContext,item.getThumb(),thumbImageView);
        JZVideoPlayer.FULLSCREEN_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
    }
}

//如果在别的地方需要暂停视频    

boolean playing = JZMediaManager.isPlaying();
if(playing){
    JZVideoPlayer currentJzvd = JZVideoPlayerManager.getCurrentJzvd();
    currentJzvd.onEvent(JZUserAction.ON_CLICK_PAUSE);
    JZMediaManager.pause();
    currentJzvd.onStatePause();
}
//播放时 如果视频开着 先暂停   和上面一样的功能 2选一
                    JZVideoPlayer currentJzvd = JZVideoPlayerManager.getCurrentJzvd();
                    if(currentJzvd!=null){
                        boolean playing = JZMediaManager.isPlaying();
                        if(playing){
                            currentJzvd.onEvent(JZUserAction.ON_CLICK_PAUSE);
                            JZMediaManager.pause();
                            currentJzvd.onStatePause();
                        }
                    }

 

嗯,就这些了。

 


尺寸样式:

 JZVideoPlayerStandard.setVideoImageDisplayType(JZVideoPlayerStandard.FOCUSABLE_AUTO);

还有好多种样式 比如铺满.具体可以点出来 关键字母 在 full  fill auto.

如果样式不没有满足你的要求可以自己修改,遗憾的是 只会加不会减:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/butnostroke11"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:descendantFocusability="blocksDescendants">
    <!--android:background="@android:color/transparent"-->
    <FrameLayout
        android:id="@+id/surface_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!--android:background="@drawable/butnostroke11"-->
    </FrameLayout>

    <!--<ImageView-->
        <!--android:id="@+id/thumb"-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="match_parent"-->
        <!--android:layout_alignParentBottom="true"-->
        <!--android:layout_alignParentLeft="true"-->
        <!--android:layout_alignParentStart="true"-->
        <!--android:scaleType="fitXY" />-->

    <cn.gavinliu.android.lib.shapedimageview.ShapedImageView
        android:id="@+id/thumb"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:scaleType="fitXY"
        app:round_radius="@dimen/x5"
        app:shape_mode="round_rect"
        app:stroke_color="@color/view_e2"
        app:stroke_width="@dimen/x1" />

    <LinearLayout
        android:id="@+id/layout_bottom"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:background="@drawable/jz_bottom_bg"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        android:visibility="invisible">

        <TextView
            android:id="@+id/current"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="14dp"
            android:text="00:00"
            android:textColor="#ffffff" />

        <SeekBar
            android:id="@+id/bottom_seek_progress"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1.0"
            android:background="@null"
            android:max="100"
            android:maxHeight="1dp"
            android:minHeight="1dp"
            android:paddingBottom="8dp"
            android:paddingLeft="12dp"
            android:paddingRight="12dp"
            android:paddingTop="8dp"
            android:progressDrawable="@drawable/jz_bottom_seek_progress"
            android:thumb="@drawable/jz_bottom_seek_thumb" />

        <TextView
            android:id="@+id/total"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00:00"
            android:textColor="#ffffff" />

        <TextView
            android:id="@+id/clarity"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:paddingLeft="20dp"
            android:text="clarity"
            android:textAlignment="center"
            android:textColor="#ffffff" />

        <ImageView
            android:id="@+id/fullscreen"
            android:layout_width="52.5dp"
            android:layout_height="fill_parent"
            android:paddingLeft="14dp"
            android:paddingRight="14dp"
            android:scaleType="centerInside"
            android:src="@drawable/jz_enlarge" />
    </LinearLayout>

    <ProgressBar
        android:id="@+id/bottom_progress"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="1.5dp"
        android:layout_alignParentBottom="true"
        android:max="100"
        android:progressDrawable="@drawable/jz_bottom_progress" />

    <ImageView
        android:id="@+id/back_tiny"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:layout_marginLeft="6dp"
        android:layout_marginTop="6dp"
        android:background="@drawable/jz_click_back_tiny_selector"
        android:visibility="gone" />

    <RelativeLayout
        android:id="@+id/layout_top"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:background="@android:color/transparent"
        android:gravity="center_vertical">

        <ImageView
            android:id="@+id/back"
            android:layout_width="23dp"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:paddingLeft="12dp"
            android:paddingStart="12dp"
            android:scaleType="centerInside"
            android:src="@drawable/jz_click_back_selector" />

        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginEnd="12dp"
            android:layout_marginLeft="12dp"
            android:layout_marginRight="12dp"
            android:layout_marginStart="12dp"
            android:layout_toEndOf="@+id/back"
            android:layout_toLeftOf="@+id/battery_time_layout"
            android:layout_toRightOf="@+id/back"
            android:ellipsize="end"
            android:maxLines="2"
            android:textColor="#ffffff"
            android:textSize="18sp" />

        <LinearLayout
            android:id="@+id/battery_time_layout"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginEnd="14dp"
            android:layout_marginRight="14dp"
            android:gravity="center_vertical"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/battery_level"
                android:layout_width="23dp"
                android:layout_height="10dp"
                android:layout_gravity="center_horizontal"
                android:background="@drawable/jz_battery_level_10" />

            <TextView
                android:id="@+id/video_current_time"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:gravity="center_vertical"
                android:maxLines="1"
                android:textColor="#ffffffff"
                android:textSize="12.0sp" />
        </LinearLayout>
    </RelativeLayout>

    <ProgressBar
        android:id="@+id/loading"
        android:layout_width="@dimen/jz_start_button_w_h_normal"
        android:layout_height="@dimen/jz_start_button_w_h_normal"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:indeterminateDrawable="@drawable/jz_loading"
        android:visibility="invisible" />

    <LinearLayout
        android:id="@+id/start_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_gravity="center_vertical">

        <ImageView
            android:id="@+id/start"
            android:layout_width="@dimen/jz_start_button_w_h_normal"
            android:layout_height="@dimen/jz_start_button_w_h_normal"
            android:src="@drawable/jz_click_play_selector" />
    </LinearLayout>


    <TextView
        android:id="@+id/replay_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/start_layout"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="6dp"
        android:text="@string/replay"
        android:textColor="#ffffff"
        android:textSize="12sp"
        android:visibility="invisible" />

    <LinearLayout
        android:id="@+id/retry_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:gravity="center_horizontal"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/video_loading_faild"
            android:textColor="@android:color/white"
            android:textSize="14sp" />

        <TextView
            android:id="@+id/retry_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            android:background="@drawable/retry_bg"
            android:paddingBottom="4dp"
            android:paddingLeft="9dp"
            android:paddingRight="9dp"
            android:paddingTop="4dp"
            android:text="@string/click_to_restart"
            android:textColor="@android:color/white"
            android:textSize="14sp" />
    </LinearLayout>
</RelativeLayout>

注意id 不可以变.



Android 视频播放器
Android
    1.调用系统播放器,
    2.VideoView  结合 MediaController
    3.SurfaceView +MediaPlayer
    4.第三方视频播放器:UniversalVideoview   JiaoZiVideoPlayer (7K+star)...
    
主要介绍一下JiaoZiVideoPlayer
    
    Manifest:
    android:configChanges="orientation|screenSize|keyboardHidden"
    



    1.高度自定义Ui
    通过自定义 extends  JZVideoPlayerStandard
    @Override
    public int getLayoutId() {
//        return cn.jzvd.R.layout.jz_layout_standard;//默认返回
        return R.layout.custom_jzvideo_palyer;//自定义
    }
    需要注意的是XML资源id不能变,可以修改颜色,添加控件,无ID控件删除.
    
    2.各个阶段的状态
    
    JZVideoPlayerStandard暴露出很多状态方便及时回调,比如:项目里有音乐和视频,要求不能同时播放,在onStatePlaying(视频即将进入播放),可以在这个方法里进行暂停音乐的操作,如果视频需要付费/解锁才能播放,可以在startVideo()这个 方法里进行判断,

    3.多尺寸展示
    Android 手机屏幕视频一般以16:9为主流.视频的尺寸可以自定义全屏铺满,或者视频原尺寸.
    JZVideoPlayerStandard.setVideoImageDisplayType(JZVideoPlayerStandard.FOCUSABLE_AUTO);//原尺寸
    这里有很多,关键字Focusable,auto,screen.
    
    可以通过添加ViewOutlineProvider 为播放界面添加圆角.
    
    4.列表滑动小窗//没用到
    
    5.自带重力感应
    在你手动设置了会禁掉.
//        JZVideoPlayerStandard.FULLSCREEN_ORIENTATION= ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
//        JZVideoPlayerStandard.NORMAL_ORIENTATION = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

  sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        sensorEventListener = new JZVideoPlayerStandard.JZAutoFullscreenListener();

onResume

Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        sensorManager.registerListener(sensorEventListener, accelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);

 

@Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(sensorEventListener);
        JZVideoPlayer.releaseAllVideos();
    }

    6.视频缓存 AndroidVideoCache
        接入简单.Demo 有例子


    7.还提供了JZVideoPlayerManager  JZMediaManager 管理类.
    JZVideoPlayerManager.getCurrentJzvd();获取当前正在播放的播放器
    JZMediaManager.isPlaying();当前是否在播放
    
    //强行暂停!
    currentJzvd.onEvent(JZUserAction.ON_CLICK_PAUSE);
                                JZMediaManager.pause();
                                currentJzvd.onStatePause();

关于有些地方回调没用

可以在fragment不可见;了然后调

@Override
public void onSupportInvisible() {
    super.onSupportInvisible();
    JZVideoPlayer.releaseAllVideos();
}

 


给视频加圆角

videoplayer_spfl.setOutlineProvider(new JzViewOutlineProvider(20));
videoplayer_spfl.setClipToOutline(true);
//可以设计播放页面 圆角
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class JzViewOutlineProvider extends ViewOutlineProvider {
    private float mRadius;
    public JzViewOutlineProvider(float radius) {
        this.mRadius = radius;
    }
    @Override
    public void getOutline(View view, Outline outline) {
//        Rect rect = new Rect();
//        view.getGlobalVisibleRect(rect);
//        int leftMargin = 0;
//        int topMargin = 0;
//        Rect selfRect = new Rect(leftMargin, topMargin,
//                rect.right - rect.left - leftMargin, rect.bottom -    rect.top - topMargin);
//        outline.setRoundRect(selfRect,mRadius);
        outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(),mRadius);
    }
}

这里需要注意的是  如果你设置的宽高和视频不对应的话 ,视频顶部会出现黑线,所以这里也是需要动态设置宽高

//动态设置边距
        LinearLayout ll_commen_root = helper.getView(R.id.ll_commen_root);
        ll_commen_root.setPadding(16,16,16  ,16 );
//注意如果修改XML的话 values-21 也有的
        //这里的视频控件高度设置为:宽度*宽高比9:16  因为设置了一个左右边距
        videoplayer_spfl.getLayoutParams().height=(ScreenUtils.getScreenWidth()-32)*9/16;

补充:  如果当前列表播放的视频离开了屏幕就会让他关闭

 

mViewBinding.rvTuijian.addOnChildAttachStateChangeListener(new RecyclerView.OnChildAttachStateChangeListener() {
            @Override
            public void onChildViewAttachedToWindow(View view) {

            }

            @Override
            public void onChildViewDetachedFromWindow(View view) {
                Jzvd jzvd = view.findViewById(R.id.videoplayer_Spfl);
                if (jzvd != null && jzvd.jzDataSource.containsTheUrl(JZMediaManager.getCurrentUrl())) {
                    Jzvd currentJzvd = JzvdMgr.getCurrentJzvd();
                    if (currentJzvd != null && currentJzvd.currentScreen != Jzvd.SCREEN_WINDOW_FULLSCREEN) {
                        Jzvd.releaseAllVideos();
                    }
                }
            }
        });

之前是Rv 中的可以监听,换成scrollview包裹的话

方法:

在播放中添加接口

//非全屏
    public interface Ibofang {
        void bofang(boolean isbofang, int rvpositon);
    }
//在Rv 中的 位置
    private int rvpositon;
    
    public void setRvpositon(int rvpositon) {
        this.rvpositon = rvpositon;
    }
@Override
    public void startVideo() {

        if (ibofang != null) {
            ibofang.bofang(true, rvpositon);
        }
 @Override
    public void release() {
        super.release();
        if (ibofang != null) {
            ibofang.bofang(false, rvpositon);
        }
    }

在Adapter中绑定

 jzvp.setRvpositon(helper.getAdapterPosition());
                jzvp.setIbofang(this); //在页面中(frag)进行处理
@Override
    public void bofang(boolean isbofang, int rvpositon) {
        if (ilistener != null) {
            ilistener.listen(isbofang, rvpositon);
        }
    }


    public interface Ilistener {
        void listen(boolean isbofang, int rvpositon);
    }

    public Ilistener ilistener;

    public void setIlistener(Ilistener ilistener) {
        this.ilistener = ilistener;
    }

Fragment中定好参数

boolean mIsbofang = false;
    int mRvPosition = 0;

视频播放时会回调

 findTuijianAdapter.setIlistener(new FindTuijianAdapter.Ilistener() {
            @Override
            public void listen(boolean isbofang, int rvpositon) {
                mIsbofang = isbofang;
                mRvPosition = rvpositon;
            }
        });

根据坐标的上移下移最后得到监听

int screenHeight = ScreenUtils.getScreenHeight();
        //顶部栏
        float dimension = getResources().getDimension(R.dimen.x90);
        //底部导航
        float dimension1 = getResources().getDimension(R.dimen.x110);
        //状态栏
        int statusBarHeight = BarUtils.getStatusBarHeight();
        btm_over = screenHeight - statusBarHeight - dimension1;

        mViewBinding.scrollviewFragFind.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

                if (mIsbofang) {
                    View jzvd = (MyJZVideoPlayerStandard) findTuijianAdapter.getViewByPosition(mViewBinding.rvTuijian, mRvPosition, R.id.jzvp);
                    int height = jzvd.getLayoutParams().height;

                    float v1 = height - statusBarHeight - dimension;
//                    System.out.println(" height :" + height); //553
//                    System.out.println(" screenHeight :" + screenHeight);// 2340

                    if (jzvd != null) {

                        int[] location = new int[2];
                        jzvd.getLocationInWindow(location);

                        if (location[1] <= -v1) {
                            Jzvd.releaseAllVideos();
                        } else if (location[1] >= btm_over + height - 100) {
                            Jzvd.releaseAllVideos();
                        }
                    }
                }

            }
        });

 

 

 

 

 

 

 

 

 

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值