You need to enable JavaScript to run this app.
文档中心
智能视频创作SDK

智能视频创作SDK

复制全文
下载 pdf
高级功能
SDK功能详解
复制全文
下载 pdf
SDK功能详解

EffectOne Android 功能详解

EffectOneSDK初始化

EffectOne初始化包含以下过程

绑定application

AppSingleton.bindInstance(this)

配置SDK默认值

配置模型路径、相册最大数、SDK图片加载、Log等的默认实现、相册默认值、图片编辑模式等,支持用户在宿主App中自定义。
把SampleCode中DefaultImageLoader.kt 文件直接复制到自己的工程当中使用即可。

// SampleCode中提供,可以直接复制过来。默认实现需要新增glide依赖
//implementation("com.github.bumptech.glide:glide:4.13.2")
EffectOneSdk.imageLoader = DefaultImageLoader() //图片加载实现

EffectOneSdk.logger = DebugLogger() //Log实现

EffectOneSdk.modelPath = EOResourceManager.getModelRootPath() //模型路径

EffectOneSdk.photoEditingMode = PhotoEditingMode.MODE_PICTURE  //图片编辑模式

鉴权配置(内置)

离线鉴权

  • 将离线鉴权文件放置到宿主工程/app/src/main/assets/License/目录下
    alt

  • 拷贝离线鉴权文件到App私有目录下

// 根据文件名,拷贝离线鉴权文件到App私有目录下
val licenseFileName = "com.volcengine.effectone.licbag"
val licenseFile = File(EOUtils.pathUtil.internalLicense(), licenseFileName)
if (!licenseFile.exists()) {
    EOUtils.fileUtil.copyAssetFile("license/${licenseFileName}", licenseFile.absolutePath)
}
  • 确认包名与鉴权文件一致,内测使用包名:"com.volcengine.effectone"
defaultConfig {
        ...
    applicationId = "com.volcengine.effectone"
    ...
}
  • 在 prepareAndInit() 中调用 auth() 进行鉴权处理
override fun prepareAndInit(callback: (Boolean, String) -> Unit) {
    coroutineScope.launch(Dispatchers.Main) {
        initConfigs()
        initResourceData()
        val authResult = withContext(Dispatchers.IO) {
            auth()
        }
        if (authResult.resCode != EOAuthErrCode.EO_SUCCESS) {
            EOToaster.show(AppSingleton.instance, authResult.resMsg)
            callback(false, "auth failed:${authResult.resMsg}")
        } else {
            callback(true, "auth success")
        }
    }
}
  • 获取鉴权结果,并可以根据结果进行后续处理
EOQuickInitHelper.prepareAndInit{  isSuccess, msg ->
    authResult = isSuccess
}

素材分发管理-EOResourceManager

EffectOneSdk需要使用素材来完成贴纸、特效、滤镜等效果,为了方便使用提供了素材管理SDK-EOResourceManager,方便接入方管理和配置素材。对于绝大部分场景,接入方直接使用EOResourceManager来管理素材即可。

  • 使用前,需要接入方对EOResourceManager进行初始化:语言、素材保存路径、域名(在线素材)等。
// 指定素材文件保存目录、素材使用语言
val config = EOResourceConfig.Builder()
    .setResourceSavePath(EOUtils.pathUtil.internalResource())
    .setDomainConfig(domainConfig)  //在线素材需要,离线素材不需要
    .setSysLanguage(Locale.getDefault().language)
    .build()
// 素材sdk初始化
EOResourceManager.init(config)

导入素材(内置)

  • 将Android下的资源交付物EffectResource文件下的内容,放置到EffectOne-Android/business/src/main/assets/EffectResource/里,目录结构如下:
    alt

  • 将Android下的资源交付物EffectResource/Resource_icons文件下的内容,放置到EffectOne-Android/business/src/main/res/drawable-xxhdpi/里
    alt

  • 加载面板配置文件内容

