You need to enable JavaScript to run this app.
智能美化特效

智能美化特效

复制全文
V4.8.0
AI特效平台(Ebox)素材 SDK Android 接入指南
复制全文
AI特效平台(Ebox)素材 SDK Android 接入指南
简介

AI 特效平台(下文简称 Ebox)是一站式 AI 特效应用开发与素材管理平台,专注于为企业及开发者提供从应用创建、页面配置、素材管理下发到授权交付的全链路解决方案, 详请见:AI特效平台(Ebox)使用手册
Ebox Android SDK 封装了 EBox 平台 API ,方便 Android App 快速接入 Ebox 平台,获取素材并使用。

快速接入

集成本地SDK到项目中

  • 在对应版本Sample中的ebox-module模块中获取到ebox sdk的aar文件集成到项目中.

  • 在AndroidManifest中添加网络权限

    <uses-permission android:name="android.permission.INTERNET" />
    

接口说明

EBox Android SDK 接口定义在 EBoxSDKManager 中,下面详细介绍常用接口

初始化

接口名称

EBoxSDKManager.init(eboxResourceConfig, context)

使用场景

某些自定义场景,单独创建实例

参数说明

参数类型说明
resourceConfigEBoxResourceConfigEBoxSDK进行初始化时需要进行的各项配置
contextContext上下文

示例代码

//绑定ApplicationContext
AppSingleton.instance = this.application

val levelConfig = LevelConfig(
    "null", Build.MANUFACTURER,
    Locale.getDefault().language, Locale.getDefault().country, ""
)

//初始化EBoxConfig
val eboxConfig = EBoxConfig(
    appId = "",
    appSecret = "",
    appVersion = "",
    levelConfig = levelConfig
)

val eboxResourceConfig = EBoxResourceConfig.Builder()
    //设置Config相关信息
    .setAppConfig(eboxConfig)
    //配置是否读取在线资源
    .setEnableOnline(true)
    //配置网络代理,这里可以替换为自己的网络实现
    .setNetWorker(DefaultNetWorker())
    //设置素材存储根路径,不设可以用EO默认值
    .setResourceSavePath("your resource download dir")
    //设置模型存储的根路径,不设可以用EO默认值
    .setModelDir("your resource download dir")
    //设置具体请求的实现,直接使用EBoxRemoteRequestBuilder即可
    .setRequestBuilder(EBoxRemoteRequestBuilder(eboxConfig))
    .build()


//初始化
EBoxSDKManager.init(eboxResourceConfig, AppSingleton.instance)

获取页面配置

接口名称

//同步接口
fun getPageConfig(): String

//异步接口
fun getPageConfig(onSuccess: (String) -> Unit)

使用场景

获取页面配置

返回值说明

类型说明
String在EBox平台配置的自定义数据

获取业务列表

接口名称

fun getBusinessList(bizKeys: List<String>, schemeMap: Map<String, String>? = null): Map<String, List<BizConfigItem>>

使用场景

获取业务列表数据

参数说明

参数类型说明
bizKeysList业务列表标识

schemeMap

Map<String, String>

Key:bizKey
Value:

  • eboxlocal:读取本地的数据

  • https: 读取在线的数据

返回值说明

类型说明

Map<String, List>

key:key为请求时的每个key
value: 为每个key请求返回的结果 为List

示例代码

val bizKeys = listof("key1","key2","key3")

val schemeMap = mutableMapOf<String, String>()
schemeMap.put("key1", "https")
schemeMap.put("key2", "https")
schemeMap.put("key3", "eboxlocal")

//key1 key2 请求服务端
//key3 读取本地数据
val result = EBoxSDKManager.getBusinessList(bizKeys, schemeMap)

获取素材项

接口名称

fun getResourceItemInfo(resId: String): EBoxResItem?

使用场景

获取单个素材项数据

参数说明

参数类型说明
resIdString素材标识

返回值说明

类型说明
EBoxResItem素材项数据的描述信息

示例代码

val eBoxResItem = EBoxSDKManager.getResourceItemInfo(resId)

