Android LibVLC,在没有 TextureView 的情况下拍摄 RTSP 流的快照

Posted

技术标签:

【中文标题】Android LibVLC,在没有 TextureView 的情况下拍摄 RTSP 流的快照【英文标题】:Android LibVLC, take snapshot of RTSP stream without TextureView 【发布时间】:2020-04-22 06:17:55 【问题描述】:

考虑将libVLC 用于android,基于官方recommended way。

我通过compilation process 没有问题(但花了一些时间)。

我想拥有快照功能,但我发现了一些非常古老(2-3 岁)的线程,其中指出此功能是 still not available (2016) 至少“不是开箱即用'this thread (2014)。

快照功能在其他平台上可用。

还有一些solutions 从SurfaceView 切换到TextureView。

但我更喜欢坚持使用 SurfaceView,因为 TextureView 会带来一些性能缺陷(根据 topic)。

在official android page 上也有说明:

在 API 24 及更高版本中,建议实现 SurfaceView 而不是 TextureView。

2014年基于我前面提到的thread的快照功能只有2个依赖:

启用 sout 模块 启用 png 作为编码器

查看VideoLAN的“VLC-Android”存储库时,有一个file负责构建libVLC。

在第 396 行,sout 模块似乎默认启用。

正如论坛中指出的那样,在编译之前,我已经在 vlc/contrib/src/ffmpeg/rules.mak 中启用了 png 作为编码器。

但是在 org.videolan.libvlc.MediaPlayer 或 org.videolan.libvlc.VLCVideoLayout 中仍然没有与快照相关的功能。

问题是如何在不使用 TextureView 的情况下使用 libVLC 在 Android 上创建快照(文件或缓冲区)?

更新1:

事实 1: 找到它在 Android 上不可用的原因。在 VLC 的核心源代码树中,在第 145 行的文件 lib/video.c 中,有带有大量 FIXME 警告的快照功能:

/* 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 );  

事实2: 我想用这个去另一个方向。如果快照功能不可用(而且使用它也不明智),我想到了一些紧急解决方案:

    在 VLC 中有一个名为 scene 的视频过滤器。这会将视频的静止图像生成到特定路径。我尝试使用它,但视频过滤器是not able to change at runtime。所以这次尝试失败了。

    我也尝试从 MediaPlayer(通过 Media.addOption)执行此操作,但也无法在 Android 上的 MediaPlayer 级别更改视频过滤器。

    然后我尝试将过滤器配置作为参数传递给 libVLC 初始化,最后成功了,但是每次我需要屏幕截图时都无法有效地创建新的 libVLC 实例。

【问题讨论】:

另外,从 TextureView 抓取位图是没有意义的,因为当视频是 HQ 并且您的屏幕分辨率较小时,TextureView 的 getBitmap 会将您的视频屏幕截图缩小到设备的限制。 你最后走了哪条路?我面临着类似的问题,而且似乎 VLC 在使用 TextureView 时还有一些问题...... 如果我记得我采用了 mfkl 的第二种方法,但那是很久以前的事了。 【参考方案1】:

解决这个问题的几种方法...

这是一个使用 libvlc https://code.videolan.org/mfkl/libvlcsharp-samples/blob/master/PreviewThumbnailExtractor.Skia/Program.cs 的跨平台缩略图示例它应该可以在 Android 上运行而无需太多编辑,因为它不使用脚本中的任何操作系统特定功能。我猜应该也能把它翻译成 Java/Kotlin。

有一个允许拍摄快照的 libvlc 函数。只要去你想要的时间,打电话给它。 https://www.videolan.org/developers/vlc/doc/doxygen/html/group__libvlc__video.html#ga9b0a3870ce962aa0358050b2d5a59143

在 VLC Android 中,medialibrary 现在管理缩略图。

LibVLC 4 现在捆绑了缩略图https://github.com/videolan/vlc/blob/d40eb012b10cc355ea9ad7a13eaf494b8e826d78/include/vlc/libvlc_media.h#L845

祝你好运。

【讨论】:

以上是关于Android LibVLC,在没有 TextureView 的情况下拍摄 RTSP 流的快照的主要内容,如果未能解决你的问题,请参考以下文章

在 windows 平台上使用 libVLC for Android

使用为 android 编译的 LibVLC 从 MPEG2 流中显示 DVB 字幕

有没有办法在单个对话框/视图中使用 libvlc 同步播放多个文件

C++ LibVLC 从帧/图像创建流

Windows视频桌面壁纸实现(libvlc)

libVLC|make:对“libvlc_new”的未定义引用