// 需要在EOQuickInitHelper initConfigs()里添加读取面板配置文件的实现,参考如下:
DefaultLocalResourceLoader.instance.localConfigsLoader = object : LocalConfigsLoader {
    private val configsPathMap : Map<String, String> = mutableMapOf<EOResourcePanelKey, String>().apply  {
        put(EOResourcePanelKey.PREVIEW_EDITOR_EFFECT, "Panel_configs/preview_editor_effect.json")
        put(EOResourcePanelKey.PREVIEW_EDITOR_FILTER, "Panel_configs/preview_editor_filter.json")
        put(EOResourcePanelKey.PREVIEW_EDITOR_FONT, "Panel_configs/preview_editor_font.json")
        put(EOResourcePanelKey.PREVIEW_EDITOR_INFO_STICKER, "Panel_configs/preview_editor_info_sticker.json")
        put(EOResourcePanelKey.PREVIEW_EDITOR_MUSIC, "Panel_configs/eo_music.json")
        put(EOResourcePanelKey.PREVIEW_EDITOR_STICKER, "Panel_configs/preview_editor_sticker.json")
        put(EOResourcePanelKey.PREVIEW_EDITOR_VOICE, "Panel_configs/preview_editor_tone.json")
        put(EOResourcePanelKey.RECORDER_BEAUTY, "Panel_configs/recorder_beauty.json")
        put(EOResourcePanelKey.RECORDER_FILTER, "Panel_configs/recorder_filter.json")
        put(EOResourcePanelKey.RECORDER_MUSIC, "Panel_configs/eo_music.json")
        put(EOResourcePanelKey.RECORDER_STICKER, "Panel_configs/recorder_sticker.json")
        put(EOResourcePanelKey.TRACK_EDITOR_MUSIC, "Panel_configs/eo_music.json")
        put(EOResourcePanelKey.TRACK_EDITOR_SOUND, "Panel_configs/track_editor_sound.json")
        put(EOResourcePanelKey.TRACK_EDITOR_TRANSITION, "Panel_configs/track_editor_transition.json")
    }.map  {
                it.key.value to  it.value
    }.toMap()
    override fun loadConfigs(panelKey: String, type: String): String? {
        val value = configsPathMap.getValue(panelKey) ?: return null
       // 从assets读取面板配置文件内容
        return EOUtils.fileUtil.readJsonFromAssets(AppSingleton.instance, "${EOUtils.pathUtil.assetsResourcePath}/${value}")
    }
}

图片编辑模式

  • 通过配置 EffectOneSdk 中 photoEditingMode 的值,可以对 EffectOne 编辑图片文件的方式进行配置

  • 默认会设置为图片编辑模式(MODE_PICTURE)

参数名含义类型

photoEditingMode

图片编辑的模式

enum class PhotoEditingMode {
    MODE_NON_PICTURE, //非图片编辑,会将图片文件按照3s视频进行编辑处理
    MODE_PICTURE      //图片编辑,会在预览编辑页面中对视频编辑相关的功能进行隐藏
}
  • 当设置为图片编辑模式之后,拍摄或导入的照片文件将会当作图片文件进行编辑和导出,具体导出图片的流程可参考图片导出详解

EffectOneActivity管理

可以通过EffectOneSdk.activityManager来管理EffectOneSdk中的Activity,包含以下能力:

  • 可以通过类名获取到对应的Activity实例

  • 关闭EffectOne的指定Activity,并设置activity result。启动对应Activity的页面可以在onActivityResult中获取到对应的回调

interface IActivityManager {

    fun finishActivities(filter: ((activity: AppCompatActivity)-> Boolean)? = null, resultCode: Int? = null, result: Intent? = null)

    fun <T: AppCompatActivity> getActivity(clazz: Class<T>): AppCompatActivity?
}
拍摄页配置详解

拍摄模块初始化

拍摄页初始化Sample
拍摄部分初始化,包含拍摄页整体初始化、通用面板配置以及美颜面板配置,可以参考以下Sample进行初始化

