### CCLiveUILib 接入指南

CCLiveUILib 是云直播观看端demo封装sdk，可以远程依赖直接使用，如需要定制UI，请依赖源码或者参考demo源码自行实现观看页面。

#### 1. 版本概览

版本号 | 发布时间 | 描述
--- | --- | ---
4.14.0 | 2023.11.2 | 1. 基于观看端demo4.14.0与dwlivesdk4.14.0

#### 2. 准备工作

开发环境建议：

    Android Studio Electric Eel | 2022.1.1 Patch 2gradle-6.9gradle tool:3.5.3minSdkVersion = 21targetSdkVersion = 33compileSdkVersion = 33buildToolsVersion = "33.0.0"

1. maven配置：

       根目录build.gradle中配置:buildscript {    repositories {        jcenter()        mavenCentral()        google()        maven { url 'https://jitpack.io' }        maven {            url "https://maven.aliyun.com/repository/public/"        }        maven {            url "https://maven.aliyun.com/repository/releases/"        }
           }    dependencies {        classpath 'com.android.tools.build:gradle:3.5.3'    }}
       allprojects {    repositories {        maven { url 'http://nexus-app.bokecc.com/repository/sdk-group/' }        jcenter()        mavenCentral()        google()        maven { url 'https://jitpack.io' }        maven {            url "https://maven.aliyun.com/repository/public/"        }        maven {            url "https://maven.aliyun.com/repository/releases/"        }    }}

2. 引入依赖

       implementation 'com.bokecc:CCLiveUILib:x.x.x'

3. 添加混淆规则

       -keep class com.bokecc.**{*;}-keep public interface com.bokecc.**{*;}-keep public class org.apache.http.**{*;}
       -keep public class tv.**{*;}
       -keep class org.webrtc.**{*;}-keep class com.intel.webrtc.base.**{*;}-keep interface com.intel.webrtc.base.**{*;}
       -keep class com.tencent.**{*;}-keep interface com.tencent.**{*;}
       -dontwarn com.bokecc.sdk.mobile.**-dontwarn com.hd.http.**-keep class com.hd.http.**{ *;}
       -keep class com.alivc.**{*;}-keep class com.aliyun.**{*;}-dontwarn com.alivc.**-dontwarn com.aliyun.**
       -dontwarn com.badlogic.gdx.**
       -keep class com.aliyun.ams.ipdetector.Inet64Util{*;}-keep class com.alibaba.sdk.android.**{*;}-keep class com.ut.**{*;}-keep class com.ta.**{*;}

#### 2. 初始化

    在Application的onCreate中调用如下方法初始化SDK：
    DWApplication.getInstance().initWithoutPrivacy(this);

#### 3. 登录直播间

