Coder Social home page Coder Social logo

ffmpeg4j's Introduction

ffmpeg4j

FFmpeg4j is a Java library that wraps the functionality of the popular open-source multimedia library FFmpeg (https://www.ffmpeg.org/), whose JNI bindings are excellently exposed through JavaCPP (https://github.com/bytedeco/javacpp). This preserves the cross-platform benefits of the JRE, while still delivering the full features and performance benefits of the FFmpeg library in an OOP fashion.

This library runs FFmpeg native routines within the JRE, via JNI. You do not need a compiled executable (i.e. ffmpeg.exe) to use ffmpeg4j, only a series of static libraries which are part of the package.

Maven

If you want the latest -SNAPSHOT:

<repositories>
	<repository>
	    <id>jitpack.io</id>
	    <url>https://jitpack.io</url>
	</repository>
</repositories>
<dependency>
    <groupId>com.github.manevolent</groupId>
    <artifactId>ffmpeg4j</artifactId>
    <version>-SNAPSHOT</version>
</dependency>

Features

  • A (partly complete) wrapper around the core behaviors of the FFmpeg library: audio, video, and their containing file formats.
  • Full coverage of all formats supported by FFmpeg (there are many!)
  • Tested for stability and optimized for the least wrapper overhead
  • Capable of delivering great apps like music bots, video transcoders, and livestream propogation
  • Sensible structure to fit within a Java development environment; don't deal directly with the C-like constructs exposed by JavaCPP.
  • Use typical InputStream and OutputStream objects to read and write media.
  • Use Channels to read and write media when seeking is needed (i.e. MP4 muxing).
  • Write applications that don't touch the disk (filesystem) for better performance and lower resource cost of in-flight data.

Examples

Read an audio file

InputStream inputStream = new FileInputStream("example.ogg");
FFmpegInput input = new FFmpegInput(inputStream);
FFmpegSourceStream stream = input.open(inputFormat);

// Read the file header, and register substreams in FFmpeg4j
stream.registerStreams();

AudioSourceSubstream audioSourceSubstream = null;
for (MediaSourceSubstream substream : stream.getSubstreams()) {
    if (substream.getMediaType() != MediaType.AUDIO) continue;

    audioSourceSubstream = (AudioSourceSubstream) substream;
}

if (audioSourceSubstream == null) throw new NullPointerException();

AudioFrame frame;

while (true) {
    try {
        frame = audioSourceSubstream.next();
        float[] interleaved_ABABAB_AudioSamples = frame.getSamples();
    } catch (EOFException ex) {
        break;
    }
}

Transcode media

private void transcode(InputStream inputStream,
                       String inputFormatName,
                       SeekableByteChannel outputChannel,
                       String outputFormatName) throws FFmpegException, IOException {
	try (FFmpegSourceStream sourceStream = FFmpegIO.openInputStream(inputStream).open(inputFormatName);
	     FFmpegTargetStream targetStream = FFmpegIO.openChannel(outputChannel).asOutput().open(outputFormatName)) {
	    sourceStream.registerStreams();
	    sourceStream.copyToTargetStream(targetStream);
	    Transcoder.convert(sourceStream, targetStream, Double.MAX_VALUE);
	}
}       

ffmpeg4j's People

Contributors

manevolent avatar syrdek avatar thomaskluiters avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ffmpeg4j's Issues

Error: Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000)

I was trying to run your example for transcoding but got error:

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x103007df0] stream 0, offset 0x30: partial file
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x103007df0] Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none(tv, bt709), 1920x960, 4215 kb/s): unspecified pixel format
Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options
Assertion desc failed at libswscale/swscale_internal.h:725

Process finished with exit code 134 (interrupted by signal 6:SIGABRT)

Am I did something wrong? May be I can add some additional configuration for suggested parameters somehow?

You can find example project with media here: https://github.com/maxixcom/ffmpeg4j-issue

Source code:

public class Main {
    private void transcode(InputStream inputStream,
                           String inputFormatName,
                           SeekableByteChannel outputChannel,
                           String outputFormatName) {
        try (FFmpegSourceStream sourceStream = FFmpegIO.openInputStream(inputStream).open(inputFormatName);
             FFmpegTargetStream targetStream = FFmpegIO.openChannel(outputChannel).asOutput().open(outputFormatName)) {
            sourceStream.registerStreams();
            sourceStream.copyToTargetStream(targetStream);

            Transcoder.convert(sourceStream, targetStream, Double.MAX_VALUE);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void run() throws IOException {
        Set<OpenOption> openOptions = Set.of(
                StandardOpenOption.CREATE,
                StandardOpenOption.WRITE,
                StandardOpenOption.TRUNCATE_EXISTING
        );
        try (
                FileInputStream inputStream = new FileInputStream("tmp/sample-0.mp4");
                SeekableByteChannel seekableByteChannel = Files.newByteChannel(Paths.get("tmp/output.ts"), openOptions);
        ) {
            transcode(inputStream,"mp4", seekableByteChannel, "mpegts");
        }
    }

    public static void main(String[] args) throws IOException {
        new Main().run();
    }
}

Turn off FFmpeg internal logging

Is there a way to turn off ffmpeg internal logging? It always prints for example a lot just by calling FFmpegSourceStream stream = input.open("mp4");

Is there a way to turn ffmpeg completely silent (maybe with the exception of severe errors)

Reaching the end of audio substream makes video substream end

I am unsure if this is just a bug in my code, but I am opening a VideoSourceSubstream and AudioSourceSubstream and reading from them to store in a buffer.
The video file I am testing with has less audio "packets" than video and when the AudioSourceSubstream reaches the end, the VideoSourceSubstream stops producing next frames.

Am I misunderstanding how these SourceSubstreams work?

My (in-progress) code is here: https://gist.github.com/ExpensiveKoala/561347881d37827e7a9ac06920603ef1

Does live streaming support for streaming?

I am responsible for developing a function to push local files to the streaming server. Encounter various problems using JavaCV. Can I complete my work using this project? Where can I see the project documentation and user manual

Comparison with ffmpeg-cli-wrapper

I'm looking for a library that provides Java bindings for FFmpeg. During my research I stumbled upon both ffmpeg-cli-wrapper and this repo here, ffmpeg4j. From a quick glance it looks like both projects share the same goals, however ffmpeg-cli-wrapper seems to be the older and more established option compared to ffmpeg4j. Which leaves me with two questions:

  1. Are there any major differences between the two libraries?
  2. If no, why was ffmpeg4j created?

Would be nice if this could be mentioned in the README as well.

FFmpegIO automatic format parsing

With FFmpegIO input/output streams, you currently have to specify the format manually, however in my use-case it's not always possible to pre-determine the format with either the file name or user input - the only option is to open the file and attempt to read. Would be great if FFmpegIO could automatically determine the file format (with FFProbe, for example).

Fix README method signatures

In the current version of the README (that appears to not have been edited in 5 years) there seems to be an error in the first example, where the FFmpegInput constructor is shown to take an InputStream as its only parameter opposed to a single instance of FFmpegIO as shown in the latter example.

This can easily lead people who only read the basic example to confusion, especially when paired with the (as far as I know) complete lack of any documentation for the java implementation.

Assertion desc failed at libswscale/swscale_internal.h:670

I tinkered a little bit with your nice ffmpeg4j and used some home videos as source. With ~10% of the videos I had problems.

  1. Assertion desc failed at libswscale/swscale_internal.h:670

The error happens when I call FFmpegSourceStream.registerStreams()

More precisely in FFMpegInput.registerStream(FFmpegSourceStream sourceStream, int stream_index) at this line:

FFmpegError.checkError("avcodec_open2", avcodec.avcodec_open2(ctx, codec, (avutil.AVDictionary) null));

  1. Exception in thread "main" com.github.manevolent.ffmpeg4j.FFmpegException: unsupported codec type: 3
    at com.github.manevolent.ffmpeg4j.stream.source.FFmpegSourceStream.registerSubstream(FFmpegSourceStream.java:212)
    at com.github.manevolent.ffmpeg4j.FFmpegInput.registerStream(FFmpegInput.java:136)
    at com.github.manevolent.ffmpeg4j.stream.source.FFmpegSourceStream.registerStreams(FFmpegSourceStream.java:80)
    at incubator.FFmpeg4jExperiments.openVideo(FFmpeg4jExperiments.java:44)
    at tool.FFmpeg4jTree.main(FFmpeg4jTree.java:65)

Great project - maybe add use case snippets..?

Hello,

love the idea of ffmpeg4j. I was tinkering a little bit but I think I will miss most of the potential. Could you upload code snippets, classes or even small working projects that use ffmpeg4j, so one could learn by looking at the code?

Thanks!

Please update to current version of FFMpeg

Also, is there a way to get a certain frame without decoding all the frames until that frame? For example if I want to get a VideoFrame 5min. into the video I have to use a loop and .next() many many times until that on frame that I want. This takes forever. I tried to achieve this with the API without any success. Methods like setPosition using Reflection but it has no effect when I subsequentially call next()

Does not start in Linux (Debian) environment.

Hello,
as soon as I try to execute the code in Debian the following message appears and nothing happens after that. On Windows there are no problems. No matter which format: mp3, mp4 etc...

[mp3 @ 0x7f42207360c0] invalid concatenated file detected - using bitrate for duration
Input #0, mp3, from '':
  Metadata:
    genre           : Cinematic
    album           : YouTube Audio Library
    title           : Impact Moderato
    artist          : Kevin MacLeod
  Duration: N/A, start: 0.034531, bitrate: 224 kb/s
    Stream #0:0: Audio: mp3, 32000 Hz, stereo, s16p, 224 kb/s
    Metadata:
      encoder         : LAME3.99r

I am trying to play the following MP3: https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3
I have followed this code: https://github.com/Manevolent/ts3j/blob/master/examples/audio/src/main/java/com/github/manevolent/ts3j/examples/audio/MusicPlayer.java

I also installed ffmpeg on my server.
Whether installed or not makes no difference.

Merge MP4 video file with AAC audio file

There are no code snippets for something like this, is it possible with this library to merge an mp4 file with an aac file with same "time" length? If yes how can I do that?

Transcode usage question (MP4)

Hello,

I'm trying to read a video file, convert it into another format and keep the output as the OutputStream.

I've tried to follow README, and the read of the input file part works great.

However, I'm trying to use Transcoder and I could not figure out the right way to specify the TargetStream.

val targetStream = new FFmpegTargetStream(
  outputFormatName,
  output,
  new FFmpegTargetStream.FFmpegNativeOutput()
)

targetStream.getSubstreams().size() // is always 0

Transcoder.convert(sourceStream, targetStream, 2d)

And it causes Transcoder failure:

Output #0, mp4, to '(null)':
[mp4 @ 0x7f859a06fa00] No streams to mux were specified
[info] - convert avi to ffmpeg *** FAILED ***
[info]   java.lang.RuntimeException: com.github.manevolent.ffmpeg4j.FFmpegException: @pool-1-thread-1-ScalaTest-running-FfmpegSpec: ffmpeg/avformat_write_header: Invalid argument (code=-22)
[info]   at com.github.manevolent.ffmpeg4j.stream.output.FFmpegTargetStream.writeHeader(FFmpegTargetStream.java:117)
[info]   at com.github.manevolent.ffmpeg4j.transcoder.Transcoder.transcode(Transcoder.java:49)

I've tried to set manually output sub streams:

targetStream.registerVideoSubstream(
  avcodec.avcodec_find_encoder_by_name("libopenh264"),
  defaultVideoSubstream.getFormat.getWidth,
  defaultVideoSubstream.getFormat.getHeight,
  defaultVideoSubstream.getFormat.getFramesPerSecond,
  new util.HashMap[String, String]()
)

But it leads to another issue:

Input #0, avi, from '':
  Metadata:
    encoder         : Lavf55.0.0
  Duration: 00:02:27.64, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: wmv2 (WMV2 / 0x32564D57), yuv420p, 640x480, 25 fps, 25 tbr, 25 tbn, 25 tbc
null
640x480 @25.0FPS 0Kbps
---------
---------
[libx264 @ 0x7fd2444f1e00] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x7fd2444f1e00] profile High 4:4:4 Predictive, level 3.0, 4:4:4 8-bit
[libx264 @ 0x7fd2444f1e00] 264 - core 155 - H.264/MPEG-4 AVC codec - Copyleft 2003-2018 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x1:0x111 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=4 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to '(null)':
    Stream #0:0: Unknown: none (libx264)
[mp4 @ 0x7fd2444f1800] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
[mp4 @ 0x7fd2444f1800] muxer does not support non seekable output
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000122e29f74, pid=84800, tid=0x0000000000004403
#
# JRE version: Java(TM) SE Runtime Environment (8.0_162-b12) (build 1.8.0_162-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.162-b12 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  [libavformat.58.dylib+0xa7f74]  avformat_get_mov_audio_tags+0x33dc4
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/daunnc/subversions/git/github/alimentiv-video-annotation/application/hs_err_pid84800.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

Could you guide me into a proper direction? I guess I'm just using the API wrong.

  • MacOS Catalina 10.15.6
  • ffmpeg version 4.3.1
  • ffmpeg cli works as expected
  • ffmpeg4j 4.1-1.4.4-2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.