//Do record init in your activity before launch record
class HostActivity: AppCompatActivity {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        //拍摄模块整体配置
        EffectOneConfigList.configure(RecorderInitConfig()> {
            it.finishAction = { activity, list, musicItem, ext ->
                       EditorMainActivity.startEditorActivityFromRecord(activity, list.map  { resourceItem ->
                    com.volcengine.easyeditor.api.MediaItem(
                        path = resourceItem.path,
                        type = if (resourceItem.type == RecordMediaType.VIDEO) MediaType.VIDEO  else MediaType.IMAGE,
                        duration = resourceItem.duration,
                        speed = resourceItem.speed
                    )
                } as ArrayList<com.volcengine.easyeditor.api.MediaItem>, null, musicItem, ext)
            }
            it.albumConfig = AlbumConfig(
                allEnable = true,
                imageEnable = true,
                videoEnable = true,
                maxSelectCount = EffectOneSdk.albumMaxSelectedCount,
                maxDuration = 60 * 60 * 1000L,   // maxDuration Unit:ms
                finishClazz = StartEditorFinishImpl::class.java
            )
        }
        EffectOneConfigList.configure(BeautyUIConfig()) {
            it.resourceLoader = DefaultLocalResourceLoader.instance
            it.defaultBeautyAction = {
        EOResourceManager.syncLoadConfigByPanelKey(EOResourcePanelKey.RECORDER_BEAUTY.value, true).tabs
            }
        }
       
        //编辑和拍摄通用面板配置
        //滤镜面板
        EffectOneConfigList.configure(FilterUIConfig()) {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        //人脸特效面板
        EffectOneConfigList.configure(EOBaseStickerUIConfig()) {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        //音乐面板
        EffectOneConfigList.configure(EOBaseMusicUIConfig()) {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        //美颜面板
        EffectOneConfigList.configure(BeautyUIConfig()) {
            it.resourceLoader = DefaultLocalResourceLoader.instance
            it.defaultBeautyAction = {
        EOResourceManager.syncLoadConfigByPanelKey(EOResourcePanelKey.RECORDER_BEAUTY.value, true).tabs
            }
        }
        ...
        //启动拍摄页
        startRecordBtn.setOnClickListener {
        val recordPermissions = mutableListOf<String>().apply  {
            add(Manifest.permission.CAMERA)
                add(Manifest.permission.RECORD_AUDIO)
            }
            EOUtils.permission.checkPermissions(activity, recordPermissions, {
            EORecordActivity.startRecord(activity)
            }, {
            RecordUtils.showRecordPermissionTips(activity, it)
            })
        } 
    }
    ...

}

    
class StartEditorFinishImpl : IAlbumFinish {
    override suspend fun finishAction(activity: Activity, mediaList: List<IMaterialItem>, albumConfig: AlbumConfig) {
        EditorMainActivity.startEditorActivityFromAlbum(activity, mediaList.map  {
            com.volcengine.easyeditor.api.MediaItem(
                path = it.path,
                type = if (it.isVideo()) MediaType.VIDEO  else MediaType.IMAGE,
                duration = if (it.isVideo()) it.duration else 3000
            )
        }  as ArrayList<com.volcengine.easyeditor.api.MediaItem>)
    }
}

RecorderInitConfig:拍摄初始化参数配置

参数名含义类型接入方实现默认值

albumConfig

相册页面的配置

AlbumConfig

data class AlbumConfig(
    val  hintText: String =  "",
    val  singleSelect:  Boolean  =  false,
    val  confirmDirectly:  Boolean  =  false,
    val  canRepeat:  Boolean  =  true,
    val  showGif:  Boolean  =  true,
    val  allEnable:  Boolean  =  false,
    val  imageEnable:  Boolean  =  true,
    val  videoEnable:  Boolean  =  true,
    val  maxSelectCount:  Int  =  35,  // sdk内部会限制最大值不能超过35
    val  minSelectCount:  Int  =  1,
    val  minDuration:  Long  =  0L,
    val  maxDuration:  Long  =  Long.MAX_VALUE,
    val  enableDocker:  Boolean  =  true,
    var  confirmTextResId:  Int  =  0,
    val  finishClazz: Class<out  IAlbumFinish> = DefaultFinishImpl::class.java  //相册选择完成后的跳转页面
) : Parcelable
AlbumConfig(
        allEnable =  true,
        imageEnable =  true,
        videoEnable =  true,
        maxSelectCount = EffectOneSdk.albumMaxSelectedCount,
    //maxDuration Unit:ms
        maxDuration =  60  *  60  *  1000L,
        finishClazz = StartEditorFinishImpl::class.java

)

finishAction

拍摄完成后回调操作

((Activity, List<RecordMediaItem>, EOBaseMusicItem?, Bundle?) -> Unit)

RecordMediaItem:拍摄视频/相册内容
EOBaseMusicItem:音乐选择信息

{  activity, list, musicItem ->
    val options = ActivityOptionsCompat.makeCustomAnimation(activity, 0, 0)
    EditorMainActivity.startEditorActivityFromRecord(activity, list.map  {  resourceItem ->
        com.volcengine.easyeditor.api.MediaItem(
            path = resourceItem.path,
            type = if (resourceItem.type == RecordMediaType.VIDEO) MediaType.VIDEO  else MediaType.IMAGE,
            duration = resourceItem.duration,
            speed = resourceItem.speed
        )
    }  as ArrayList<com.volcengine.easyeditor.api.MediaItem>, options.toBundle(), musicItem)
}

defaultCameraDirection

默认摄像头方向

CameraFacingId

  • FACING_FRONT

  • FACING_BACK

选择默认摄像头方向

FACING_FRONT

defaultResolution

默认拍摄分辨率

ResolutionId

  • RESOLUTION_540 //540p

  • RESOLUTION_720 //720p

  • RESOLUTION_1080 //1080p

  • RESOLUTION_4K //4K

选择默认分辨率

RESOLUTION_1080

enableEffectStickerBtn

是否显示人脸贴纸按钮

Boolean
默认:true

enableAlbumBtn

是否显示相册按钮

Boolean
默认:true

selectModelFactory

拍摄页底部拍摄模式选择工厂类

默认实现

open class DefaultEORecordSelectModelFactory: IEORecordSelectModelFactory {
    override fun getDefaultSelectIndex(): Int {
        return 2
    }

    override fun getSupportModelList(): List<IEOModelItem> {
        return  listOf(
            Record2MINModel(), Record30SModel(), Record15SModel(), RecordPhotoModel()
        )
    }
}

可根据需求自定义所需的拍摄时长

启动拍摄页

val recordPermissions = mutableListOf<String>().apply  {
    add(Manifest.permission.CAMERA)
    add(Manifest.permission.RECORD_AUDIO)
}
EOUtils.permission.checkPermissions(activity, recordPermissions) {
    EORecordActivity.startRecord(activity)
}

启动拍摄页需要申请CAMERA和RECORD_AUDIO权限,如果宿主Activity继承自FragmentActivity,可以直接使用*EOUtils.permission.checkPermissions(activity, recordPermissions)*方法完成鉴权操作,如果不是,则需要接入方自己开发鉴权相关,请参考运行时权限申请相关文档。并在获得权限
后,调用 EORecordActivity.startRecord(activity) 启动拍摄页
https://developer.android.com/training/permissions/requesting?hl=zh-cn

RecorderMenuUIConfig:拍摄页侧边栏配置(可选)

参数含义类型接入方实现默认值

menuList

侧边栏展示项

List
可选项:

  • RecorderItemType.ITEM_FLIP:镜头翻转

  • RecorderItemType.ITEM_FLASH:闪光灯

  • RecorderItemType.ITEM_COUNTDOWN:倒计时

  • ecorderItemType.ITEM_FILTER:滤镜

  • RecorderItemType.ITEM_BEAUTY:美颜

  • RecorderItemType.ITEM_SPEED:倍速

可调整侧边栏Item顺序、删减侧边栏项

listOf(
    RecorderItemType.ITEM_FLIP,
    RecorderItemType.ITEM_FLASH,
    RecorderItemType.ITEM_COUNTDOWN,
    RecorderItemType.ITEM_FILTER,
    RecorderItemType.ITEM_BEAUTY,
    RecorderItemType.ITEM_SPEED,
)

unfoldCount

不折叠的数量,超过的item会被折叠

Int

选择默认不折叠数

5

foldEnabled是否开启侧边栏可折叠功能Boolean控制是否可以开启侧边栏折叠功能true

通用面板配置

滤镜、人脸特效、音乐等面板,为拍摄和编辑共用。文档默认使用离线素材管理,如果需要使用其他的素材管理,可自行实现ResourceLoader。DefaultLocalResourceLoader的实现请参考Sample或者参考EffectOne Android 素材管理

//滤镜面板
EffectOneConfigList.configure(FilterUIConfig()> {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}
//人脸特效面板
EffectOneConfigList.configure(EOBaseStickerUIConfig()> {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}
//音乐面板
EffectOneConfigList.configure(EOBaseMusicUIConfig()> {
        it.resourceLoader = DefaultLocalResourceLoader.instance
    it.showInEditor = true // 在预览编辑中音乐UI的总开关
    it.showInRecorder = true // 在拍摄中音乐UI的总开关
}

美颜面板初始化

EffectOneConfigList.configure(BeautyUIConfig()> {
        it.resourceLoader = DefaultLocalResourceLoader.instance
    it.defaultBeautyAction = {
        //获取美颜配置中defaultOn = 1的item作为美颜默认项(sdk中会自动过滤,简单处理接入方直接传入整体美颜config即可)
        EOResourceManager.syncLoadConfigByPanelKey(EOResourcePanelKey.RECORDER_BEAUTY.value, true).tabs
    }
}

合拍功能配置(可选)

EO120 版本额外新增合拍功能,具体业务层的实现如下:

启动相册选图器 -> 选择一个被合拍的视频文件 -> 跳转至拍摄页面进行合拍拍摄

  • 合拍功能初始化的具体配置,请参考 business/EODuetInitHelper.kt

合拍面板初始化

EffectOneConfigList.configure((RecorderDuetUIConfig())) {
        it.resourceLoader = DefaultLocalResourceLoader.instance
    it.defaultDuetAction = {
        EOResourceManager.syncLoadConfigByPanelKey(EOResourcePanelKey.RECORDER_DUET.value, true).tabs
    }
}

合拍默认布局资源加载

  • 在初次进入合拍拍摄页之前,需要对默认的合拍布局资源进行拷贝,以保证正确的合拍拍摄页效果。
CoroutineScope(Dispatchers.IO).launch  {
    loadDefaultDuet()
}

/**
  * 使用EOResourceManager对默认合拍布局资源进行加载
  *  @return : 返回加载结果(true: 加载成功;false: 加载失败)
  */
private suspend fun loadDefaultDuet() : Boolean {
    DefaultLocalResourceLoader.instance.loadResourceList(EOResourcePanelKey.RECORDER_DUET.value, "")
    val duetItems = EOResourceManager.syncLoadConfigByPanelKey(
        EOResourcePanelKey.RECORDER_DUET.value,
        true
    ).tabs.firstOrNull()
    duetItems?.subItems?.let  {  subItems ->
        if (subItems.isNotEmpty()) {
            DefaultLocalResourceLoader.instance.loadResourceItem(subItems.first())
            return true
        }
    }
    return false
}

合拍启动选图器配置

  1. 配置合拍功能的 AlbumConfig
val duetAlbumConfig = AlbumConfig(
    allEnable = false,
    imageEnable = false,
    videoEnable = true,    // 只可选择视频类型的文件
    maxSelectCount = 1,    // 合拍中只能传入一个被合拍的视频文件
    finishClazz = StartRecordFinishImpl::class.java,    // 选图结束后将启动拍摄页
    hintText = "(示例)请选择一段用于合拍的视频文件"
)

// StartRecordFinishImpl 详情请参考[2.7.3合拍拍摄页面配置](https://bytedance.larkoffice.com/docx/Mfl3dOTcqoP4kAxf6BOcCjMLn5f#Qu2EdTnQDooGfUxaZJvclzton0b)
class StartRecordFinishImpl : IAlbumFinish {
    override suspend fun finishAction(activity: Activity, mediaList: List<IMaterialItem>, albumConfig: AlbumConfig) {
        val videoPath = ""
        val audioPath = ""

        val bundle = Bundle()
        bundle.putBoolean("isDuet", true)
        bundle.putString("duetVideoPath", videoPath)
        bundle.putString("duetAudioPath", audioPath)
        EOQuickInitHelper.startRecorder(activity as FragmentActivity, bundle)

        if (!activity.isFinishing) {
            activity.finish()
        }

    }
}
  1. 启动相册页
val albumPermissions = mutableListOf<String>().apply  {
    if (Build.VERSION.SDK_INT  >= Build.VERSION_CODES.TIRAMISU) {
        add(Manifest.permission.READ_MEDIA_IMAGES)
        add(Manifest.permission.READ_MEDIA_VIDEO)
        add(Manifest.permission.READ_MEDIA_AUDIO)
    } else {
        add(Manifest.permission.READ_EXTERNAL_STORAGE)
        add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    }
    // 相机权限和音频录制权限用于选图结束后启动拍摄页
    add(Manifest.permission.CAMERA)
    add(Manifest.permission.RECORD_AUDIO)
}
EOUtils.permission.checkPermissions(activity, albumPermissions, {
    AlbumEntrance.startChooseMedia(
        activity, 1001, duetAlbumConfig
    )
}, {
    AlbumEntrance.showAlbumPermissionTips(activity)
})

合拍拍摄页面配置

通过合拍功能进入拍摄模块时,需要传入额外的Bundle配置项,来启动拍摄页中合拍相关的功能

Bundle Key含义类型参考值
isDuet是否启用合拍模式Booleantrue

duetVideoPath

被合拍视频文件的绝对路径

String

使用相册页传出的选中视频文件的路径
(注意需要确保该路径为绝对路径,如需将uri路径转换为绝对路径,可参考EOUtils.pathUtil.getAbsolutePathFromUri())

duetAudioPath被合拍音频文件的绝对路径String如果选中视频文件中存在音轨,则可以同时传入选中视频文件的绝对路径
编辑页配置详解

编辑模块初始化

编辑部分初始化,主要包含预览编辑页面侧边栏、通用面板配置、编辑功能面板配置等
编辑页初始化Sample
从相册进入编辑页面与从拍摄进入编辑页面,流程上基本一致,只是参数不同。下面以从相册选择图片/视频之后进入编辑页面为例演示下启动编辑页面整体流程:

class HostActivity: AppCompatActivity {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        
        // 编辑和拍摄通用面板配置
        // 滤镜面板
        EffectOneConfigList.configure(FilterUIConfig()> {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        // 人脸特效面板
        EffectOneConfigList.configure(EOBaseStickerUIConfig()> {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        // 音乐/音效面板
        EffectOneConfigList.configure(EOBaseMusicUIConfig()> {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        
        // 编辑功能面板配置
        // 信息贴纸面板
        EffectOneConfigList.configure(InfoStickerUIConfig()> {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        // 文本面板
        EffectOneConfigList.configure(TextStickerUIConfig()> {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        // 动画特效面板
        EffectOneConfigList.configure(EffectPanelUIConfig()> {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        // 录音-音色面板
        EffectOneConfigList.configure(AudioFilterUIConfig()> {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        // 转场面板
        EffectOneConfigList.configure(TransitionUIConfig()> {
            it.resourceLoader = DefaultLocalResourceLoader.instance
        }
        ...
        // 启动编辑页面
        startEditorBtn.setOnClickListener {
            EditorMainActivity.startEditorActivityFromAlbum(activity = activity, 
                list = arrayListOf<MediaItem>().apply  {
            add(
                        MediaItem(
                            path = 媒体文件本地路径,
                            type = 媒体文件类型(视频 / 图片),
                            duration = 媒体文件时长
                        )
                    )
                    add(
                        MediaItem(
                            path = 媒体文件本地路径,
                            type = 媒体文件类型(视频 / 图片),
                            duration = 媒体文件时长
                        )
                    )
                }
            )
        }
    }
    ...
}

EditorMenuUIConfig:预览编辑页面侧边栏配置(可选)

参数含义类型接入方实现默认值

menuList

侧边栏展示项

List
可选项:

  • EditorItemType.ITEM_PRO:剪辑

  • EditorItemType.ITEM_TEXT_STICKER:文本

  • EditorItemType.ITEM_INFO_STICKER:信息贴纸

  • EditorItemType.ITEM_FILTER:滤镜

  • EditorItemType.ITEM_EFFECT:动画特效

  • EditorItemType.ITEM_AUDIO_FILTER:录音

  • EditorItemType.ITEM_FACE_EFFECT:人脸特效

可调整侧边栏Item顺序、删减侧边栏项

listOf(
        EditorItemType.ITEM_PRO,
        EditorItemType.ITEM_TEXT_STICKER,
        EditorItemType.ITEM_INFO_STICKER,
        EditorItemType.ITEM_FILTER,
        EditorItemType.ITEM_EFFECT,
    EditorItemType.ITEM_FACE_EFFECT,
        EditorItemType.ITEM_AUDIO_FILTER,

)

unfoldCount

不折叠的数量,超过的item会被折叠

Int

选择默认不折叠数

5

foldEnabled是否开启侧边栏可折叠功能Boolean控制是否可以开启侧边栏折叠功能true

通用面板配置

滤镜、人脸特效、音乐等面板,为拍摄和编辑共用。文档默认使用离线素材管理,如果需要使用其他的素材管理,可自行实现ResourceLoader。DefaultLocalResourceLoader的实现请参考Sample或者参考EffectOne Android 素材管理

// 滤镜面板
EffectOneConfigList.configure(FilterUIConfig()> {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}
// 人脸特效面板
EffectOneConfigList.configure(EOBaseStickerUIConfig()> {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}
// 音乐/音效面板
EffectOneConfigList.configure(EOBaseMusicUIConfig()> {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}

编辑功能面板配置

在编辑中,文档默认使用离线素材管理,如果需要使用其他的素材管理,可自行实现ResourceLoader。DefaultLocalResourceLoader的实现请参考Sample或者参考EffectOne Android 素材管理

// 信息贴纸面板
EffectOneConfigList.configure(InfoStickerUIConfig()) {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}
// 文本面板
EffectOneConfigList.configure(TextStickerUIConfig()) {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}
// 动画特效面板
EffectOneConfigList.configure(EffectPanelUIConfig()) {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}
// 录音-音色面板
EffectOneConfigList.configure(AudioFilterUIConfig()) {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}
// 转场面板
EffectOneConfigList.configure(TransitionUIConfig()) {
        it.resourceLoader = DefaultLocalResourceLoader.instance
}

其他配置(可选)

配置素材最大个数

EO支持配置同一个编辑实例中,一些素材的最大个数,避免素材添加过多,引起性能问题。EO提供的默认值,适用于大部分中端机型。接入方可以根据业务需求,为低端设备配置更低的素材数

素材类型参数名默认值备注
图片/文字/信息化贴纸EditorResourceCountConfig.maxStickerCount30最大的贴纸数(文字+图片+信息化贴纸)
音效EditorResourceCountConfig.maxSoundEffectCount30轨道编辑面板最多可以添加的音效数目
EffectOneConfigList.configure(EditorResourceCountConfig()) {
        it.maxStickerCount = 30
    it.maxSoundEffectCount = 30
}

配置导入初始画布比例

EO在导入素材时支持配置默认画布比例,并支持在比例面板进行画布比例的切换。初始化配置为RatioConfig,支持以下6种比例设置,暂不支持拓展

比例值介绍
CanvasAspectRatio.RATIO_ORIGINAL设置画布的比例为第一段素材的比例
CanvasAspectRatio.RATIO_9_16设置画布比例 width:height 为 9:16
CanvasAspectRatio.RATIO_3_4设置画布比例 width:height 为 3:4
CanvasAspectRatio.RATIO_1_1设置画布比例 width:height 为 1:1
CanvasAspectRatio.RATIO_4_3设置画布比例 width:height 为 4:3
CanvasAspectRatio.RATIO_16_9设置画布比例 width:height 为 16:9

「高级剪辑」-> 「比例」面板中提供上述6个画幅比例的切换能力

//面板功能配置
EffectOneConfigList.configure(RatioConfig()) {
        it.defaultRatio = CanvasAspectRatio.RATIO_ORIGINAL
}

启动编辑页面

进入相册

启动相册也需要以下权限,如果宿主是FragmentActivity,可以用EffectOne封装好的权限工具直接申请

val albumPermissions = mutableListOf<String>().apply  {
    if (Build.VERSION.SDK_INT  >= Build.VERSION_CODES.TIRAMISU) {
        add(Manifest.permission.READ_MEDIA_IMAGES)
        add(Manifest.permission.READ_MEDIA_VIDEO)
        add(Manifest.permission.READ_MEDIA_AUDIO)
    } else {
        add(Manifest.permission.READ_EXTERNAL_STORAGE)
        add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
    }
}
EOUtils.permission.checkPermissions(activity, albumPermissions) {
    //call back after permission all granted
}

如果不是FragmentActivity,则需要接入方自己开发鉴权相关,请参考运行时权限申请相关文档。并在获得权限后,启动相册
https://developer.android.com/training/permissions/requesting?hl=zh-cn

从相册页面选择素材之后,跳转到编辑页面

/**
  * 从相册页面选择素材之后,跳转到编辑页面
  *  @param activity 当前页面
  *  @param list [MediaItem] 类型的素材列表
  *  @param options 自定义的附加参数,方便添加转场或者共享元素动画
  */
EditorMainActivity.startEditorActivityFromAlbum(
    activity: Activity,
    list: ArrayList<MediaItem>,
    options: Bundle? = null,
)

从拍摄模块拍摄照片或视频之后,跳转到编辑页面

/**
  * 从拍摄模块拍摄照片或视频之后,跳转到编辑页面
  *  @param activity 当前页面
  *  @param list [MediaItem] 类型的素材列表
  *  @param options 自定义的附加参数,方便添加转场或者共享元素动画
 * @param musicItem [EOBaseMusicItem] 类型,拍摄时添加的背景音乐信息
  */
EditorMainActivity.startEditorActivityFromRecord(
    activity: Activity,
    list: ArrayList<MediaItem>,
    options: Bundle? = null,
    musicItem: EOBaseMusicItem? = null,
)
草稿

EffectOne支持将编辑中的视频保存成草稿,可以通过下方接口跳转草稿页预览草稿或者从草稿恢复视频编辑态

// 如何启动草稿页
EditorDraftActivity.startDraftActivity(activity)
UI定制

Android UI 定制原理:Android利用apk打包中,同名资源冲突覆盖,支持客户在宿主中通过替换同名的drawable文件以及string、color对应的value,来进行UI定制化。EffectOneSDK中所有支持替换的资源,都会放在Sample中的default_res_files对应模块的目录下。根据EffectOneSDK的UI场景,目前的模块分为相册(album)、拍摄(camera)、编辑-预览编辑(previeweditor)、编辑-轨道编辑-(trackeditor)、基础组件(base)。
alt
注:主页、导出页仅仅提供相关接口的SampleCode,用户需要自己参考实现,不在换皮的范围内

  1. 主题色:色卡

色卡颜色表格:

Effect one色卡
EffectOne SDK中所有可替换的颜色都可以在色卡中找到对应的key和色值。对应的资源文件,请参考Sample中的default_res_files/v_x_x/res/color/eo_color_card.xml

如何自定义主题色

如果需要在宿主App中,替换不同的主题色,可以在宿主的res/values/目录下colors.xml中,将需要修改的色卡对应的Color Resource Item () copy到color.xml下,并根据需要直接修改对应色卡的色值(RGBA)。EffectOneSDK中对应的颜色将会被替换成新的颜色

如何查找UI中对应控件的色卡key-value

参考各模块UI标注

文案

EffectOne中英文对照表

EffectOne SDK中除素材的文案外,所有可替换的文案都定义在对应模块的string.xml中,可以在Sample中找到,string.xml会根据模块放在对应的目录下。

如何自定义文案

如果需要在宿主App中,替换不同的文案(中英文),可以在宿主的res/values/和res/values-zh-rCn/目录下的strings.xml中,将需要修改的String Resource Item(),从default_res_files中对应模块下的strings.xml内copy过来,并修改对应的中英文

如何查找UI中对应文字的key-value

参考各模块UI标注

图标

EffectOne图标对照表

EffectOne SDK中除素材外,所有可替换的图标对应的默认drawable文件,可以在Sample中找到,drawable会根据模块放在对应的目录下。为了缩减包大小,EffectOneSDK中绝大部分的默认图标,格式为svg。我们支持也支持用户使用PNG、JPG、WEBP等常见图片格式进行替换

如何替换图标

如果需要在宿主App中,替换不同的图标,可以在宿主的drwable目录下(如果是3x的png,需要在drawable-xxhdpi目录下),创建同名的图片文件(文件名相同即可,后缀可以不同,默认为svg导入的.xml)。如何导入svg图片,请参考https://developer.android.com/studio/write/vector-asset-studio。原始图片文件,会存放在default_res_files中对应模块下的drawable文件夹下。

如何查找UI中对应图标的key和样式

参考各模块UI标注
注意:标注文档中给出的图标建议尺寸单位是3x的图片像素,需要在使用png/jpg/webp等格式图片进行同名替换,并存放在drawable-xxhdpi目录下。如果使用svg进行替换,需要换算为dp。具体dp值可以使用3x像素值除以3或者参考对应资源文件中的svg。svg的xml文件需要放在宿主的drawable目录下

各模块UI标注

基础组件

基础组件客户可更换UI范围

拍摄

拍摄部分客户可更换UI范围

预览编辑

预览编辑客户可更换UI范围

轨道编辑

轨道编辑客户可更换UI范围

草稿

草稿箱客户可更换UI范围

音乐

音乐&音效&音乐音量面板客户可更换UI范围

相册

相册部分客户可更换UI范围

其他接入方式

依赖和接入流程,请参考Effectone接入文档-Android。快速接入使用.gradle配置工程,kottlin+Android原生FragmentActivity方式接入。其他语言和框架的接入,可以参考下文,替换快速接入中对应的模块

非FragmentActivity

如果接入方的宿主不是FragmentActivity而是ComponentActivity,EOQuickInitHelper中提供的Android运行时权限相关接口,无法使用,接入方可以参考EOQuickInitHelper.kt的源码,自行实现相关能力。https://developer.android.com/training/permissions/requesting?hl=zh-cn

Java语言接入

Application

public class SampleApplication extends Application {
    @Override
    public  void  onCreate() {
        super.onCreate();
        ...
        EOQuickInitHelper.INSTANCE.setLicenseFileName("20231023_20241023_com.volcengine.effectone_union.licbag");
        EOQuickInitHelper.INSTANCE.initApplication(this);
    }
}

启动页

public class JavaActivity extends FragmentActivity {
    private View startRecordBtn;
    @Override
    protected  void  onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        startRecordBtn = findViewById(R.id.sample_start_recorder);
        startRecordBtn.setOnClickListener(new  View.OnClickListener() {
            @Override
            public  void  onClick(View v) {
                EOQuickInitHelper.INSTANCE.prepareAndInit(JavaActivity.this, new  Function1<Boolean, Unit>() {
                    @Override
                    public Unit invoke(Boolean it) {
                        if (it) {
                            EOQuickInitHelper.INSTANCE.startRecorder(JavaActivity.this);
                        } else {
                            EOToaster.INSTANCE.show(JavaActivity.this, "Auth Fail", Toast.LENGTH_SHORT);
                        }
                        return null;
                    }
                });
            }
        });
    }
}

导出页

无Java版本的导出页源码,接入方可以参考SampleCode中kottlin版本的导出页源码以及导出接口文档,自行实现
EffectOne-Android 视频导出接口介绍

使用gradle.kts格式替代.gradle接入

.gradle.kts和.gradle对应关系,参考官方文档Example 30:https://docs.gradle.org/8.4/userguide/declaring_repositories.html

setting.gradle.kts

//如果使用的是.kts文件进行如下配置
dependencyResolutionManagement {
        ...
    repositories {
                ...
        maven("https://artifact.bytedance.com/repository/thrall_ck/") {
            credentials {
                username  = MAVEN_USER_NAME
                password  = MAVEN_PASS_WORD
            }
            authentication {
                create<BasicAuthentication>("basic")
            }
                }
        maven("https://artifact.bytedance.com/repository/thrall_cv/") {
            credentials {
                username  = MAVEN_USER_NAME
                password  = MAVEN_PASS_WORD
            }
            authentication {
                create<BasicAuthentication>("basic")
            }
                }
        }
}

app/build.gradle.kts

...
val effectOneVersion="1.0.0"//对应的effectOneSdk版本号
dependencies  {
    api("com.volcengine.effectone:editor-ui:${effectOneVersion}")
    api("com.volcengine.effectone:recorder-ui:${effectOneVersion}")
    //素材加载SDK
        api("com.volcengine.effectone:base-resource:${effectOneVersion}")
    //上述三个SDK公用同一个版本号
        implementation("com.github.bumptech.glide:glide:4.13.2")// 默认图片库依赖(DefaultImageLoader),可选
        implementation("androidx.appcompat:appcompat:1.3.0") //根据宿主环境自行选择版本,推荐1.3.0
}

android {
    ...
    defaultConfig {
        ...
        vectorDrawables.useSupportLibrary = true //支持vetorDrawable,当你需要替换EffectOne中的svg图片时使用
        applicationId = "com.volcengine.effectone" //确保包名和授权的包名一致,内测鉴权文件使用此包名
    }
    packaging {
        ...
    jniLibs {
    useLegacyPackaging = true
    }
    jniLibs.pickFirsts.add("lib/arm64-v8a/libc++_shared.so")
        jniLibs.pickFirsts.add("lib/armeabi-v7a/libc++_shared.so")
    }

}

gradle.properties

android.useAndroidX=true
android.enableJetifier=true

Jetpack Compose快速接入

EffectOneSDK的拍摄和剪辑页面,采用内置UI的方式,因此对于Compose接入几乎没有区别。如果接入方宿主不是FragmentActivity,需要自行实现Android运行时权限申请。导出页的高级功能和UI,需要接入方自己开发。下边提供下JectPack Compose接入相关SampleCode

初始化&Application

Componet的gradle配置以及Application初始化和普通UI接入无区别

启动页

class HostActivity  :  FragmentActivity() {

    override fun onCreate(savedInstanceState:  Bundle?)  {
        super.onCreate(savedInstanceState)
                setContent  {
            SampleEffectStudioRecommendTheme  {
                // A surface container using the 'background' color from the theme
                                Surface(
                                        modifier = Modifier.fillMaxSize(),
                                        color = MaterialTheme.colorScheme.background
                                )  {
                    Main("Android")
                }
                        }
                }
    }

}

@Composable
fun Main(name:  String, modifier:  Modifier  = Modifier)  {
        Box(
                modifier = Modifier.fillMaxSize(),
                )  {
        val  activity = LocalContext.current  as  FragmentActivity
                Button(onClick =  {
            EOQuickInitHelper.prepareAndInit(activity)  {
                EOQuickInitHelper.startRecorder(activity)
            }
                }, modifier = Modifier.align(Alignment.Center))  {
            Text(
                                text =  "Start Recorder",
                                modifier = modifier
                        )
        }
        }
}

导出页

同Android原生View接入

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