如果您仅接入播放页面，参考以下代码登录直播间：

    public void loginLive(){        //房间 id 和账户 id，必传        final String roomId = "";        final String accountId = "";        //昵称        final String userName = "";        //密码        String password = "";
            //是否允许截屏        boolean isAllowScreenShot = true;
            //是否是次验证        boolean isSecondVerify = false;

            //额外参数        String viewerCustomUa = "";        String viewerCustomInfo = "";        String groupId = "";
            // TODO:  参数校验         Log.e(TAG,"roomId="+roomId+"");        Log.e(TAG,"accountId="+accountId+"");        Log.e(TAG,"userName="+userName+"");        Log.e(TAG,"password="+password+"");        Log.e(TAG,"viewerCustomUa="+viewerCustomUa+"");        Log.e(TAG,"viewerCustomInfo="+viewerCustomInfo+"");        Log.e(TAG,"isAllowScreenShot="+isAllowScreenShot+"");        Log.e(TAG,"isSecondVerify="+isSecondVerify+"");        Log.e(TAG,"groupId="+groupId+"");
            // 创建登录信息        final LoginInfo loginInfo = new LoginInfo();        loginInfo.setRoomId(roomId);        loginInfo.setUserId(accountId);
            if (!TextUtils.isEmpty(userName)){            loginInfo.setViewerName(userName);        }        if (!TextUtils.isEmpty(password)){            loginInfo.setViewerToken(password);        }
            if (isSecondVerify){            loginInfo.setSecondaryVerify(1);        }
            if (!TextUtils.isEmpty(viewerCustomUa)){            loginInfo.setViewerCustomUa(viewerCustomUa);        }        if (!TextUtils.isEmpty(viewerCustomInfo)){            loginInfo.setViewerCustomInfo(viewerCustomInfo);        }        if (!TextUtils.isEmpty(groupId)){            loginInfo.setGroupId(groupId);        }

            final boolean isAllowScreenShotFinal = isAllowScreenShot;
            checkoutLivePermission(new PermissionCallback() {            @Override            public void onSuccess() {                //新版登录接口（V4.0.0）                DWLive.getInstance().startLogin(loginInfo, new DWLiveLoginListener() {                    @Override                    public void onLogin(TemplateInfo info, Viewer viewer, RoomInfo roomInfo, PublishInfo publishInfo) {                        // TODO:  提示登录成功                         //跳转观看页面                        LivePlayActivity.openActivity(activity, false, accountId,username,roomId,!isAllowScreenShotFinal);                    }
                        @Override                    public void onException(DWLiveException e) {
                        }
                        @Override                    public void onLoginFailed(int i, String s) {                        // TODO:  提示登录失败                    }                });            }
                @Override            public void onFailed() {
                }        });
        }

    private void checkoutLivePermission(final PermissionCallback callback) {        Permissions.request(activity, new String[]{                        Manifest.permission.READ_EXTERNAL_STORAGE,                        Manifest.permission.WRITE_EXTERNAL_STORAGE},                new Permissions.Consumer<Integer>() {                    @Override                    public void accept(Integer integer) {                        if (activity.isFinishing() || activity.isDestroyed()) {                            return;                        }                        callback.onSuccess();                    }                });    }

#### 4. 登录回放房间

     public void loginReplay(){        String roomId = "";        String accountId = "";        final String recordId = "";        String userName = "";        String password = "";
            //是否允许截屏        boolean isAllowScreenShot = true;        //主次验证逻辑        boolean isSecondVerify = false;
            // TODO:  参数校验
            //额外参数        String viewerCustomUa = "";        String viewerCustomInfo = "";        String groupId = "";

            Log.e(TAG,"roomId="+roomId+"");        Log.e(TAG,"accountId="+accountId+"");        Log.e(TAG,"recordId="+recordId+"");        Log.e(TAG,"userName="+userName+"");        Log.e(TAG,"password="+password+"");        Log.e(TAG,"isAllowScreenShot="+isAllowScreenShot+"");        Log.e(TAG,"isSecondVerify="+isSecondVerify+"");        Log.e(TAG,"viewerCustomUa="+viewerCustomUa+"");        Log.e(TAG,"viewerCustomInfo="+viewerCustomInfo+"");        Log.e(TAG,"groupId="+groupId+"");

            // 创建登录信息        final ReplayLoginInfo loginInfo = new ReplayLoginInfo();        loginInfo.setRoomId(roomId);        loginInfo.setUserId(accountId);        loginInfo.setRecordId(recordId);        if (!TextUtils.isEmpty(userName)){            loginInfo.setViewerName(userName);        }        if (!TextUtils.isEmpty(password)){            loginInfo.setViewerToken(password);        }        if (isSecondVerify){            loginInfo.setSecondaryVerify(1);        }        if (!TextUtils.isEmpty(viewerCustomUa)){            loginInfo.setViewerCustomUa(viewerCustomUa);        }        if (!TextUtils.isEmpty(viewerCustomInfo)){            loginInfo.setViewerCustomInfo(viewerCustomInfo);        }        if (!TextUtils.isEmpty(groupId)){            loginInfo.setGroupId(groupId);        }

            final boolean isAllowScreenShotFinal = isAllowScreenShot;
            checkoutReplayPermission(new PermissionCallback() {            @Override            public void onSuccess() {                DWLiveReplay.getInstance().startLogin(loginInfo, new DWLiveReplayLoginListener() {
                        @Override                    public void onLogin(TemplateInfo templateInfo, Marquee marquee) {                        // TODO:  提示登录成功                        // 跳转回放界面                        ReplayPlayActivity.openActivity(activity, false, recordId,!isAllowScreenShotFinal);
                        }
                        @Override                    public void onLoginFailed(int i, String s) {                        // TODO:  提示登录失败                    }
                        @Override                    public void onException(DWLiveException e) {
                        }                });            }
                @Override            public void onFailed() {            }        });
        }
    /**     * 检测回放所需权限     * @param callback     */    private void checkoutReplayPermission(final PermissionCallback callback) {        Permissions.request(activity, new String[]{                        Manifest.permission.READ_EXTERNAL_STORAGE,                        Manifest.permission.WRITE_EXTERNAL_STORAGE},                new Permissions.Consumer<Integer>() {                    @Override                    public void accept(Integer integer) {                        if (activity.isFinishing() || activity.isDestroyed()) {                            return;                        }                        callback.onSuccess();                    }                });
        }

#### 5. 进入离线回放房间

    public void enterLocalReplay(){
            checkoutLocalReplayPermission(new PermissionCallback() {            @Override            public void onSuccess() {                Intent intent = new Intent(activity, DownloadListActivity.class);                activity.startActivity(intent);            }
                @Override            public void onFailed() {                // TODO:  提示获取权限失败            }        });    }    /**     * 检测 离线回放所需权限     * @param callback     */    private void checkoutLocalReplayPermission(final PermissionCallback callback) {        Permissions.request(activity, new String[]{                        Manifest.permission.READ_EXTERNAL_STORAGE,                        Manifest.permission.WRITE_EXTERNAL_STORAGE},                new Permissions.Consumer<Integer>() {                    @Override                    public void accept(Integer integer) {                        if (activity.isFinishing() || activity.isDestroyed()) {                            return;                        }                        if (integer == PERMISSION_GRANTED) {                            callback.onSuccess();                        } else {                            callback.onFailed();                        }
                        }                });
        }

#### 7. 进入入口页面

如果您需要接入入口页面及登录页面，参考以下代码

    xxxxxxxxxxstartActivity(new Intent(SplashActivity.this, PilotActivity.class));