0
votes

Consider using libVLC for Android, based on the official recommended way.

I went through the compilation process without problems (but took some time).

I'd like to have the snapshot functionality, but I've found some very old (2-3 years old) threads around which states that this feature is still not available (2016) at least "not out of the box' by this thread (2014).

Snapshot functionality is available on other platforms.

Also there are some solutions where they switch from SurfaceView to TextureView.

However I prefer sticking to SurfaceView as TextureView brings some performance drawbacks (according to this topic).

Also on an official android page it's stated:

In API 24 and higher, it's recommended to implement SurfaceView instead of TextureView.

In 2014 there were only 2 dependecies of the snapshot function based on the thread I've mentioned earlier:

  • enabling sout module
  • enabling png as encoder

When looking the "VLC-Android" repository of VideoLAN, there is a file responsible for building libVLC.

In line 396, sout module seems to be enabled by default.

Before compilation I've enabled png as encoder in vlc/contrib/src/ffmpeg/rules.mak as pointed out in the forum.

However there is still no function related to snapshot in either org.videolan.libvlc.MediaPlayer or in org.videolan.libvlc.VLCVideoLayout.

The question is how can I create a snapshot (either into file, or into buffer) on Android with libVLC, without using TextureView?

Update1:

Fact1: Found the reason on why it's unavailable on Android. In VLC's core source tree, in file lib/video.c on line 145 there is the snapshot function with a massive FIXME warning:

/* FIXME: This is not atomic. All parameters should be passed at once
 * (obviously _not_ with var_*()). Also, the libvlc object should not be
 * used for the callbacks: that breaks badly if there are concurrent
 * media players in the instance. */
var_Create( p_vout, "snapshot-width", VLC_VAR_INTEGER );
var_SetInteger( p_vout, "snapshot-width", i_width);
var_Create( p_vout, "snapshot-height", VLC_VAR_INTEGER );
var_SetInteger( p_vout, "snapshot-height", i_height );
var_Create( p_vout, "snapshot-path", VLC_VAR_STRING );
var_SetString( p_vout, "snapshot-path", psz_filepath );
var_Create( p_vout, "snapshot-format", VLC_VAR_STRING );
var_SetString( p_vout, "snapshot-format", "png" );
var_TriggerCallback( p_vout, "video-snapshot" );
vlc_object_release( p_vout );  

Fact2: I wanted to go to another direction with this. If snapshot function is not usable (and also not wise to use it), I thought of some emergency solutions:

  1. there is a video-filter in VLC named scene. This produce still images of the video to a specific path. I tried using this, but video-filters are not able to change at runtime. So this attempt failed.

  2. I also tried to do it from the MediaPlayer (via Media.addOption), but video filters are also not possible to change at MediaPlayer level on Android.

  3. I tried then to pass the filter config as an argument to libVLC initialization and finally it succeeded, however that won't be effective to create a new libVLC instance everytime when I need a screenshot.

1
Also, grabbing the bitmap from TextureView is pointless as when the video is HQ, and your screen resolution is smaller, TextureView's getBitmap will scale down your video screenshot to the device's limitations.Daniel
which way did you finally go? I'm facing similar problems, and it seems that VLC has some more problems using TextureView...Mohru
If I remember I took the second approach of mfkl, but it was long time ago.Daniel

1 Answers

1
votes

A few ways to go about this...

Good luck.