Wednesday, 1 February 2023

How to restart video play when we getting MediaPlayer.Event.EncounteredError in Media player Android (LibVlc)

This is my code for class file

class LiveVideoFragment : BaseFragment(), IVLCVout.Callback {
    private var libvlc: LibVLC? = null
    private lateinit var holder: SurfaceHolder
    private lateinit var mMediaPlayer: MediaPlayer
    private var mFilePath = "rtsp://192.168.0.1:554/livestream/1"
    private var mVideoWidth = 0
    private var mVideoHeight = 0


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_rove_r3_live_video, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        showLiveVideoWhenR3Connected()

    }


    override fun onPause() {
        super.onPause()
        Log.d("CALLBACKK", "onPause")

        Handler(Looper.getMainLooper()).postDelayed({ releasePlayer() }, 200)

    }


    private fun showLiveVideoWhenR3Connected() {
        handleRtsp()
        createPlayer(mFilePath)
    }


    override fun onNewLayout(
        vlcVout: IVLCVout?,
        width: Int,
        height: Int,
        visibleWidth: Int,
        visibleHeight: Int,
        sarNum: Int,
        sarDen: Int
    ) {
        if (width * height == 0) return
        mVideoWidth = width
        mVideoHeight = height
        setSize(mVideoWidth, mVideoHeight)
    }

    override fun onSurfacesCreated(vlcVout: IVLCVout?) {
    }

    override fun onSurfacesDestroyed(vlcVout: IVLCVout?) {
    }

    override fun onHardwareAccelerationError(vlcVout: IVLCVout?) {
        Handler(Looper.getMainLooper()).postDelayed({ releasePlayer() }, 200)
        Toast.makeText(
            requireContext(),
            R.string.error_with_hardware_acceleration,
            Toast.LENGTH_LONG
        )
            .show()
    }


    fun createPlayer(path: String) {
        try {
            releasePlayer()
            // TODO: make this more robust, and sync with audio demo
            val options = ArrayList<String>()
            options.add("--audio-time-stretch") // time stretching
            options.add("-vvv") // verbosity
            options.add("--rtsp-tcp")
            libvlc = LibVLC(context, options)
            holder.setKeepScreenOn(true)

            // Creating media player
            mMediaPlayer = MediaPlayer(libvlc)
            mMediaPlayer.setEventListener(mPlayerListener)

            // Seting up video output
            val vout: IVLCVout = mMediaPlayer.vlcVout
            vout.setVideoView(view_surface)
            vout.addCallback(this)
            vout.attachViews()
            val m = Media(libvlc, Uri.parse(path))
            val cache = 500
            m.addOption(":network-caching=$cache")
            m.addOption(":file-caching=$cache")
            m.addOption(":live-cacheing=$cache")
            m.addOption(":sout-mux-caching=$cache")
            m.addOption(":codec=mediacodec,iomx,all")
            mMediaPlayer.media = m
            mMediaPlayer.play()
            val volume: Int = mMediaPlayer.volume
            mMediaPlayer.volume = 0
            Log.i("TAG", "createPlayerVolume: $volume")
        } catch (e: Exception) {
            Log.i("TAG", "createPlayer: " + e.localizedMessage)
        }
    }

    private fun releasePlayer() {
        if (libvlc == null)
            return
        mMediaPlayer.stop()
        val vout = mMediaPlayer.vlcVout
        vout.removeCallback(this)
        vout.detachViews()
        libvlc?.release()
    }

    private fun handleRtsp() {
        holder = view_surface.holder
    }

    private val mPlayerListener: MediaPlayer.EventListener = MyPlayerListener(this)

    inner class MyPlayerListener(owner: Rove3LiveVideoFragment) : MediaPlayer.EventListener {
        private val mOwner: WeakReference<Rove3LiveVideoFragment>

        init {
            mOwner = WeakReference(owner)
        }

        override fun onEvent(event: MediaPlayer.Event) {
            val player = mOwner.get()
            when (event.type) {
                MediaPlayer.Event.EndReached -> {
                    Log.d("MediaPlayerEVENTERRO", "MediaPlayerEndReached")
                    player?.releasePlayer()
                }
                MediaPlayer.Event.EncounteredError -> {
                    player?.releasePlayer()
                    libvlc?.release()
                    mMediaPlayer.stop()
                    mMediaPlayer.pause()
                    mMediaPlayer.retain()
                    mMediaPlayer.isSeekable
                    createPlayer(mFilePath)
                    val m = Media(libvlc, Uri.parse(mFilePath))
                    val cache = 1500

//                    m.addOption(":network-caching=$cache")
//                    m.addOption(":file-caching=$cache")
//                    m.addOption(":live-cacheing=$cache")
//                    m.addOption(":sout-mux-caching=$cache")
//                    m.addOption(":codec=mediacodec,iomx,all")
                    mMediaPlayer.media = m
                    mMediaPlayer.play()
                    Log.d("MediaPlayerEVENTERROR", "Media Player Error, re-try")
                }
                MediaPlayer.Event.Playing, MediaPlayer.Event.Paused, MediaPlayer.Event.Stopped -> {}
                else -> {}
            }
        }
    }

    private fun setSize(width: Int, height: Int) {
        mVideoWidth = width
        mVideoHeight = height
        if (mVideoWidth * mVideoHeight <= 1) return
        if (holder == null || view_surface == null) return
        var w = activity?.window?.decorView?.width
        var h = activity?.window?.decorView?.height
        val isPortrait = resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT
        if (w != null) {
            if (w > h!! && isPortrait || w < h && !isPortrait) {
                val i = w
                w = h
                h = i
            }
        }
        val videoAR = mVideoWidth.toFloat() / mVideoHeight.toFloat()
        val screenAR = h?.toFloat()?.let { w?.toFloat()?.div(it) }
        if (screenAR != null) {
            if (screenAR < videoAR) if (w != null) {
                h = (w / videoAR).toInt()
            } else if (h != null) {
                w = (h * videoAR).toInt()
            }
        }
        holder.setFixedSize(mVideoWidth, mVideoHeight)
        val lp: ViewGroup.LayoutParams = view_surface.layoutParams


        if (w != null) {
            lp.width = w
        }
        if (h != null) {
            lp.height = h
        }
        view_surface.layoutParams = lp
        view_surface.invalidate()
    }
}

this code is working fine i am able to show live video using rtsp player Some time when i fast open app then i am getting MediaPlayer.Event.EncounteredError i don't know what is reason but in that function i am trying to again restart and create media player but still my video is not playing its showing full black background in surface view . actually i want restart my live broadcast restart when ever any error coming like Hardware error or any MediaPlayer.Event.EncounteredError please help me what i am doing wrong how to restart live view .

I am using below library to show live video

**implementation "de.mrmaffen:vlc-android-sdk:2.0.6"
    implementation 'org.videolan.libvlc:libvlc_options:2.0.6'**


from How to restart video play when we getting MediaPlayer.Event.EncounteredError in Media player Android (LibVlc)

No comments:

Post a Comment