ExoPlayer icon indicating copy to clipboard operation
ExoPlayer copied to clipboard

Am I able to play a local video file alongside streamed audio? or is it one or the other

Open mosjwarris opened this issue 3 years ago • 8 comments
trafficstars

I have local looping video files i want to play whilst streaming an audio file. Can i combine the two on the player? or do I have to pick one or the other and have 2 separate instances?

Thanks

mosjwarris avatar Aug 02 '22 14:08 mosjwarris

You may be able to do this with MergingMediaSource, and do the video looping with ConcatenatingMediaSource.

Something like:

MediaSource audioMediaSource = ...
MediaSource videoMediaSource = ...
MediaSource[] videoMediaSources = new MediaSource[???];
Arrays.fill(videoMediaSources, videoMediaSource);
MergingMediaSource mergedMediaSource =
    new MergingMediaSource(audioMediaSource, new ConcatenatingMediaSource(videoMediaSources));
player.setMediaSource(mergedMediaSource);

icbaker avatar Aug 02 '22 16:08 icbaker

MediaSource[] videoMediaSources = new MediaSource[???]; Arrays.fill(videoMediaSources, videoMediaSource); MergingMediaSource mergedMediaSource = new MergingMediaSource(audioMediaSource, new ConcatenatingMediaSource(videoMediaSources)); player.setMediaSource(mergedMediaSource);

thanks, sorry to be difficult but any chance of this example in kotlin? im new to android and not great on java syntax / conversion

mosjwarris avatar Aug 02 '22 16:08 mosjwarris

If you paste Java into a Kotlin file in Android Studio it will do a pretty good job of converting it.

icbaker avatar Aug 02 '22 16:08 icbaker

If you paste Java into a Kotlin file in Android Studio it will do a pretty good job of converting it.

i did give that a crack but android studio didnt seem to want to do it! ill persist

mosjwarris avatar Aug 02 '22 16:08 mosjwarris

I dont seem to be able to get this to work syntacticly in kotlin, the types dont play nice together to match the example

mosjwarris avatar Aug 03 '22 16:08 mosjwarris

You can create two ExoPlayer instances on two separate threads. That would be easier.

yuroyami avatar Aug 05 '22 10:08 yuroyami

Kotlin example:

fun loopVideoAgainstAudio(
    videoMediaSource : MediaSource,
    audioMediaSource : MediaSource,
    numLoops : Int) : MediaSource { 
  val videoMediaSources = Array(numLoops) {videoMediaSource}
  return MergingMediaSource(
      audioMediaSource,
      ConcatenatingMediaSource(*videoMediaSources));
}

icbaker avatar Aug 05 '22 10:08 icbaker

thanks, seems to throw an error with MergingMediaSource$IllegalMergeException using my following code, perhaps to do with how i have to convert the items into media sources first?

    override fun onBind(intent: Intent?): IBinder {
        intent?.let {
            exoPlayer.playWhenReady = true

            val videoUri = Uri.parse(intent.extras?.getString(VIDEO_FILE_ID))
            val audioUri = Uri.parse(intent.extras?.getString(AUDIO_FILE_ID))

            val videoItem = MediaItem.fromUri(videoUri)
            val audioItem = MediaItem.fromUri(audioUri)

            val videoSource = ProgressiveMediaSource
                .Factory(DefaultDataSource.Factory(this)).createMediaSource(videoItem)
            val audioSource = ProgressiveMediaSource
                .Factory(DefaultDataSource.Factory(this)).createMediaSource(audioItem)

            val source = loopVideoAgainstAudio(videoSource, audioSource, 10)
            loadMedia(source)
        }
        return VideoServiceBinder()
    }

    fun loopVideoAgainstAudio(videoMediaSource : MediaSource, audioMediaSource : MediaSource, numLoops : Int) : MediaSource {
        val videoMediaSources = Array(numLoops) { videoMediaSource }
        return MergingMediaSource(
            audioMediaSource,
            ConcatenatingMediaSource(*videoMediaSources)
        )
    }

mosjwarris avatar Aug 05 '22 13:08 mosjwarris