Search code examples
javaandroidvlclibvlc

How can I create a snapshot from the video via libvlcjni?


Before, I used TextureView as video container. I could take a snapshot via getBitmap().
But I'm updated the VLCMobileKit, and now I using this code:

        <org.videolan.libvlc.util.VLCVideoLayout
        android:id="@+id/vlc_surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" />

I tried to take a snapshot via buildDrawingCache() but is always return with an empty image.

                    videoLayout.setDrawingCacheEnabled(true);
                    videoLayout.buildDrawingCache();
                    Bitmap bitmap = videoLayout.getDrawingCache();

I tried to take a screenshot from the full of activity. I saw the video layout is transparent on the image.


Solution

  • You can not get the snapshot directly. You have to use a SurfaceView instead of VLCVideoLayout to get the current frame.

    PixelCopy class can convert the SurfaceView frame to Bitmap. So you have to replace your VLCVideoLayout with a SurfaceView. Attach this surface view to your MediaPlayer before playing the media.

    mMediaPlayer.vlcVout.setVideoView(surfaceView)
    mMediaPlayer.vlcVout.attachViews()
    

    Now use call the below function to get the current video snapshot bitmap.

    fun usePixelCopy(videoView: SurfaceView, callback: (Bitmap?) -> Unit) {
        val bitmap: Bitmap = Bitmap.createBitmap(
                videoView.width,
                videoView.height,
                Bitmap.Config.ARGB_8888
        )
        try {
            val handlerThread = HandlerThread("PixelCopier")
            handlerThread.start()
            PixelCopy.request(
                    videoView, bitmap,
                    { copyResult ->
                        if (copyResult == PixelCopy.SUCCESS) {
                            callback(bitmap)
                        }
                        handlerThread.quitSafely()
                    },
                    Handler(handlerThread.looper)
            )
        } catch (e: IllegalArgumentException) {
            callback(null)
            e.printStackTrace()
            showMessage(R.string.error)
        }
    }
    

    Note: Code is in Kotlin and works only in Android N and above. I'm using it in my VideoPlayer app.