diff --git a/app/build.gradle b/app/build.gradle
index e1352257..53ee1b37 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -64,21 +64,11 @@ dependencies {
// Banuba Video Editor SDK dependencies
def banubaSdkVersion = '1.39.1'
- implementation "com.banuba.sdk:ffmpeg:5.1.3"
- implementation "com.banuba.sdk:camera-sdk:${banubaSdkVersion}"
- implementation "com.banuba.sdk:camera-ui-sdk:${banubaSdkVersion}"
implementation "com.banuba.sdk:core-sdk:${banubaSdkVersion}"
implementation "com.banuba.sdk:core-ui-sdk:${banubaSdkVersion}"
- implementation "com.banuba.sdk:ve-flow-sdk:${banubaSdkVersion}"
- implementation "com.banuba.sdk:ve-sdk:${banubaSdkVersion}"
- implementation "com.banuba.sdk:ve-ui-sdk:${banubaSdkVersion}"
implementation "com.banuba.sdk:ve-gallery-sdk:${banubaSdkVersion}"
- implementation "com.banuba.sdk:ve-effects-sdk:${banubaSdkVersion}"
implementation "com.banuba.sdk:effect-player-adapter:${banubaSdkVersion}"
implementation "com.banuba.sdk:ar-cloud:${banubaSdkVersion}"
- implementation "com.banuba.sdk:ve-audio-browser-sdk:${banubaSdkVersion}"
- implementation "com.banuba.sdk:ve-export-sdk:${banubaSdkVersion}"
- implementation "com.banuba.sdk:ve-playback-sdk:${banubaSdkVersion}"
// Photo Editor SDK dependency
// WARNING!
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1c592396..f0a13024 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -24,12 +24,6 @@
-
- // The dialog is used only to demonstrate and play an exported video file.
-
- // Release Video Editor SDK after exporting video and closing the latest SDK screen
- //(application as? SampleApp)?.releaseVideoEditor()
- Log.d(SampleApp.TAG, "Video Editor export result = $result")
-
- if (result is ExportResult.Success) {
- AlertDialog.Builder(this).setMessage("Export result")
- .setPositiveButton("Play Video") { _, _ ->
- playExportedVideo(result)
- }
- .setNeutralButton("Close") { _, _ ->
- }.create().show()
- }
- }
-
- private fun playExportedVideo(exportResult: ExportResult.Success) {
- exportResult.videoList.firstOrNull()?.let {
- Utils.playExportedVideo(this@MainActivity, it.sourceUri)
- }
- }
-
- // Opens system app to pick video for PIP
- private val requestVideoOpenPIP = registerForActivityResult(
- ActivityResultContracts.GetContent()
- ) { videoPipUri ->
- if (videoPipUri != Uri.EMPTY && videoPipUri != null) {
- openVideoEditor(pipVideo = videoPipUri)
- }
- }
-
- // Opens system app to pick image for Trimmer
- private val requestImageOpenTrimmer = registerForActivityResult(
- ActivityResultContracts.GetContent()
- ) { imageUri ->
- if (imageUri != Uri.EMPTY && imageUri != null) {
- val slideShowList =
- Utils.createSlideShowList(
- applicationContext,
- lifecycleScope,
- imageUri
- )
- openVideoEditorTrimmerWithSlideShow(slideShowList)
- }
- }
-
private val requestImageOpenPhotoEditor = registerForActivityResult(
ActivityResultContracts.GetContent()
) { imageUri ->
@@ -121,8 +66,8 @@ class MainActivity : AppCompatActivity() {
setContentView(binding.root)
// Handle Video Editor license flow
- val videoEditor = sampleApp.videoEditor
- if (videoEditor == null) {
+ val photoEditor = sampleApp.photoEditor
+ if (photoEditor == null) {
binding.licenseStateView.visible()
binding.licenseStateView.text = ERR_SDK_NOT_INITIALIZED
return
@@ -130,23 +75,9 @@ class MainActivity : AppCompatActivity() {
// Might take up to 1 sec in the worst case.
// Please optimize use of this function in your project to bring the best user experience
- videoEditor.getLicenseState { isValid ->
+ photoEditor.getLicenseState { isValid ->
if (isValid) {
// ✅ License is active, all good
- // You can show button that opens Video Editor or
- // Start Video Editor right away
- binding.btnVideoEditor.setOnClickListener {
- openVideoEditor()
- }
- binding.btnPiPVideoEditor.setOnClickListener {
- requestVideoOpenPIP.launch("video/*")
- }
- binding.btnDraftsVideoEditor.setOnClickListener {
- openVideoEditorDrafts()
- }
- binding.btnSlideShowVideoEditorTrimmer.setOnClickListener {
- requestImageOpenTrimmer.launch("image/*")
- }
binding.btnOpenPhotoEditor.setOnClickListener {
// Start Photo Editor SDK
startPhotoEditor(PhotoCreationActivity.startFromGallery(this@MainActivity))
@@ -161,11 +92,6 @@ class MainActivity : AppCompatActivity() {
binding.licenseStateView.text = ERR_LICENSE_REVOKED
Log.w(SampleApp.TAG, ERR_LICENSE_REVOKED)
- binding.licenseStateView.visible()
- binding.btnVideoEditor.isEnabled = false
- binding.btnPiPVideoEditor.isEnabled = false
- binding.btnDraftsVideoEditor.isEnabled = false
- binding.btnSlideShowVideoEditorTrimmer.isEnabled = false
binding.btnOpenPhotoEditor.isEnabled = false
}
}
@@ -176,42 +102,6 @@ class MainActivity : AppCompatActivity() {
_binding = null
}
- private fun openVideoEditor(pipVideo: Uri = Uri.EMPTY) {
- val videoCreationIntent = VideoCreationActivity.startFromCamera(
- context = this,
- // set PiP video configuration
- pictureInPictureConfig = PipConfig(
- video = pipVideo,
- openPipSettings = false
- ),
- // setup what kind of action you want to do with VideoCreationActivity
- // setup data that will be acceptable during export flow
- additionalExportData = null,
- // set TrackData object if you open VideoCreationActivity with preselected music track
- audioTrackData = null
- )
- startVideoEditor(videoCreationIntent)
- }
-
- private fun openVideoEditorDrafts() {
- startVideoEditor(VideoCreationActivity.startFromDrafts(this))
- }
-
- private fun openVideoEditorTrimmerWithSlideShow(videos: List) {
- startVideoEditor(
- VideoCreationActivity.startFromTrimmer(
- this,
- videos.toTypedArray()
- )
- )
- }
-
- private fun startVideoEditor(intent: Intent) {
- sampleApp.prepareVideoEditor()
-
- videoEditorExportResult.launch(intent)
- }
-
private fun startPhotoEditor(intent: Intent) {
sampleApp.preparePhotoEditor()
diff --git a/app/src/main/java/com/banuba/example/integrationapp/SampleApp.kt b/app/src/main/java/com/banuba/example/integrationapp/SampleApp.kt
index b1b51a10..8ef2ca3d 100644
--- a/app/src/main/java/com/banuba/example/integrationapp/SampleApp.kt
+++ b/app/src/main/java/com/banuba/example/integrationapp/SampleApp.kt
@@ -22,75 +22,17 @@ class SampleApp : Application() {
const val ERR_LICENSE_REVOKED =
"License is revoked or expired. Please contact Banuba https://www.banuba.com/faq/kb-tickets/new"
}
-
- // Manages Video Editor SDK
- var videoEditor: BanubaVideoEditor? = null
-
// Manages Photo Editor SDK
var photoEditor: BanubaPhotoEditor? = null
override fun onCreate() {
super.onCreate()
- // Prepare Video Editor in the beginning for simplicity
- prepareVideoEditor()
- }
-
- fun prepareVideoEditor() {
- // Video and Photo SDK share license management system.
- // It is required to keep only one instance.
-
- if (photoEditor != null) {
- BanubaPhotoEditor.release()
- photoEditor = null
- }
-
- if (videoEditor == null) {
- Log.d(TAG, "Prepare Video Editor SDK")
-
- // Initialize Video Editor
- VideoEditorModule().initialize(this@SampleApp)
-
- // Initialize Banuba Video Editor SDK
- videoEditor = BanubaVideoEditor.initialize(LICENSE_TOKEN)
-
- if (videoEditor == null) {
- // Token you provided is not correct - empty or truncated
- Log.e(TAG, ERR_SDK_NOT_INITIALIZED)
- }
- }
+ preparePhotoEditor()
}
fun preparePhotoEditor() {
- // Video and Photo SDK share license management system.
- // It is required to keep only one instance.
-
- if (videoEditor != null) {
- releaseVideoEditor()
- }
-
Log.d(TAG, "Prepare Photo Editor SDK")
// Photo Editor SDK auto releases its resources
photoEditor = BanubaPhotoEditor.initialize(LICENSE_TOKEN)
}
-
- // Call it to release VE SDK before opening PE
- private fun releaseVideoEditor() {
- Log.d(TAG, "Release Video Editor SDK")
- releaseUtilityManager()
- stopKoin()
- videoEditor = null
- }
-
- private fun releaseUtilityManager() {
- val utilityManager = try {
- // EditorUtilityManager is NULL when the token is expired or revoked.
- // This dependency is not explicitly created in DI.
- getKoin().getOrNull()
- } catch (e: InstanceCreationException) {
- Log.w(TAG, "EditorUtilityManager was not initialized!", e)
- null
- }
-
- utilityManager?.release()
- }
}
diff --git a/app/src/main/java/com/banuba/example/integrationapp/Utils.kt b/app/src/main/java/com/banuba/example/integrationapp/Utils.kt
index 4f6e76fa..92422f50 100644
--- a/app/src/main/java/com/banuba/example/integrationapp/Utils.kt
+++ b/app/src/main/java/com/banuba/example/integrationapp/Utils.kt
@@ -10,50 +10,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.lifecycle.LifecycleCoroutineScope
import com.banuba.sdk.core.ext.obtainReadFileDescriptor
-import com.banuba.sdk.ve.slideshow.SlideShowScaleMode
-import com.banuba.sdk.ve.slideshow.SlideShowSource
-import com.banuba.sdk.ve.slideshow.SlideShowTask
import kotlinx.coroutines.launch
import java.io.File
// Helper methods not required for the SDK integration
object Utils {
- // Creates the list with 2 video sources - the first based on image taken from gallery and
- // the second on image taken from assets
- fun createSlideShowList(
- context: Context,
- lifecycleCoroutineScope: LifecycleCoroutineScope,
- selectedImage: Uri
- ): List {
- val list = mutableListOf()
- lifecycleCoroutineScope.launch {
- val externalSlideshowDir =
- File(context.getExternalFilesDir(null), "slideshow").apply { mkdirs() }
-
- list.add(buildSlideshowFromFile(context, selectedImage, externalSlideshowDir))
- list.add(buildSlideshowFromBitmap(context, externalSlideshowDir))
- }
- return list
- }
-
- // Plays exported video to demonstrate the result
- fun playExportedVideo(
- activity: AppCompatActivity,
- videoUri: Uri
- ) {
- val intent = Intent(Intent.ACTION_VIEW).apply {
- addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
- val uri = FileProvider.getUriForFile(
- activity,
- "${activity.packageName}.provider",
- File(videoUri.encodedPath ?: "")
- )
- setDataAndType(uri, "video/mp4")
- }
- activity.startActivity(intent)
- }
-
- // Previews exported image to demonstrate the result
fun previewExportedImage(
activity: AppCompatActivity,
uri: Uri
@@ -68,64 +29,4 @@ object Utils {
Log.e(SampleApp.TAG, "Can't handle intent")
}
}
-
- /**
- * Helper function to create slideshow video from image taken from the gallery.
- * It is highly recommended to execute in the background thread
- */
- private suspend fun buildSlideshowFromFile(
- context: Context,
- source: Uri,
- folder: File
- ): Uri {
- val slideshowFromFile = File(folder, "slideshowFromFile.mp4").apply { createNewFile() }
- return context.obtainReadFileDescriptor(source)?.let {
- val params = SlideShowTask.Params.create(
- context = context,
- size = Size(1280, 768),
- destFile = slideshowFromFile,
- sources = listOf(
- SlideShowSource.File(
- source = source,
- durationMs = 3000
- )
- ),
- animationEnabled = true,
- debugEnabled = true,
- scaleMode = SlideShowScaleMode.SCALE_BALANCED
- )
- SlideShowTask.makeVideo(params)
- Uri.fromFile(slideshowFromFile)
- } ?: Uri.EMPTY
- }
-
- /**
- * Helper function to create slideshow video from image taken from assets.
- * It is highly recommended to execute in the background thread
- */
- private suspend fun buildSlideshowFromBitmap(
- context: Context,
- folder: File
- ): Uri {
- val slideshowFromBitmap = File(folder, "slideshowFromBitmap.mp4").apply { createNewFile() }
- val bitmap = context.assets.open("image_sample.jpeg").run {
- BitmapFactory.decodeStream(this)
- }
- val params = SlideShowTask.Params.create(
- context = context,
- size = Size(1280, 768),
- destFile = slideshowFromBitmap,
- sources = listOf(
- SlideShowSource.Picture(
- source = bitmap,
- durationMs = 3000
- )
- ),
- animationEnabled = true,
- debugEnabled = false,
- scaleMode = SlideShowScaleMode.SCALE_BALANCED
- )
- SlideShowTask.makeVideo(params)
- return Uri.fromFile(slideshowFromBitmap)
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/banuba/example/integrationapp/VideoEditorModule.kt b/app/src/main/java/com/banuba/example/integrationapp/VideoEditorModule.kt
index 3e13e3b8..d2aa3149 100644
--- a/app/src/main/java/com/banuba/example/integrationapp/VideoEditorModule.kt
+++ b/app/src/main/java/com/banuba/example/integrationapp/VideoEditorModule.kt
@@ -1,67 +1,67 @@
package com.banuba.example.integrationapp
-
-import android.content.Context
-import androidx.fragment.app.Fragment
-import com.banuba.sdk.arcloud.data.source.ArEffectsRepositoryProvider
-import com.banuba.sdk.arcloud.di.ArCloudKoinModule
-import com.banuba.sdk.audiobrowser.di.AudioBrowserKoinModule
-import com.banuba.sdk.audiobrowser.domain.AudioBrowserMusicProvider
-import com.banuba.sdk.core.data.TrackData
-import com.banuba.sdk.core.ui.ContentFeatureProvider
-import com.banuba.sdk.effectplayer.adapter.BanubaEffectPlayerKoinModule
-import com.banuba.sdk.export.di.VeExportKoinModule
-import com.banuba.sdk.gallery.di.GalleryKoinModule
-import com.banuba.sdk.playback.di.VePlaybackSdkKoinModule
-import com.banuba.sdk.ve.di.VeSdkKoinModule
-import com.banuba.sdk.ve.flow.di.VeFlowKoinModule
-import com.banuba.sdk.veui.di.VeUiSdkKoinModule
-import org.koin.android.ext.koin.androidContext
-import org.koin.core.context.startKoin
-import org.koin.core.qualifier.named
-import org.koin.dsl.module
-
-class VideoEditorModule {
-
- fun initialize(applicationContext: Context) {
- startKoin {
- androidContext(applicationContext)
- allowOverride(true)
-
- // pass the customized Koin modules that implements required dependencies. Keep order of modules
- modules(
- VeSdkKoinModule().module,
- VeExportKoinModule().module,
- VePlaybackSdkKoinModule().module,
- AudioBrowserKoinModule().module,
- ArCloudKoinModule().module,
- VeUiSdkKoinModule().module,
- VeFlowKoinModule().module,
- GalleryKoinModule().module,
- BanubaEffectPlayerKoinModule().module,
- SampleIntegrationKoinModule().module,
- )
- }
- }
-}
-
-/**
- * All dependencies mentioned in this module will override default
- * implementations provided from SDK.
- */
-private class SampleIntegrationKoinModule {
-
- val module = module {
- single(createdAtStart = true) {
- ArEffectsRepositoryProvider(
- arEffectsRepository = get(named("backendArEffectsRepository")),
- ioDispatcher = get(named("ioDispatcher"))
- )
- }
-
- single>(
- named("musicTrackProvider")
- ) {
- AudioBrowserMusicProvider()
- }
- }
-}
+//
+//import android.content.Context
+//import androidx.fragment.app.Fragment
+//import com.banuba.sdk.arcloud.data.source.ArEffectsRepositoryProvider
+//import com.banuba.sdk.arcloud.di.ArCloudKoinModule
+//import com.banuba.sdk.audiobrowser.di.AudioBrowserKoinModule
+//import com.banuba.sdk.audiobrowser.domain.AudioBrowserMusicProvider
+//import com.banuba.sdk.core.data.TrackData
+//import com.banuba.sdk.core.ui.ContentFeatureProvider
+//import com.banuba.sdk.effectplayer.adapter.BanubaEffectPlayerKoinModule
+//import com.banuba.sdk.export.di.VeExportKoinModule
+//import com.banuba.sdk.gallery.di.GalleryKoinModule
+//import com.banuba.sdk.playback.di.VePlaybackSdkKoinModule
+//import com.banuba.sdk.ve.di.VeSdkKoinModule
+//import com.banuba.sdk.ve.flow.di.VeFlowKoinModule
+//import com.banuba.sdk.veui.di.VeUiSdkKoinModule
+//import org.koin.android.ext.koin.androidContext
+//import org.koin.core.context.startKoin
+//import org.koin.core.qualifier.named
+//import org.koin.dsl.module
+//
+//class VideoEditorModule {
+//
+// fun initialize(applicationContext: Context) {
+// startKoin {
+// androidContext(applicationContext)
+// allowOverride(true)
+//
+// // pass the customized Koin modules that implements required dependencies. Keep order of modules
+// modules(
+// VeSdkKoinModule().module,
+// VeExportKoinModule().module,
+// VePlaybackSdkKoinModule().module,
+// AudioBrowserKoinModule().module,
+// ArCloudKoinModule().module,
+// VeUiSdkKoinModule().module,
+// VeFlowKoinModule().module,
+// GalleryKoinModule().module,
+// BanubaEffectPlayerKoinModule().module,
+// SampleIntegrationKoinModule().module,
+// )
+// }
+// }
+//}
+//
+///**
+// * All dependencies mentioned in this module will override default
+// * implementations provided from SDK.
+// */
+//private class SampleIntegrationKoinModule {
+//
+// val module = module {
+// single(createdAtStart = true) {
+// ArEffectsRepositoryProvider(
+// arEffectsRepository = get(named("backendArEffectsRepository")),
+// ioDispatcher = get(named("ioDispatcher"))
+// )
+// }
+//
+// single>(
+// named("musicTrackProvider")
+// ) {
+// AudioBrowserMusicProvider()
+// }
+// }
+//}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 10a81c4b..0361baed 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -6,75 +6,19 @@
android:layout_height="match_parent"
tools:context=".MainActivity">
-
-
-
-
-
-
-
-
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintVertical_chainStyle="packed" />
+ app:layout_constraintVertical_bias="0"
+ app:layout_constraintVertical_chainStyle="packed"/>
@color/primaryBrandLight
- ?attr/colorPrimary
-
-
-