UPD3。我认为这个问题将被关闭,我将不得不放弃设想的想法,因为据我了解,android 不存在可行的解决方案。我尝试了另一个javacv抓取器FFMPEGFrameGrabber,但它也没有设置我想要的框架。作为最后一次尝试,我将尝试直接在 github opencv 上提出另一个问题。我现在想知道的是 - 有没有其他方法可以只暴露所需的框架?
我正在创建一个android应用程序,它opencv通过VideoCapture. 我在几天内分析了大量网站以寻找我的问题,为什么和Videoio.CAP_PROP_FPS其他Videoio.CV_CAP_PROP_FRAME_COUNT常量总是返回0.0. android有人说它只opencv-android返回 2 个值(指向问题的链接,其中指明了源代码),其他人据称根本不打开视频。
如果我理解正确,那么实际上它VideoCapture通过 提取视频文件的元数据ffmpeg,但android由于短缺,它只是不想处理它,因为我认为这个文件(ffmpeg.so)。是的,我知道opencv-android不官方支持ffmpeg,但是网上有很多关于这个话题的答案,从他们那里我只找到了一篇或多或少有用的文章,如何连接opencv + ffmpeg(它已经过时了,所以不好)。
根据经验,我发现在计算机上连接 dll 库时:
System.loadLibrary("opencv_ffmpeg310_64.dll");
可以访问珍贵的常量CAP_PROP_FPS和CV_CAP_PROP_FRAME_COUNT方法capture.set();,这在我的项目中现在是非常必要的......如果你不包含这个库,那么它将总是返回 0.0。
我决定通过下载库来测试这个想法到极致com.github.wseemann:FFmpegMediaMetadataRetriever-core——事实上,它从视频中提取元数据,就像opencv在连接了 dll 的计算机上的程序一样。
决定尝试ffmpeg.so从源代码构建我们自己的 android 库ffmpeg。不幸的是,我至少在架构下构建失败,因为编译器在没有找到arm64-v8a的类型上给出了一堆错误。#include stdlib.h我一开始纠正了平庸的错误,但后来出现了更复杂的错误——我没有特别在c/中翻找。c++
谁遇到过类似的问题?它是如何解决的?也许JavaCV提供类似于get()方法set()的东西VideoCapture?set如果仍然可以通过其他库以某种方式解决对常量的访问,那么到目前为止我还没有以其他方式访问该方法,我无法为官方解决opencv。
尽管 20-22 岁,是否有关于ffmpeg为android 组装的真正明智的教程?!opencv我的想法是否与文件有关ffmpeg.so?互联网上真的没有人可以将收集到的*.so文件发布为 android 用于建筑arm64-v8a和其他吗?你不能抛出链接Stack Overflow——我几乎修改了这个主题的所有内容。
测试:
Android: 12
MinSDK: 26
OC: Windows 10/Linux Ubuntu
OpenCV: 4.5.5
FFmpeg: 4.4
Ndk: 21.4.7075529 (использовал эту версию, так как обычно туториалы использовали некоторые файлы, которые в новой версии были удалены)
UPD。
因此,我设法获取*.so了不同架构的文件,包括arm64-v8a. 我尝试按类型连接:
System.loadLibrary("ffmpeg"); // libffmpeg.so для arm64-v8a
但它仍然不能解决我的问题。也许您需要CMakeLists.txt在来自 opencv-android sdk 的文件中指定类似的内容:
add_library(ffmpeg SHARED path-to-lib/libffmpeg.so)
set_target_properties(ffmpeg PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(ffmpeg)
正确的?为了结合 opencv 和ffmpeg?如果没有,如何将这些*.so文件的支持添加到 opencv 本身?
UPD2。
有趣的一件事是,在其中一个函数的控制台中显示了一条日志opencv,其中明确输入了未来常量的值CAP_PROP_FPS(即视频 fps):
但是服务器 API 似乎不想返回这个值,不清楚为什么会发生这种情况(可能是由于我在 1 pro link 中附加的问题source-code)。
据我了解,根据有关该方法的文档get(块return和note表示返回 0.0),opencv-android 代码没有显式实现,并且编写了这些常量的逻辑。即使是这样,那方法set()呢?有没有可能的解决方案?


感谢所有帮助过的人……咳咳,也就是感谢我自己!这里和官方论坛都没有答案
opencv,这让我很开心。但是 10 天后,我自己找到了解决方案,没有任何帮助。我无法从官方的 opencv 获得正确的工作,但不清楚我开始安装所需框架FFMPEGFrameGrabber的包中的奇迹是什么。javacv起初,我在使用带有扩展名的视频时没有任何反应*.avi,但是当我选择格式*.mp4时,奇迹发生了,然后是带有扩展名的视频的帧*.avi。至于常量,这个抓取器还允许您从视频中获取元数据,例如,getFrameRate(...)还有setFrameRate(...)其他方法。我确定我opencv-android可以公开所需的框架,例如FFMPEGFrameGrabber,但是,可能开发人员只是懒得添加对版本的这种支持4.5.5,至少他们可以窥探它是如何完成的javacv。综上所述,结论是:目前是正式版
opencv-android,目前是这个版本4.5.5,如果你只需要从视频中获取它的分辨率(高度和宽度),那么你不需要安装任何其他东西 - 使用官方之一opencv。如果需要从视频中提取元数据,设置当前帧,那么可以有2个选项:1)来自opencv的独立库,在你的项目中占用很少的空间:
MediaMetadataRetriever/FFmpegMediaMetadataRetriever(我建议第二个)。第一个是内置库,第二个支持一些好东西,与内置库不同。例如,第一个(内置)也没有从我这里提取任何数据,第二个设法从视频中提取元数据。这些包装器还允许您通过设置时间来获得所需的帧,但生成的帧Bitmap质量不是很好,并且对于每个视频,您必须编写自己的循环来计算每帧之间的时间,这不是方便的。2)如果您需要更合乎逻辑和统一的解决方案,那么看看旁边
javacv,有不同的抓取器用于对图像进行排序和其他有用的功能,这将使您免于创建自行车。但是有一点——类层次结构与官方opencv略有不同,所以如果之前用官方opencv编写的代码,你将不得不尝试重写你的代码,并且数据类型会有所不同(例如,javacv有自己的矩阵Mat)。优点之一是您可以通过简单地编写依赖项来从存储库中安装官方opencvvia 。但总的来说,我并没有搬到这个包,因为官方的opencv对我来说似乎更方便,我不想重写代码。Gradlejavacv总的来说,到目前为止我一直拒绝设置想要的框架(如果官方的opencv不添加功能,也许以后我还会考虑这个想法),但是对于项目我
FFmpegMediaMetadataRetriever是和官方一起使用的opencv。