Reputation: 51
In my android app, it needs to play the video streams received from other apps. The video streams are received in byte array format. I am using androidx.media3.exoplayer for video playback. I had searched a lot for the sample code of streaming byte array data to Exo player but I couldn't find any solutions. The following method is used to set the byte array data to player,
@OptIn(UnstableApi::class)
private suspend fun prepareExoPlayerFromByteArray(data: ByteArray) {
if(data.isNotEmpty()) {
Log.d(TAG, ">> Data is not empty $data")
val extractorFactory = ExtractorsFactory { arrayOf(Ac3Extractor()) }
val dsf = CustomDataSourceFactory(data)
dsf.createDataSource()
val mediasourceFactory = ProgressiveMediaSource.Factory(dsf,
extractorFactory
)
withContext(Dispatchers.Main) {
exoPlayer = ExoPlayer.Builder(this@MainActivity, mediasourceFactory).build()
exoPlayer!!.setMediaItem(MediaItem.fromUri(Uri.EMPTY))
// Prepare the player.
exoPlayer!!.prepare()
// Start the playback.
exoPlayer!!.play()
}
} else {
Log.d(TAG, ">> Data is empty $data")
}
}
My intention is to initialize the instance of Exo-player only once and after that the byte array data has to be set to the player upon receiving. The above code got crashed,
Playback error androidx.media3.exoplayer.ExoPlaybackException: Source error androidx.media3.exoplayer.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:701) androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:671) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.os.HandlerThread.run(HandlerThread.java:67) Caused by: androidx.media3.common.ParserException: Loading finished before preparation is complete.{contentIsMalformed=true, dataType=1} at androidx.media3.exoplayer.source.ProgressiveMediaPeriod.maybeThrowPrepareError(ProgressiveMediaPeriod.java:247) at androidx.media3.exoplayer.source.MaskingMediaPeriod.maybeThrowPrepareError(MaskingMediaPeriod.java:157) at androidx.media3.exoplayer.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:1096)
If anyone know the correct solution for setting custom data source into Exo-player please share the exact source code...
Upvotes: 1
Views: 747
Reputation: 229
The issue you are facing might be related to the timing of preparing the player and handling the data source.
withContext(Dispatchers.Main) {
// Initialize ExoPlayer if it's not already initialized
if (exoPlayer == null) {
val mediasourceFactory = ProgressiveMediaSource.Factory(dsf, extractorFactory)
exoPlayer = ExoPlayer.Builder(this@MainActivity, mediasourceFactory).build()
exoPlayer.setMediaItem(mediaItem)
exoPlayer.prepare()
exoPlayer.play()
} else {
// ExoPlayer is already initialized, just update the media item
exoPlayer.setMediaItem(mediaItem)
exoPlayer.prepare()
exoPlayer.play()
}
}
This modification checks whether the ExoPlayer instance is already initialized. If it is, it updates the media item and prepares the player. If not, it initializes the player and sets the media item.
Upvotes: 0