data class EBoxResItem(
    //资源ID
    val resId: String = "",
    //资源名称
    val name: String = "",
    //资源的md5
    val md5: String = "",
    //资源的下载链接,下载后会和下发的md5进行比对
    val url: String = "",
    //资源的封面链接
    val coverUrl: String = "",
    //资源类型
    val type: String = "",
    //资源依赖的模型
    val requirements: Requirements? = null
)

获取素材列表

接口名称

fun getResourceList(isOnline: Boolean): List<EBoxResItem>?

使用场景

获取素材列表数据

参数说明

参数类型说明

isOnline

Boolean

获取在线/离线素材列表
true 获取在线素材列表
false 获取离线素材列表

返回值说明

类型说明
List该应用下所有素材的信息

示例代码

val result = EBoxSDKManager.getResourceList(true)

加载素材

接口名称

fun getResourceItem(resId: String): EBoxResItem?

使用场景

加载资源,在线资源可能会下载,离线资源仅拷贝

参数说明

参数类型说明
resIdString素材标识

返回值说明

类型说明
EBoxResItem下载好的素材描述信息

示例代码

//耗时方法,需要执行在子线程
val eboxResItem = EBoxSDKManager.getResourceItem(resId)

加载模型

接口名称

//同步方法
fun loadModel(obfuscatedNames: List<String>, sdkVersion: String): Boolean

//异步方法
fun loadModel(obfuscatedNames: List<String>, sdkVersion: String, onSuccess: (Boolean) -> Unit)

使用场景

加载模型文件,在线模型可能会下载,离线模型仅拷贝

参数说明

参数类型说明
namesList模型名集合
sdkVersionString特效sdk版本号

返回值说明

类型说明
Boolean加载成功过返回true,加载失败返回false

示例代码

val success = EBoxSDKManager.loadModel(obfuscatedNames,sdkVersion)

检查素材

接口名称

fun checkResourceReady(resId: String): Boolean

使用场景

检查素材项是否准备好

参数说明

参数类型说明
resIdString素材标识

返回值说明

类型说明

Boolean

true:素材存在
false:素材不存在

示例代码

val res = EBoxSDKManager.checkResourceReady(resId)
错误码说明

EBoxErrCode

错误码定义说明
0EO_RESOURCE_SUCCESS获取素材成功
1001EO_ERR_RESPONSE网络请求错误
1002EO_ERR_PARSE数据解析错误
1003EO_ERR_VERIFY数据md5验证错误
1004EO_ERR_UNZIP文件解压错误
1005EO_ERR_MERGE本地、远端数据融合错误
1006EO_ERR_DOWNLOAD下载错误
1007EO_ERR_LOCAL_CONFIG_NOT_FOUND本地面板Json未发现
1008EO_ERR_LOCAL_CONFIG_PARSE本地面板Json解析失败
1009RESOURCE_ID_NOT_FORMAT素材ID不合法
1010RESOURCE_TOKEN_FETCH_FAIL获取token失败
1011RESOURCE_MD5_CHECK_FAIL素材md5校验失败
1012RESOURCE_DOWNLOAD_FAIL素材加载失败
1013RESOURCE_DOWNLOAD_MODEL_FAIL模型资源加载失败
1014RESOURCE_RES_ID_INVALID素材ID不存在
1015RESOURCE_ILLEGAL_URLURL不合法
1016RESOURCE_NOT_READY资源没有就绪
1017RESOURCE_ILLEGAL_FILE资源文件不合法
1201ILLEGAL_CONFIG配置错误
1999UNKNOWN未知错误
离线文件说明

离线文件目录结构

ebox
├── page.json // 应用的页面配置
├── material_list.json // 离线素材列表
├── business_list // 离线业务列表目录                  
│   ├── beauty.json      
│   ├── ...    
├── material // 离线素材,按类型分子目录存放                  
│   ├── native_effect // 贴纸素材包目录     
│   │   ├── 爱心飘落_xx.zip  
│   │   ├── ...
│   ├── ...     
├── model // 模型文件目录                   
│   ├── algo_ggl1pqh_v11.1.model      
│   ├── ...   
├── icon // 图标文件目录                  
│   ├── 爱心飘落_xx.png      
│   ├── ...

