artclarke / humble-video

Humble Video: Demuxing, Decoding, Filtering, Encoding and Muxing of 100's of video and audio formats and Codecs from the JVM
GNU Affero General Public License v3.0
557 stars 115 forks source link

JNILibraryLoader could not load library humblevideo. When I running app from JAR. #112

Closed kubisG closed 5 years ago

kubisG commented 7 years ago

Hello,

I'm facing to an following issue.

I'm using your project especialy your demo RecordAndEncodeVideo as part of my application. It works fine when I'm running app from my IDE. It do some stuf and record the screen as I expected.

Unfortunatelly it does not work when I create a JAR of same app ... of course with dependecies and try to run app by JAR.

Following error occurs: 11:49:58.980 [Thread-2] ERROR io.humble.ferry.JNILibraryLoader - Could not load library: humblevideo; version: 0. Exception in thread "Thread-2" java.lang.UnsatisfiedLinkError: no humblevideo in java.library.path at java.lang.ClassLoader.loadLibrary(Unknown Source) at java.lang.Runtime.loadLibrary0(Unknown Source) at java.lang.System.loadLibrary(Unknown Source) at io.humble.ferry.JNILibraryLoader.loadLibrary0(JNILibraryLoader.java:268) at io.humble.ferry.JNILibraryLoader.loadLibrary(JNILibraryLoader.java:171) at io.humble.ferry.JNILibrary.load(JNILibrary.java:152) at io.humble.ferry.FerryJNI.(FerryJNI.java:16) at io.humble.ferry.Ferry.(Ferry.java:24) at io.humble.video.VideoJNI.(VideoJNI.java:19) at io.humble.video.Rational.make(Rational.java:414) at cz.osu.core.recorder.Recorder.run(Recorder.java:166) at java.lang.Thread.run(Unknown Source)

I was going through the JAR and i found libhumblevideo-0.dll on very first folder in the JAR. So library is present in JAR.

In my pom.xml i have following dependecy:

io.humble humble-video-all 0.2.1

Can you please give me some advice to make it runnable from JAR ?
I'm using 64bit windows, 64bit jdk

artclarke commented 5 years ago

Try with 0.3.0, and reopen if still broken.

HovhannesV commented 4 years ago

I have the same issue with version 0.3.0

wneirynck commented 4 years ago

Hi, I've had the same issue and it appears it's not possible to load a native library from inside a jar. So you'll have to extract it and write it to a file on disk. See this Stackoverflow article for details.

McPringle commented 3 years ago

Well, with Xuggler it works, Xuggler loads the library from the JAR file. Both projects use FFmpeg and OS-dependent libraries. Maybe it is just a configuration issue or both frameworks are loading the libraries in a different way?

McPringle commented 3 years ago

To reproduce this problem you can check out GPX Animator. It uses Xuggler by default and I replaced Xuggler with Humble on a branch. Steps to reproduce (GPX Animator needs Java 15):

Clone the repo

git clone https://github.com/zdila/gpx-animator
cd gpx-animator

Test with Xuggler

git checkout master
Run from source
./gradlew run --args="--input ./src/test/resources/gpx/bikeride.gpx --output test.mp4"
Build the JAR file
./gradlew assemble
Run from JAR file
java --enable-preview -jar .\build\libs\gpx-animator-1.7.0-SNAPSHOT-all.jar --input ./src/test/resources/gpx/bikeride.gpx --output test.mp4

Test with Humble

git checkout issue-321-humble
Run from source
./gradlew run --args="--input ./src/test/resources/gpx/bikeride.gpx --output test.mp4"
Build the JAR file
./gradlew assemble
Run from JAR file
java --enable-preview -jar .\build\libs\gpx-animator-1.7.0-SNAPSHOT-all.jar --input ./src/test/resources/gpx/bikeride.gpx --output test.mp4
12:44:13.129 [main] ERROR io.humble.ferry.JNILibraryLoader - Could not load library: humblevideo; version: 0.
Exception in thread "main" java.lang.UnsatisfiedLinkError: no humblevideo in java.library.path: ...

Running with Gradle and from the IDE works, running from the assembled JAR files work with Xuggler and crashes with Humble. In the GPX Animator project, Xuggler and Humble are used in one class: VideoFrameWriter. I would guess that Humble is loading the libraries in a different way than Xuggler. Taking a look at the source of Xuggler library loading might help.

@artclarke: This issue should be reopened. I tested it with the same result on Windows 10 Pro 20H2, macOS Big Sur, and Pop! OS Linux 20.10 (all in 64 bit, newest versions with all patches).

mozeq commented 3 years ago

Did some digging in the code and logs and it turned out the humble code looks for the native lib info in its manifest, so the solution was to add <mergeManifestMode>mergewithoutmain</mergeManifestMode> to the maven-assembly-plugin config. Here's the full working assembly configuration that I'm currently using in my project:

             <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.3.0</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <mergeManifestMode>mergewithoutmain</mergeManifestMode>
                            <archive>
                                <manifest>
                                    <mainClass>
                                        com.example.Main
                                    </mainClass>
                                    <addClasspath>true</addClasspath>
                                    <addExtensions>false</addExtensions>
                                </manifest>
                            </archive>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>