From Remote URL
VideoEditor SDK supports loading audio files from a remote URL, this can be a resource hosted by a hosting provider or your servers.
Download audio#
For each remote resource, we create a File
in the cache directory and download the remote resource. Since file handling and downloading are IO operations, we do this inside a coroutine using the IO dispatcher.
Add audio assets to AssetConfig
#
AssetConfig
#To use the audio clips, they must first be available in the SDK's backend. This is done by adding the audio assets to the AssetConfig
.
The AudioTrackAsset
takes in a unique identifier, an AudioSource
, and optionally the title, artist, and duration in seconds.
Create categories#
We then add the audio clips to an AudioTrackCategoryItem
object that holds the metadata of the category such as a unique identifier, title, and optionally a preview image.
The AudioTrackItem
uses the same identifier as the one specified when creating the corresponding AudioTrackAsset
. It also optionally takes an ImageSource
that is used to display its thumbnail.
Configure UiConfigAudio
#
UiConfigAudio
#Here, we configure UiConfigAudio
and set the audio track lists.
class AddAudioOverlaysFromRemoteURL(private val activity: AppCompatActivity) : Example(activity) {// Filenames of remote assetsprivate val assetNames = arrayOf("elsewhere", "trapped_in_the_upside_down")override fun invoke() {activity.lifecycleScope.launch {showLoader(true)val files = runCatching {coroutineScope {// Download each of the remote resourcesassetNames.map {async(Dispatchers.IO) {// Create file in cache directoryval file = File(activity.cacheDir, it)if (file.exists()) file.delete()file.createNewFile()// Save remote resource to fileURL("https://img.ly/static/example-assets/$it.mp3").openStream().use { input ->file.outputStream().use { output ->input.copyTo(output)}}file}}.awaitAll() // Wait for all downloads to finish}}.getOrNull()showLoader(false)files?.let {startEditor(it)} ?: showMessage("Error downloading the file")}}private fun startEditor(files: List<File>) {// In this example, we do not need access to the Uri(s) after the editor is closed// so we pass false in the constructorval settingsList = VideoEditorSettingsList(false)// Set the source as the Uri of the image to be loaded.configure<LoadSettings> {it.source = activity.resourceUri(R.raw.skater)}// Add asset to AssetConfigassetNames.forEachIndexed { idx, name ->settingsList.config.addAsset(AudioTrackAsset("id_$name", AudioSource.create(files[idx])))}val audioTrackCategories = listOf(AudioTrackCategoryItem("audio_cat_elsewhere", "Elsewhere", assetNames.map { AudioTrackItem("id_$it") }))settingsList.configure<UiConfigAudio> {it.setAudioTrackLists(audioTrackCategories)}// Start the video editor using VideoEditorBuilder// The result will be obtained in onActivityResult() corresponding to EDITOR_REQUEST_CODEVideoEditorBuilder(activity).setSettingsList(settingsList).startActivityForResult(activity, EDITOR_REQUEST_CODE)// Release the SettingsList once donesettingsList.release()}override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {intent ?: returnif (requestCode == EDITOR_REQUEST_CODE) {// Wrap the intent into an EditorSDKResultval result = EditorSDKResult(intent)when (result.resultStatus) {EditorSDKResult.Status.CANCELED -> showMessage("Editor cancelled")EditorSDKResult.Status.EXPORT_DONE -> showMessage("Result saved at ${result.resultUri}")else -> {}}}}}