素材列表文件字段说明

{
    "item_list": [ // 素材项列表
        {
            "id": 1522471938, // 素材 ID
            "md5": "1ede5dd06c9d317fdccc0a280d01e098", // 素材包文件 md5
            "name": "reshape_v8_lite", // 素材包名
            "requirements": { // 依赖项
                "models": [ // 算法模型列表
                    {
                        "md5": "3ca5c7f74a8b9088762b718d5a1418c8", // 模型文件 md5
                        "name": "algo_ggl1pqh_v11.1.model", // 模型名
                        "url": "eboxlocal://EffectResource/ebox/model/algo_ggl1pqh_v11.1.model" // 模型地址,本地文件 url scheme 为 eboxlocal,path 为包含离线文件根目录 /ebox 内相的对路径
                    },
                    // ...
                ]
            },
            "type": "native_beauty", // 素材类型
            "url": "eboxlocal://EffectResource/ebox/material/native_beauty/reshape_v8_lite_1522471938.zip" // 素材地址,本地文件 url scheme 为 eboxlocal,path 为包含离线文件根目录 /ebox 内相的对路径
        },
        // ...
   ]
}

业务列表文件字段说明

{
    "item_list": [ // 业务项列表
        {
            "config": "", // 业务项扩展字段
            "cover": "eboxlocal://EffectResource/ebox/icon/%E7%88%B1%E5%BF%83%E9%A3%98%E8%90%BD_1522486530.png", // 业务项图标地址,本地文件 url scheme 为 eboxlocal,path 为包含离线文件根目录 /ebox 内相的对路径
            "extend_id": "", // 业务项扩展 ID
            "material_ref_ids": [ // 关联的素材 ID
                1522486530
            ],
            "name": "爱心飘落" // 业务项名字
        },
        // ...
    ]
}
FAQ

素材都支持哪些集成方式以及 SDK 如何设置

使用 AI 特效平台(Ebox)线上服务(海外暂不支持)托管素材

部分内置+部分在线

使用场景
  • 场景:部分素材内置,来加快素材加载速度;其余素材托管在 EBox 平台按需下载,减小包体

  • 优点:实现加载速度和包体之间的平衡;使用 EBox 平台管理素材,无需服务端开发

移动端配置
  • 从应用 sample code 中获取离线文件 ebox 目录,文件位置参考相关应用文档,例如 cv 应用查看移动端v4.8.0 AI特效平台(Ebox)Sample Code使用指南体验离线素材部分

  • 离线文件根目录 ebox 下保留 material_list.json 以及 material 目录中需要内置的素材包、model 目录中需要内置的模型文件,其它文件都删掉

  • material_list.json 文件中仅保留需要内置的项

  • 将ebox文件夹放到assets/EffectResource目录下,如图

  • 在使用之前,做好如下配置
val eboxResourceConfig = EBoxResourceConfig.Builder()
    // 在线功能开启
    .setEnableOnline(true)
    .setNetWorker(DefaultNetWorker())
    // 设置素材存储目录,不设置走默认
    .setResourceSavePath("your resource download dir")
    // 设置模型存储的根路径
    .setModelDir("your model download dir")
    .setRequestBuilder(EBoxRemoteRequestBuilder(eboxConfig))
    .build()
    
EBoxSDKManager.init(eboxResourceConfig, AppSingleton.instance)

部署在自己的文件服务器上,不使用 AI 特效平台(Ebox) 线上服务

如果需要把素材部署在自己的服务器上,不使用 AI 特效平台(Ebox)素材线上服务,考虑下面的接入方式

部分内置+部分在线

使用场景
  • 场景:部分资源内置,来加快素材加载速度;其余素材部署到线上

  • 优点:减小包体,按需加载

