记录:uni-app 开发原生组件视频通话的总结

由于本人不会原生,因此原生的东西整起来十分费劲,但最终还是好了 URTC视频通话,由于之前同事整的URTC版本较低 ,导致视频通过过程大多数情况是没有声音的,和客服沟通后让我升级sdk试试
如下部分代码可见 Uni-app官网原生插件开发可见.
一、Uni-app的配置如下:

1、 图中common-2.12.4.arr,libuvccamera-release.arr,ucloudrtclib-2.1.4.arr 这三个arr包 为URTC提供的android包,放进去就行,主要是uniplugin_urtc-release.aar 这个包 需要用android studio打包生存的
2、关于package.json里的配置
"plugins": [
{
"type": "module",
"name": "chkj-urtc", //原生插件名称
"class": "com.chkj.urtc.URTCModule" //原生插件代码里自己创建的类 具体参考Uni-app原生插件开发
}
],
"hooksClass": "com.chkj.urtc.URTCAppHookProxy", //uni-app原生插件配置代理跳转入口
"integrateType": "aar",
3、引入原生插件

二、android studio打开下载好的sdk代码
1、创建Module uniplugin_urtc 将sdk里的代码剪切到这个module里

2、lib文件夹

3、uniplugin_urtc的build.gradle配置
//plugins {
// id 'com.android.application'
//}
apply plugin: 'com.android.library' //代表是个插件

android {
compileSdkVersion 26
defaultConfig {
minSdkVersion rootProject.minSdkVersion
compileSdkVersion rootProject.compileSdkVersion
buildToolsVersion rootProject.buildToolsVersion
targetSdkVersion rootProject.targetSdkVersion
versionName rootProject.versionName
versionCode 44
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
}

lintOptions {
    checkReleaseBuilds false
    // Or, if you prefer, you can continue to check for errors in release builds,
    // but continue the build even when errors are found:
    abortOnError false
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}
compileOptions {
    sourceCompatibility = '1.8'
    targetCompatibility = '1.8'
}

}
repositories {
flatDir {
dirs 'libs'
}
}
dependencies {
compileOnly fileTree(include: ['.jar', '.aar'], dir: 'libs')
// implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'com.android.support.test🏃1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

// compileOnly 'com.android.support:appcompat-v7:28.0.0'
// compileOnly 'com.android.support:recyclerview-v7:28.0.0'
// compileOnly 'com.android.support:support-v4:28.0.0'
implementation var.SupportV7
implementation var.SupportV4
implementation var.SupportRecyclerviewV7
implementation 'com.squareup.okhttp3:okhttp:3.9.1'
//bugly
implementation 'com.tencent.bugly:crashreport:latest.release'
implementation 'com.tencent.bugly:nativecrashreport:latest.release'
implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
implementation 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'

compileOnly 'com.alibaba:fastjson:1.1.46.android'
compileOnly fileTree(include: ['uniapp-v8-release.aar'], dir: '../app/libs')

compileOnly(name: 'ucloudrtclib-2.1.4', ext: 'aar')
compileOnly(name: 'libuvccamera-release', ext: 'aar')
compileOnly(name: 'common-2.12.4', ext: 'aar')

}
4、URTCAppHookProxy
package com.chkj.urtc;

import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.text.TextUtils;

import com.ucloudrtclib.sdkengine.UCloudRtcSdkEnv;
import com.ucloudrtclib.sdkengine.define.UCloudRtcSdkLogLevel;

import io.dcloud.feature.uniapp.UniAppHookProxy;

public class URTCAppHookProxy implements UniAppHookProxy {

@Override
public void onCreate(Application application) {
    if (TextUtils.equals(getCurrentProcessName(application), application.getPackageName())) {
        init(application);
    }
}

@Override
public void onSubProcessCreate(Application application) {
    if (TextUtils.equals(getCurrentProcessName(application), application.getPackageName())) {
        init(application);
    }
}

private void init(Application application) {
    // 初始化SDK
    UCloudRtcSdkEnv.initEnv(application);
    // 打印日志到logcat
    UCloudRtcSdkEnv.setWriteToLogCat(true);
    // 开启日志上报
    UCloudRtcSdkEnv.setLogReport(true);
    // logo日志等级
    UCloudRtcSdkEnv.setLogLevel(UCloudRtcSdkLogLevel.UCLOUD_RTC_SDK_LogLevelNone);
}

private String getCurrentProcessName(Context context) {
    int pid = android.os.Process.myPid();
    ActivityManager mActivityManager = (ActivityManager) context
            .getSystemService(Context.ACTIVITY_SERVICE);
    for (ActivityManager.RunningAppProcessInfo appProcess : mActivityManager
            .getRunningAppProcesses()) {
        if (appProcess.pid == pid) {
            return appProcess.processName;
        }
    }
    return null;
}

}
5、URTCModule
package com.chkj.urtc;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.view.WindowManager;

