-
Notifications
You must be signed in to change notification settings - Fork 379
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixed renderers provided by the VideoRenderProvider and updated the R…
…enderProviders to share common functionality (#802)
- Loading branch information
1 parent
dc32cd6
commit b7a22cd
Showing
6 changed files
with
123 additions
and
118 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
.../kotlin/com/devbrackets/android/exomedia/core/renderer/provider/AbstractRenderProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.devbrackets.android.exomedia.core.renderer.provider | ||
|
||
import androidx.annotation.OptIn | ||
import androidx.media3.common.util.UnstableApi | ||
import androidx.media3.exoplayer.Renderer | ||
import com.devbrackets.android.exomedia.core.renderer.RendererType | ||
import kotlin.reflect.KClass | ||
|
||
@OptIn(UnstableApi::class) | ||
abstract class AbstractRenderProvider( | ||
private val type: RendererType | ||
): RenderProvider { | ||
private var latestRenderers: List<Renderer> = emptyList() | ||
|
||
override fun type() = type | ||
override fun getLatestRenderers() = latestRenderers | ||
|
||
override fun rendererClasses(): List<String> { | ||
return emptyList() | ||
} | ||
|
||
protected fun buildRenderers( | ||
vararg initialRenderers: Renderer, | ||
action: (className: String) -> Renderer? | ||
): List<Renderer> { | ||
val renderers = mutableListOf(*initialRenderers) | ||
|
||
// Adds any registered classes | ||
rendererClasses().forEach { className -> | ||
try { | ||
action(className)?.let { renderer -> | ||
renderers.add(renderer) | ||
} | ||
} catch (e: Exception) { | ||
// Purposefully left blank | ||
} | ||
} | ||
|
||
return renderers.also { | ||
latestRenderers = it | ||
} | ||
} | ||
|
||
protected fun <T> Class<T>.newInstance(vararg params: Pair<KClass<*>, Any>): T { | ||
val types = params.map { it.first.java }.toTypedArray() | ||
val values = params.map { it.second }.toTypedArray() | ||
|
||
return getConstructor(*types).newInstance(*values) | ||
} | ||
} |
72 changes: 31 additions & 41 deletions
72
...ain/kotlin/com/devbrackets/android/exomedia/core/renderer/provider/AudioRenderProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,72 +1,62 @@ | ||
package com.devbrackets.android.exomedia.core.renderer.provider | ||
|
||
import android.content.Context | ||
import java.lang.reflect.Array | ||
import android.os.Handler | ||
import android.util.Log | ||
import androidx.annotation.OptIn | ||
import androidx.media3.common.audio.AudioProcessor | ||
import androidx.media3.common.util.UnstableApi | ||
import androidx.media3.exoplayer.Renderer | ||
import androidx.media3.exoplayer.audio.AudioCapabilities | ||
import androidx.media3.exoplayer.audio.AudioRendererEventListener | ||
import androidx.media3.exoplayer.audio.DecoderAudioRenderer | ||
import androidx.media3.exoplayer.audio.MediaCodecAudioRenderer | ||
import androidx.media3.exoplayer.mediacodec.MediaCodecSelector | ||
import com.devbrackets.android.exomedia.core.renderer.RendererType | ||
|
||
@OptIn(UnstableApi::class) | ||
open class AudioRenderProvider : RenderProvider { | ||
private var latestRenderers: List<Renderer> = emptyList() | ||
|
||
override fun type() = RendererType.AUDIO | ||
|
||
open class AudioRenderProvider : AbstractRenderProvider(RendererType.AUDIO) { | ||
override fun rendererClasses(): List<String> { | ||
return listOf( | ||
"androidx.media3.decoder.opus.LibopusAudioRenderer", | ||
"androidx.media3.decoder.flac.LibflacAudioRenderer", | ||
"androidx.media3.decoder.ffmpeg.FfmpegAudioRenderer", | ||
"androidx.media3.decoder.flac.LibflacAudioRenderer", | ||
"androidx.media3.decoder.opus.LibopusAudioRenderer" | ||
) | ||
} | ||
|
||
override fun getLatestRenderers(): List<Renderer> { | ||
return latestRenderers | ||
} | ||
|
||
fun buildRenderers(context: Context, handler: Handler, listener: AudioRendererEventListener): List<Renderer> { | ||
val renderers = mutableListOf<Renderer>() | ||
|
||
val audioCapabilities = AudioCapabilities.getCapabilities(context) | ||
renderers.add(MediaCodecAudioRenderer(context, MediaCodecSelector.DEFAULT, handler, listener, audioCapabilities)) | ||
|
||
// Adds any registered classes | ||
rendererClasses().forEach { className -> | ||
try { | ||
val renderer = buildRenderer(className, handler, listener) | ||
renderers.add(renderer) | ||
} catch (e: Exception) { | ||
// Purposefully left blank | ||
} | ||
} | ||
fun buildRenderers( | ||
context: Context, | ||
handler: Handler, | ||
listener: AudioRendererEventListener | ||
): List<Renderer> { | ||
val initialRenderer = MediaCodecAudioRenderer( | ||
context, | ||
MediaCodecSelector.DEFAULT, | ||
handler, | ||
listener, | ||
AudioCapabilities.getCapabilities(context) | ||
) | ||
|
||
return renderers.also { | ||
latestRenderers = it | ||
return buildRenderers(initialRenderer) { className -> | ||
buildRenderer(className, handler, listener) | ||
} | ||
} | ||
|
||
private fun buildRenderer( | ||
className: String, | ||
handler: Handler, | ||
listener: AudioRendererEventListener | ||
): Renderer { | ||
val rendererClass = Class.forName(className) | ||
|
||
val audioProcessorVarArg = Array.newInstance(AudioProcessor::class.java, 0) | ||
|
||
val constructor = rendererClass.getConstructor( | ||
Handler::class.java, | ||
AudioRendererEventListener::class.java, | ||
audioProcessorVarArg::class.java | ||
) | ||
|
||
return constructor.newInstance(handler, listener, audioProcessorVarArg) as Renderer | ||
): Renderer? { | ||
return when (val rendererClass = Class.forName(className)) { | ||
DecoderAudioRenderer::class.java -> rendererClass.newInstance( | ||
Handler::class to handler, | ||
AudioRendererEventListener::class to listener, | ||
arrayOf<AudioProcessor>()::class to arrayOf<AudioProcessor>() | ||
) | ||
else -> { | ||
Log.w("AudioRenderProvider", "Unsupported audio Renderer class $rendererClass") | ||
null | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 4 additions & 1 deletion
5
...src/main/kotlin/com/devbrackets/android/exomedia/core/renderer/provider/RenderProvider.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters