Salve a tutti sto usando Exoplayer su Android per visualizzare dei flussi video live; le url che mi arrivano per la fruizione del video sono sia in rtmp che in rtsp (entrambi visibili su VLC da PC su open internet)
Sul terminale android il flusso RTMP si vede mentre quello RTSP no e rimane lo schermo nero.

A livello di codice ho implementato questo

ExoPlayerMgr
codice:
    @IntDef(PlayerState.PLAYER_IDLE, PlayerState.PLAYER_LOADING, PlayerState.PLAYER_READY, PlayerState.PLAYER_PAUSED, PlayerState.PLAYER_FAILED, PlayerState.PLAYER_BUFFERING, PlayerState.PLAYER_ENDED, PlayerState.PLAYER_STOPPED)
    @Retention(AnnotationRetention.SOURCE)
    annotation class PlayerState {
        companion object {
            const val PLAYER_IDLE = -1
const val PLAYER_LOADING = 0
const val PLAYER_READY = 1
const val PLAYER_PAUSED = 2
const val PLAYER_FAILED = 3
const val PLAYER_BUFFERING = 4
const val PLAYER_ENDED = 5
const val PLAYER_STOPPED = 6
}
    }

private val mediaSourceEventListener: MediaSourceEventListener = object :
        MediaSourceEventListener {
        override fun onLoadStarted(windowIndex: Int, mediaPeriodId: MediaSource.MediaPeriodId?, loadEventInfo: LoadEventInfo, mediaLoadData: MediaLoadData) {
            MyLog.d(reqTag, "onLoadStarted....")
        }
        override fun onLoadCompleted(windowIndex: Int, mediaPeriodId: MediaSource.MediaPeriodId?, loadEventInfo: LoadEventInfo, mediaLoadData: MediaLoadData) {
            MyLog.d(reqTag, "onLoadCompleted....")
        }
        override fun onLoadCanceled(windowIndex: Int, mediaPeriodId: MediaSource.MediaPeriodId?, loadEventInfo: LoadEventInfo, mediaLoadData: MediaLoadData) {
            MyLog.d(reqTag, "onLoadCanceled....")
        }
        override fun onLoadError(windowIndex: Int, mediaPeriodId: MediaSource.MediaPeriodId?, loadEventInfo: LoadEventInfo, mediaLoadData: MediaLoadData, error: IOException, wasCanceled: Boolean) {
            MyLog.d(reqTag, "onLoadError - error cause: ${error.cause} - error message: ${error.message}")
            listener?.onPlayerStateChanged(PlayerState.PLAYER_FAILED, 1000, "errorDescription: ${error.message} - errorCause: ${error.cause}")
        }
        override fun onUpstreamDiscarded(windowIndex: Int, mediaPeriodId: MediaSource.MediaPeriodId, mediaLoadData: MediaLoadData) {
            MyLog.d(reqTag, "onUpstreamDiscarded....")
        }
        override fun onDownstreamFormatChanged(windowIndex: Int, mediaPeriodId: MediaSource.MediaPeriodId?, mediaLoadData: MediaLoadData) {
            MyLog.d(reqTag, "onDownstreamFormatChanged....")
        }
    }

    fun play() {
        firstReady = true
isInterrupted = false
initPlayer(null)
        listener?.onPlayerStateChanged(PlayerState.PLAYER_LOADING, 0, "")

        var mediaSource: MediaSource

        var rtmp = false
        if (videoUrl.startsWith("rtmp")) rtmp = true

        val mediaitem = MediaItem.fromUri(Uri.parse(videoUrl))
        if (rtmp) {
            val rtmpFactory = RtmpDataSource.Factory()
            mediaSource =
                ProgressiveMediaSource.Factory(rtmpFactory).createMediaSource(mediaitem)
        } else {
            mediaSource = RtspMediaSource.Factory().setForceUseRtpTcp(true)
                .createMediaSource(MediaItem.fromUri(videoUrl))
        }
        mediaSource.addEventListener(mainHandler, mediaSourceEventListener)
        player?.repeatMode = repatMode
        player?.setMediaSource(mediaSource ,true)
        player?.prepare()
        MyLog.d(reqTag, "playing clear videoUrl: $videoUrl")
    }

private fun initPlayer(drm: DrmSessionManager?) {
        MyLog.d(reqTag,"initPlayer...")
        if (ctx.get() == null) {
            MyLog.d(reqTag,"initPlayer -> ctx.get() null...")
            ctx = WeakReference(MyApplication.appContext)
        }
        trackSelector = DefaultTrackSelector(context, AdaptiveTrackSelection.Factory())
        val params = trackSelector!!.parameters.buildUpon()
        params.setMaxVideoSize(1920, 1080)
        trackSelector!!.parameters = params.build()
        if (dataSourceFactory == null) {
            dataSourceFactory = DefaultDataSource.Factory(context, createHTTPDataSource())
        }
        drm?.prepare()

        player = ExoPlayer.Builder(context).setTrackSelector(trackSelector!!).setLoadControl(
            DefaultLoadControl()
        ).build()
        player?.playWhenReady = true
player?.addListener(this)
        playerView?.player = player
}
Quello che vedo succedere è questo:
nel flusso RTMP il player inizia in stato BUFFERING poi vedo i log dei metodi onLoadStarted e onLoadCompleted del MediaSourceEventListener e quindi si arriva allo stato PLAYING e il flusso video si vede mentre per il flusso RTSP non vedo il log di onLoadStarted e rimane bloccato nel buffering.

Qualche idea?

Grazie a chi risponderà