import com.alibaba.fastjson.JSONObject;
import com.chkj.urtc.Application.UCloudRtcApplication;
import com.chkj.urtc.activity.ConnectActivity;
import com.chkj.urtc.activity.RoomActivity;
import com.chkj.urtc.common.Config;
import com.chkj.urtc.utils.CommonUtils;
import com.chkj.urtc.utils.PermissionUtils;
import com.taobao.weex.annotation.JSMethod;
import com.taobao.weex.bridge.JSCallback;
import com.ucloudrtclib.sdkengine.UCloudRtcSdkEnv;
import com.ucloudrtclib.sdkengine.define.UCloudRtcSdkMode;
import com.ucloudrtclib.sdkengine.define.UCloudRtcSdkPushEncode;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import io.dcloud.feature.uniapp.common.UniModule;

public class URTCModule extends UniModule {

private Handler mMainHandler = new Handler(Looper.getMainLooper());
private Context mContext = null;
private final JSONObject result = new JSONObject();

@JSMethod(uiThread = false)
public void join(JSONObject params, final JSCallback callback) {
    if (params == null) {
        result.put("code", -1);
        result.put("msg", "请填写参数配置");
        callback.invokeAndKeepAlive(result);
        return;
    }

    if (mWXSDKInstance != null) mContext =  mWXSDKInstance.getContext();

    int openCamera = params.getIntValue("openCamera");
    String appKey = params.getString("appKey");
    String appId = params.getString("appId");
    String roomId = params.getString("roomId");
    String uerId = params.getString("uerId");
    String token = params.getString("token");
    int connect = params.getIntValue("connect");
    boolean debugModel = params.getBooleanValue("debugModel");

    if (TextUtils.isEmpty(appKey)) {
        result.put("code", -1);
        result.put("msg", "请填写appKey");
        callback.invokeAndKeepAlive(result);
        return;
    }
    if (TextUtils.isEmpty(appId)) {
        result.put("code", -1);
        result.put("msg", "请填写appId");
        callback.invokeAndKeepAlive(result);
        return;
    }
    if (TextUtils.isEmpty(roomId)) {
        result.put("code", -1);
        result.put("msg", "请填写roomId");
        callback.invokeAndKeepAlive(result);
        return;
    }
    if (TextUtils.isEmpty(uerId)) {
        result.put("code", -1);
        result.put("msg", "请填写uerId");
        callback.invokeAndKeepAlive(result);
        return;
    }
    if (TextUtils.isEmpty(token)) {
        result.put("code", -1);
        result.put("msg", "请填写token");
        callback.invokeAndKeepAlive(result);
        return;
    }

    //检测是否拥有camera权限
    if (!checkPermissions(Manifest.permission.CAMERA)) {
        if (callback != null) {
            result.put("code", -1);
            result.put("msg", "插件需要[Manifest.permission.CAMERA]权限,请申请!");
            callback.invokeAndKeepAlive(result);
        }
        return;
    }
    //检测是否拥有文件写入权限
    if (!checkPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        if (callback != null) {
            result.put("code", -1);
            result.put("msg", "插件需要[Manifest.permission.WRITE_EXTERNAL_STORAGE]权限,请申请!");
            callback.invokeAndKeepAlive(result);
        }
        return;
    }
    //检测是否拥有录音权限
    if (!checkPermissions(Manifest.permission.RECORD_AUDIO)) {
        if (callback != null) {
            result.put("code", -1);
            result.put("msg", "插件需要[Manifest.permission.RECORD_AUDIO]权限,请申请!");
            callback.invokeAndKeepAlive(result);
        }
        return;
    }

// List needPermissions = new ArrayList<>();
// needPermissions.add(Manifest.permission.CAMERA);
// needPermissions.add(Manifest.permission.RECORD_AUDIO);
// needPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
// needPermissions.add(Manifest.permission.READ_PHONE_STATE);
//
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
// needPermissions.add(Manifest.permission.BLUETOOTH_SCAN);
// needPermissions.add(Manifest.permission.BLUETOOTH_CONNECT);
// }
// String[] requestPermissions = new String[needPermissions.size()];
// needPermissions.toArray(requestPermissions);
// PermissionUtils.needsPermissions(mContext, requestPermissions);
// Thread thread = new Thread(new RoomActivity.CopyMixFileTask(this));
// thread.start();

    // 配置参数
    Config config = Config.getInstance();
    config.setOpenCamera(openCamera);
    config.setAppId(appId);
    config.setAppKey(appKey);
    config.setRoomId(roomId);
    config.setUerId(uerId);
    config.setToken(token);
    if (connect == 0) {
        connect = 60;
    }
    config.setConnect(connect);
    config.setDebugModel(debugModel);

    UCloudRtcSdkEnv.setEncodeMode(UCloudRtcSdkPushEncode.UCLOUD_RTC_PUSH_ENCODE_MODE_H264);
    /**
     * 设置SDK模式
     *      UCLOUD_RTC_SDK_MODE_TRIVAL: 测试模式
     *      UCLOUD_RTC_SDK_MODE_NORMAL: 正式模式
     */
    UCloudRtcSdkEnv.setSdkMode(config.isDebugModel() ? UCloudRtcSdkMode.UCLOUD_RTC_SDK_MODE_TRIAL : UCloudRtcSdkMode.UCLOUD_RTC_SDK_MODE_NORMAL);
    // 设置重连次数,-1为无限重连
    UCloudRtcSdkEnv.setReConnectTimes(config.getConnect());
    UCloudRtcSdkEnv.setTokenSecKey(config.getAppKey());
    WindowManager windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics outMetrics = new DisplayMetrics();
    if (windowManager != null) {
        windowManager.getDefaultDisplay().getMetrics(outMetrics);
    }
    CommonUtils.mItemWidth = outMetrics.widthPixels / 3;
    CommonUtils.mItemHeight = CommonUtils.mItemWidth;

    // 跳转房间页面

// final Intent intent = new Intent(mContext, RoomActivity.class);
final Intent intent = new Intent(mContext, ConnectActivity.class);
// final Intent intent = new Intent(mContext, UCloudRtcApplication.class);

    intent.putExtra("room_id", roomId);
    intent.putExtra("user_id", uerId);
    intent.putExtra("app_id", appId);
    intent.putExtra("token", token);
    intent.putExtra("join_channel", true);
    mMainHandler.postDelayed(new Runnable() {
        @Override
        public void run() {

// startActivity(intent);
// finish();
mContext.startActivity(intent);
}
}, 500);

// mContext.startActivity(new Intent(mContext, RoomActivity.class));
// mContext.startActivity(new Intent(mContext, ConnectActivity.class));

}

private boolean checkPermissions(String permission) {
    boolean result = false;
    if (Build.VERSION.SDK_INT >= 23) {
        int hasPer = mContext.checkSelfPermission(permission);
        if (hasPer == PackageManager.PERMISSION_GRANTED) {
            result = true;
        }
    } else {
        result = true;
    }
    return result;
}

}