移动端配置
  • 从应用 sample code 中获取离线文件 ebox 目录,文件位置参考相关应用文档,例如 cv 应用查看 移动端v4.8.0 AI特效平台(Ebox)Sample Code使用指南 体验离线素材部分

  • 离线文件根目录 ebox 下保留 material_list.json 以及 material 目录中需要内置的素材包、model 目录中需要内置的模型文件,其它文件都删掉

  • material_list.json 文件中仅保留需要内置的项

  • 将ebox文件夹放到assets/EffectResource目录下

  • 在使用特效之前,做好如下配置

val eboxResourceConfig = EBoxResourceConfig.Builder()
    // 在线功能开启
    .setEnableOnline(true)
    // 配置网络代理,这里可以替换为自己的网络实现
    .setNetWorker(DefaultNetWorker())
    // 设置素材存储目录,不设置走默认
    .setResourceSavePath("your resource download dir")
    // 设置模型存储的根路径,不设置走默认
    .setModelDir("your model download dir")
    // 设置 MockRequestBuilder
    .setRequestBuilder(EboxMockRequestBuilder())
    .build()
    
EBoxSDKManager.init(eboxResourceConfig, AppSingleton.instance)
Mock 在线素材

为了方便理解,下方提供一个简单的 mock server 和 EboxMockRequestBuilder,用来演示如何部署在线素材(环境为mac系统,python3,保证测试手机和电脑在相同的wifi环境下)

  1. 在文件服务中创建 EffectResource 目录,把 sample code 中完整的 ebox 文件夹(不删减内容) 拷贝到 EffectResource下, 本地启动一个简易文件 server,以 python3 为例
# EffectResource 为 ebox 目录的父目录
cd ~/Downloads/EffectResource

# 在本机的 ip 上 8000 端口,启动 SimpleHttpServer
python3 -m http.server 8000
  1. 获取本机的ip地址
# 使用ifconfig 查看电脑的ip
ipconfig getifaddr en0
  1. 执行下面的 python 脚本,把 ebox 目录中素材 URL 替换为在 mock server 中的 URL
    replace_domain.py
    1.75KB

例如步骤2 中获取的 ip 地址是 192.168.50.52,服务端口是 8000,执行下面命令

# 把脚本拷贝到 EffectResource 目录
cp replace_domain.py ~/Downloads/EffectResource/

# 执行转换
# src:本地 domain
# tar:mock server domain
# dir:ebox 文件夹位置
python3 replace_domain.py --src eboxlocal://EffectResource --tar http://192.168.50.52:8000 --dir ./ebox
  1. 成功即可通过http请求,访问电脑上的交付产物文件夹,类似


到此,完成了 server 数据的 mock

  1. 在 sample code 中,修改AndroidManifest.xml,打开http访问权限(仅限于mock 接口测试,正式接入的代码中可以删掉)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" >
    <!-- 添加网络访问权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        android:usesCleartextTraffic="true"
        ...
  1. 在 sample code 中实现 EboxMockRequestBuilder
// ip:port,参考上文的 mock server
class EboxMockRequestBuilder(private val host: String = "http://192.168.50.52:8000/") : IRequestBuilder {

    companion object {
        const val TAG = "EBoxRemoteRequestBuilder"

        const val PATH_BIZ_CONFIG = "/ebox/business_list/"
        const val PATH_RESOURCE_MATERIAL_LIST = "/ebox/material_list.json"
        const val PATH_PAGE_CONFIG = "/ebox/page.json"
    }

    private fun getEBoxDomain(scheme: String?): String {
        return host
    }

    // 下载素材、模型、icon 等
    @SuppressLint("UseKtx")
    override fun <T> buildDownloadResourceRequest(sourceItem: FetchSource<T>): RequestInfo {
        val uri = Uri.parse(sourceItem.getUrl())
        return if (uri.scheme == EBOX_LOCAL) {
            RequestInfo(
                uri.scheme ?: "",
                "${uri.host}${uri.path}",
                RequestType.GET,
            )
        } else {
            RequestInfo(
                getEBoxDomain(""),
                uri.path!!,
                RequestType.GET,
            )
        }
    }

