java - 使用带有 JNA 和 gst1-java-core 的 Gstreamer for Android?
问题描述
在开始之前,请允许我说,我知道可以使用 C 代码将 Gstreamer 本地集成到 Android 中,就像Android 教程本身中所做的那样。
这个问题与简单地让 Gstreamer 在 Android 上运行无关,而是在 Android 上使用预先存在的本机 Java 包装器库gst1-java-core和Android Studio 中的JNA在新的 Native 项目中运行它。但是,如果本机 C 代码是唯一的方法,请告诉我您是否尝试过并且失败了我正在尝试做的事情。
让我们开始。
系统信息:
- 操作系统:Linux Ubuntu 18.04
- 安卓工作室版本:4.1.2
- Java版本:8
- SDK 版本:30(针对 API 21)
- NDK版本:21(也试过23)
- 测试设备:Samsung Galaxy Tab S6 Lite(虽然还没到)
过程涉及在 Android Studio 中设置一个全新的项目,并选择 Native C++ 作为项目模板,然后将其他所有内容保持默认,包括工具链。一旦项目建成并完成它的 Gradle 业务,我就执行了通常的git init并在 Git 中进行设置。之后,我从发布页面下载 gst1-java-core-1.4.0.jar 并将其添加到直接位于“ app/ ”文件夹内的“ libs/ ”中。
完成后,我修改了 app 目录中的 build.gradle 文件以匹配这个Gradle Gist。
这之后自然是 Gradle 同步,当它正确完成后,我转到我的MainActivity.java并添加了两行代码。首先在顶部:
import org.freedesktop.gstreamer.Gst;
然后在onCreate方法中:
Gst.init();
然后产生了这个错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.rcbappnative, PID: 9644
java.lang.UnsatisfiedLinkError: Could not load library: gstreamer
at org.freedesktop.gstreamer.lowlevel.GstNative.load(GstNative.java:56)
at org.freedesktop.gstreamer.lowlevel.GstNative.load(GstNative.java:46)
at org.freedesktop.gstreamer.lowlevel.GstAPI.<clinit>(GstAPI.java:37)
at org.freedesktop.gstreamer.Gst.getVersion(Gst.java:144)
at org.freedesktop.gstreamer.Gst.init(Gst.java:473)
at org.freedesktop.gstreamer.Gst.init(Gst.java:419)
at com.example.rcbappnative.MainActivity.onCreate(MainActivity.java:25)
at android.app.Activity.performCreate(Activity.java:7963)
at android.app.Activity.performCreate(Activity.java:7952)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3629)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3806)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2267)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
然后,我继续尝试通过遵循Android的 Gstreamers 安装说明来纠正此问题,方法是下载与我的 NDK 版本(gstreamer-1.0-android-universal-1.18.3.tar.xz)匹配的二进制文件,然后将它们解压缩到一个文件夹中然后由环境变量指向
GSTREAMER_ROOT_ANDROID=/home/user/Android/gstreamer
我将此环境变量添加到~/.project以及~/.bashrc并获取其中任何一个并尝试构建和运行,但没有任何改变。
然后我尝试将它同时添加到local.properties和gradle.properties ( 也一次添加一个),但仍然会发生相同的错误。
gstreamer-java 的 github 提供的Java 示例在我的机器上工作得很好,所以看起来它不是系统范围的错误,而是 Android 环境特定的错误,它以某种方式无法加载库。也许是因为它不知道寻找那个环境变量。
所以现在的问题是;有没有人通过 JNA 让 gst1-java-core 与 Android 一起工作,或者任何人都可以指出我在导入这个库方面可能做错了什么的正确方向?任何帮助将不胜感激。
解决方案
因此,我对 Android 和子系统的了解不足是我的错误,即使 Android 主要是用 Java 开发的,它也不支持“本地”运行 Java。这意味着 JNI 不相关,因为根据 Wikipedia JNI 是:
在软件设计中,Java Native Interface是一种外来函数接口编程框架,使运行在Java虚拟机中的Java代码能够调用和被其他语言如C、C++和汇编语言编写的本机应用程序和库调用。
所以这么说 - 因为Android不运行JVM,而是在Linux内核上运行Native C,这意味着尝试通过JNI集成“java包装器”目前在Android上是不可能的。
因此,通用解决方案和遵循Gstreamers 官方教程似乎是目前在 Android 中使用 Gstreamer 的唯一方法。
我只能怪我自己认为其他人只是“错过”了 JNI 和 gst1-java-core,而且我什至比Gstreamer 官方网站本身更了解。
不过,我想回答这个问题,因为如果其他人走错了路,我现在可以正式建议遵循官方教程并创建一个具有Native支持的 Android 应用程序,以便您可以直接从 Gstreamer 编译和集成 C 代码,然后制作你的应用程序就是这样工作的。
我目前可以说,按照上述段落的建议,我创建了一个有效的 Android 应用程序,其中 Gstreamer 实时流当前启动并使用自定义管道运行。我不会说这很容易。因为不是;特别是如果您不擅长 C 编程。但这绝对是可行的,而且教程很好。
推荐阅读
- memory - 为什么在 Mariabackup 期间出现 mysqld 错误
- java - java how to skip into file until hex string?
- html - Material Design Lite - Tool Tip positioning
- python - How to fix Psycopg2 Error Pip Installation in Mac Terminal?
- sql - R查询动态的地方与闪亮的输入
- python - Python code non-stop when processing text documents
- amazon-web-services - Is there a way to restart (Stop and Start) AWS ElasticSearch?
- javascript - How to print with SmartWebView
- animation - Change the direction of animation on Flutter
- angular - 使用 Angular 8 使用 Formbuilder Typescript 在视图中切换 FormControl