三、sdk代码
1、gradle配置
apply plugin: 'com.android.application' //可运行app
//apply plugin: 'com.android.library'

android {
compileSdkVersion 26
defaultConfig {
applicationId "com.chkj.urtctest"
minSdkVersion rootProject.minSdkVersion
compileSdkVersion rootProject.compileSdkVersion
buildToolsVersion rootProject.buildToolsVersion
targetSdkVersion rootProject.targetSdkVersion
versionName rootProject.versionName
versionCode 44
ndk {
abiFilters "armeabi-v7a", "arm64-v8a"
}
}

// lintOptions {
// checkReleaseBuilds false
// // Or, if you prefer, you can continue to check for errors in release builds,
// // but continue the build even when errors are found:
// abortOnError false
// }

signingConfigs {
    config {
        storeFile file('****.jks')
        storePassword '****'
        keyAlias = '****'
        keyPassword '***'
    }
}


buildTypes {

// release {
// minifyEnabled true
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// signingConfig signingConfigs.release
// }
// debug {
// signingConfig signingConfigs.release
// }
debug {
signingConfig signingConfigs.config
}
release {
signingConfig signingConfigs.config
}
}

// sourceSets {
// main {
// jniLibs.srcDirs = ["/src/main/jniLibs"]
// }
// }
//使用uniapp时,需复制下面代码
/代码开始/
aaptOptions {
additionalParameters '--auto-add-overlay'
//noCompress 'foo', 'bar'
ignoreAssetsPattern "!.svn:!.git:.:!CVS:!thumbs.db:!picasa.ini:!.scc:~"
}
/
代码结束*/
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
repositories {
flatDir {
dirs 'libs'
}
}
}

dependencies {
// implementation fileTree(include: ['*.jar'], dir: 'libs')
// implementation var.SupportV7
// implementation var.SupportV4
// implementation var.SupportRecyclerviewV7
// implementation 'com.squareup.okhttp3:okhttp:3.9.1'
// testImplementation 'junit:junit:4.12'
//
// implementation (name: 'ucloudrtclib-2.1.4', ext: 'aar')
// implementation(name: 'libuvccamera-release', ext: 'aar')
// implementation(name: 'common-2.12.4', ext: 'aar')
// androidTestImplementation 'com.android.support.test🏃1.0.2'
// androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
// //bugly
// implementation 'com.tencent.bugly:crashreport:latest.release'
// implementation 'com.tencent.bugly:nativecrashreport:latest.release'
// implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
// implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
// implementation 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'

implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')

// implementation 'com.android.support:support-v4:28.0.0'
// implementation 'com.android.support:appcompat-v7:28.0.0'
// implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation var.SupportV7
implementation var.SupportV4
implementation var.SupportRecyclerviewV7
implementation 'com.facebook.fresco:fresco:1.13.0'
implementation 'com.facebook.fresco:animated-gif:1.13.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.alibaba:fastjson:1.1.46.android'

implementation project(path: ':uniplugin_urtc')

}

2、创建主入口程序,继承 DCloudApplication

3、uni-app打包本地app资源,将代码放到app>src>main>assets>apps下,然后配置dcloud_uniplugins.json 这个下面的

四、测试运行app 可调试

五、打包aar

以上记录只是成功后的总结记录,中间由于很多版本引用等问题非常痛苦,几经周折终于搞定,特此记录

posted @ 2022-06-02 15:37  星巴克先生  阅读(1299)  评论(1编辑  收藏  举报