- 인쇄
Editor 연동
- 인쇄
Library 선택
app/build.gradle
에 Live 라이브러리, 통합된 라이브러리, 분할된 라이브러리 중 선택해서 추가하세요.
통합된 library
dependencies {
def shoplive_sdk_version = "1.6.4.1"
// Shoplive combined packaging
implementation "cloud.shoplive:shoplive-sdk-all:$shoplive_sdk_version" // live + short-form + editor
}
분할된 library
dependencies {
def shoplive_sdk_version = "1.6.4.1"
def your_exoplayer_version = "2.19.1"
def your_media3_version = "1.4.1"
def shoplive_exoplayer_version = your_exoplayer_version + "." + "8"
def shoplive_media3_version = your_media3_version + "." + "8"
// Shoplive split packaging
implementation "cloud.shoplive:shoplive-common:$shoplive_sdk_version" // must required
implementation "cloud.shoplive:shoplive-exoplayer:$shoplive_exoplayer_version" // must required
// When using media3. Exoplayer will be deprecated soon.
// https://developer.android.com/guide/topics/media/media3/getting-started/migration-guide
// implementation "cloud.shoplive:shoplive-media3:$shoplive_media3_version"
implementation "cloud.shoplive:shoplive-network:$shoplive_sdk_version" // must required
implementation "cloud.shoplive:shoplive-filter:$shoplive_sdk_version" // for short-form editor
implementation "cloud.shoplive:shoplive-video-editor:$shoplive_sdk_version" // for short-form editor
implementation "cloud.shoplive:shoplive-sdk-core:$shoplive_sdk_version" // for live player
implementation "cloud.shoplive:shoplive-short-form:$shoplive_sdk_version" // for short-form player
}
Proguard Rule 추가
R8 Build를 하면 난독화 문제가 발생할 수 있습니다. 아래의 내용을 추가해주세요.
-keep public class cloud.shoplive.** { *; }
-dontwarn cloud.shoplive.**
-keep class org.json.** { *; }
-keep class com.google.gson.** { *; }
AccessKey 적용
ShopLiveCommon.setAccessKey("your accessKey")
Access Key
Access key 와 secret key는 샵라이브 담당자로부터 제공받을 수 있습니다.
largeHeap 추가
저사양 단말에서 Memory 관련 문제가 발생할 수 있습니다. AndroidManifest.xml 아래의 내용을 추가해주세요.
<application
android:largeHeap="true">
JNI 충돌
2 files found with path 'lib/arm64-v8a/libc++_shared.so' from inputs
충돌이 발생할 경우 build.gradle에 아래 내용을 추가해주세요.
android {
packagingOptions {
pickFirst("lib/x86/libc++_shared.so")
pickFirst("lib/x86_64/libc++_shared.so")
pickFirst("lib/armeabi-v7a/libc++_shared.so")
pickFirst("lib/arm64-v8a/libc++_shared.so")
}
}
ShopLiveVideoEditor
data 설정
ShopLiveVideoEditorData
Property name | Type | Description |
---|---|---|
maxVideoDuration | Long | 최대 Video Duration milliseconds (Default : 600000) |
minVideoDuration | Long | 최소 Video Duration milliseconds (Default : 1000) |
isCreatedShortform | Boolean | Short-form을 바로 생성 할 수 있는 기능 (Default: true) |
outputVideoQuality | ShopLiveVideoEditorVideoQuality | output video의 품질을 선택 할 수 있는 기능 (Default: NORMAL) |
outputResolution | ShopLiveVideoEditorResolution | output video의 해상도를 선택 할 수 있는 기능 (Default: RESOLUTION_720) |
aspectRatio | ShopLiveShortformEditorAspectRatio | Crop 기능의 종횡비를 선택 할 수 있는 기능 |
visibleActionButton | ShopLiveShortformEditorVisibleActionButton | Video editor의 기능을 선택 할 수 있는 기능 |
ShopLiveShortformEditorAspectRatio
Property name | Type | Description |
---|---|---|
width | Int | Crop width 비율 (Default : 9) |
height | Int | Crop height 비율 (Default : 16) |
isFixed | Boolean | Crop 종횡비를 유지 시키는 기능 (Default: false) |
ShopLiveShortformEditorVisibleActionButton
Property name | Type | Description |
---|---|---|
isUsedFilterButton | Boolean | Video의 필터를 사용할 수 있는 기능 (Default: true) |
isUsedVolumeButton | Boolean | Video의 볼륨을 조절 할 수 있는 사용할 수 있는 기능 (Default: true) |
isUsedPlaybackSpeedButton | Boolean | Video의 속도 조절 할 수 있는 버튼을 사용할 수 있는 기능 (Default: true) |
isUsedCropButton | Boolean | Video의 크기를 조절 할 수 있는 버튼을 사용할 수 있는 기능 (Default: true) |
handler 설정
class ShopLiveVideoEditorHandler {
open fun onSuccess(videoEditorActivity: ComponentActivity, result: ShopLiveEditorResultData) {
// Do something
}
open fun onEvent(
context: Context,
command: String,
payload: Map<String, Any?>
) {
// Do something
}
open fun onError(context: Context, error: ShopLiveCommonError) {
// Do something
}
open fun onCancel() {
// Do something
}
}
ShopLiveEditorResultData
Property name | Type | Description |
---|---|---|
shortsId | String? | 생성된 shortsId의 값 (data의 속성 isCreatedShortform이 true 일 때 확인 가능) |
localVideoUri | Uri | 생성된 Local Video uri |
localCoverImageUri | Uri | 생성된 Local Cover uri |
remoteOriginVideoUrl | String? | 생성된 Remote 원본 Video url (data의 속성 isCreatedShortform이 true 일 때 확인 가능) |
remoteCoverImageUrl | String? | 생성된 Remote Cover url, 첫 프레임 (data의 속성 isCreatedShortform이 true 일 때 확인 가능) |
width | Int | 생성된 Video의 width |
height | Int | 생성된 Video의 height |
duration | Long | 생성된 Video의 duration |
customize 설정
Video editor 실행
ShopLiveEditorLocalData
갤러리의 Media를 사용할 때 사용합니다.
data class ShopLiveEditorLocalData(
override val uri: Uri?,
) : ShopLiveEditorBaseData(uri)
ShopLiveEditorCameraData
카메라를 사용할 때 사용합니다.
data class ShopLiveEditorCameraData(
override val uri: Uri?,
) : ShopLiveEditorBaseData(uri)
example
ShopLiveVideoEditor(activity)
.setData(ShopLiveVideoEditorData())
.setHandler(object : ShopLiveVideoEditorHandler() {
override fun onSuccess(
videoEditorActivity: ComponentActivity,
result: ShopLiveEditorResultData
) {
super.onSuccess(videoEditorActivity, result)
}
override fun onError(context: Context, error: ShopLiveCommonError) {
super.onError(context, error)
}
override fun onCancel() {
super.onCancel()
}
}).start(ShopLiveEditorLocalData(it))
ShopLiveCoverPicker
data 설정
ShopLiveCoverPickerData
Property name | Type | Description |
---|---|---|
shortsId | String? | shortsId에 해당 하는 Cover를 업데이트 할 수 있는 기능 |
aspectRatio | ShopLiveShortformEditorAspectRatio | Crop 기능의 종횡비를 선택 할 수 있는 기능 |
visibleActionButton | ShopLiveCoverPickerVisibleActionButton | Cover picker의 기능을 선택 할 수 있는 기능 |
ShopLiveShortformEditorAspectRatio
Property name | Type | Description |
---|---|---|
width | Int | Crop width 비율 (Default : 9) |
height | Int | Crop height 비율 (Default : 16) |
isFixed | Boolean | Crop 종횡비를 유지 시키는 기능 (Default: false) |
ShopLiveShortformEditorVisibleActionButton
Property name | Type | Description |
---|---|---|
isUsedCropButton | Boolean | Video의 크기를 조절 할 수 있는 버튼을 사용할 수 있는 기능 (Default: true) |
handler 설정
class ShopLiveCoverPickerHandler {
open fun onSuccess(coverPickerActivity: ComponentActivity, result: ShopLiveEditorResultData) {
// Do something
}
open fun onEvent(
context: Context,
command: String,
payload: Map<String, Any?>
) {
// Do something
}
open fun onError(context: Context, error: ShopLiveCommonError) {
// Do something
}
open fun onCancel() {
// Do something
}
}
ShopLiveEditorResultData
Property name | Type | Description |
---|---|---|
shortsId | String? | 기존 shortsId의 값 (data의 속성 shortsId을 입력할 때 확인 가능) |
localVideoUri | Uri | 생성된 Local Video uri |
localCoverImageUri | Uri | 변경된 Local Cover uri |
remoteOriginVideoUrl | String? | 기존 Remote 원본 Video url (data의 속성 shortsId을 입력할 때 확인 가능) |
remoteCoverImageUrl | String? | 변경된 Remote Cover url (data의 속성 shortsId을 입력할 때 확인 가능) |
width | Int | 기존 Video의 width |
height | Int | 기존 Video의 height |
duration | Long | 기존 Video의 duration |
customize 설정
Cover picker 실행
ShopLiveEditorLocalData
디바이스에 저장되어 있는 영상을 사용할 때 사용합니다.
data class ShopLiveCoverPickerLocalData(
val uri: Uri?,
) : ShopLiveCoverPickerBaseData()
ShopLiveCoverPickerUrlData
외부 Url 영상을 사용해서 Cover를 선택합니다. ex) Short-form Cover 선택
data class ShopLiveCoverPickerUrlData(
val url: String?,
) : ShopLiveCoverPickerBaseData()
example
ShopLiveCoverPicker(videoEditorActivity)
.setData(ShopLiveCoverPickerData(result.shortsId))
.setHandler(object : ShopLiveCoverPickerHandler() {
override fun onSuccess(
coverPickerActivity: ComponentActivity,
result: ShopLiveEditorResultData
) {
super.onSuccess(coverPickerActivity, result)
}
override fun onError(context: Context, error: ShopLiveCommonError) {
super.onError(context, error)
}
})
.start(ShopLiveCoverPickerLocalData(result.videoUri))
응용 사용법
Gallery → Video editor → Cover picker
private fun startVideoEditor() {
activity.activityResultRegistry
.register(
"KEY_SHOPLIVE_SHORTFORM_EDITOR_VISUAL_MEDIA",
ActivityResultContracts.PickVisualMedia()
) {
if (it != null) {
ShopLiveVideoEditor(activity)
.setData(ShopLiveVideoEditorData())
.setHandler(object : ShopLiveVideoEditorHandler() {
override fun onSuccess(
videoEditorActivity: ComponentActivity,
result: ShopLiveEditorResultData
) {
super.onSuccess(videoEditorActivity, result)
ShopLiveCoverPicker(videoEditorActivity)
.setData(ShopLiveCoverPickerData(result.shortsId))
.setHandler(object : ShopLiveCoverPickerHandler() {
override fun onSuccess(
coverPickerActivity: ComponentActivity,
result: ShopLiveEditorResultData
) {
super.onSuccess(coverPickerActivity, result)
videoEditorActivity.finish() // Remove video editor
coverPickerActivity.finish() // Remove cover picker
}
override fun onError(context: Context, error: ShopLiveCommonError) {
super.onError(context, error)
handler.onError(context, error)
}
})
.start(ShopLiveCoverPickerLocalData(result.videoUri))
}
override fun onError(context: Context, error: ShopLiveCommonError) {
super.onError(context, error)
handler.onError(context, error)
}
override fun onCancel() {
super.onCancel()
startVideoEditor() // Retry gallery
}
}).start(ShopLiveEditorLocalData(it))
} else {
handler.onCancel()
}
}.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.VideoOnly))