    // 获取素材列表
    override fun buildResMaterialListRequest(resScheme: String?, pageNumber: Int, pageSize: Int): RequestInfo {
        val scheme = if (EBoxSDKManager.resourceConfig.enableOnline) {
            resScheme
        } else {
            EBOX_LOCAL
        }
        val resHeaderMap = createCommonHeaderMap()

        val requestPath = if (scheme == EBOX_LOCAL) {
            "${EBoxSDKManager.resourceConfig.offlineRootPath}/material_list.json"
        } else {
            PATH_RESOURCE_MATERIAL_LIST
        }

        return RequestInfo(
            getEBoxDomain(scheme),
            requestPath,
            RequestType.GET,
            resHeaderMap
        )
    }

    // 获取单个素材,查缺补漏用,mock不必实现
    override fun buildResItemRequest(resId: String, resScheme: String?): RequestInfo {
        val resHeaderMap = createCommonHeaderMap()
        return RequestInfo(
            getEBoxDomain(""),
            "",
            RequestType.GET,
            resHeaderMap
        )
    }

    // 获取业务列表
    override fun buildBizConfigRequest(bizId: String, bizScheme: String?): RequestInfo {
        val scheme = if (EBoxSDKManager.resourceConfig.enableOnline) {
            bizScheme
        } else {
            EBOX_LOCAL
        }
        val bizHeaderMap = createCommonHeaderMap()
        val requestPath = if (scheme == EBOX_LOCAL) {
            "${EBoxSDKManager.resourceConfig.offlineRootPath}/business_list/${bizId}.json"
        } else {
            "${PATH_BIZ_CONFIG}${bizId}.json"
        }
        return RequestInfo(
            getEBoxDomain(scheme),
            requestPath,
            RequestType.GET,
            bizHeaderMap
        )
    }

    // 获取页面配置
    override fun buildPageConfigRequest(): RequestInfo {
        val scheme = if (EBoxSDKManager.resourceConfig.enableOnline) {
            EBOX_ONLINE
        } else {
            EBOX_LOCAL
        }
        val requestPath = if (scheme == EBOX_LOCAL) {
            "${EBoxSDKManager.resourceConfig.offlineRootPath}/page.json"
        } else {
            PATH_PAGE_CONFIG
        }
        val bizHeaderMap = createCommonHeaderMap()
        return RequestInfo(
            getEBoxDomain(scheme),
            requestPath,
            RequestType.GET,
            bizHeaderMap
        )
    }

    // 获取模型信息,查缺补漏用,mock不必实现
    override fun buildModelObfuscatedRequest(
        obfuscatedNames: List<String>,
        sdkVersion: String
    ): RequestInfo {

        val resHeaderMap = createCommonHeaderMap()
        return RequestInfo(
            getEBoxDomain(""),
            "",
            RequestType.GET,
            resHeaderMap
        )
    }

    private fun createCommonHeaderMap(): MutableMap<String, String> {
        val headerMap = mutableMapOf<String, String>()
        return headerMap
    }

}
  1. 构建运行 sample code

如果之前运行过,建议先删除 sample 应用,避免之前有离线加载的素材影响测试,然后重新编译运行 sample code。可以根据之前运行 python 服务器的 terminal 输出的日志,来判断是否访问了 mock server 上的资源。Server 端日志大概如下:


如果一个素材既内置在 App 中又在线上配置了,会使用哪个

素材包文件相同 (md5 已有)情况优先使用内置的,否则会下载远端的覆盖

在线素材可以预加载吗

想要在 UI 展示前提前加载的素材,可以提前通过素材 ID 调用素材加载接口提前加载,示例代码:

val resIds = arrayOf("123", "456", "789")

//耗时方法,需要执行在子线程
for (resId in resIds) {
    EBoxSDKManager.getResourceItem(resId)
}

缓存清理策略是怎样的

目前没有自动清理的策略,需要使用方按需手动清理。缓存路径为初始化接口传入的路径。
注意资源缓存有依赖关系(素材依赖算法模型),如需清理,建议在没有使用时整体全部清理,业务再按需加载

最近更新时间:2025.12.29 15:03:10
这个页面对您有帮助吗?
有用
有用
无用
无用