Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ffmpeg stuck when using Channels to extract image close to the end of a video #233

Closed
shoeoffhead opened this issue Oct 11, 2021 · 16 comments · Fixed by #244
Closed

ffmpeg stuck when using Channels to extract image close to the end of a video #233

shoeoffhead opened this issue Oct 11, 2021 · 16 comments · Fixed by #244

Comments

@shoeoffhead
Copy link

This problem is when using Channels.

I used this video file as input: https://file-examples-com.github.io/uploads/2020/03/file_example_WEBM_480_900KB.webm

The video has a length of 30540 milliseconds.

If I extract an image at 30.000 milliseconds on the console it works: /mnt/Data/software/ffmpeg-4.4-amd64-static/ffmpeg -loglevel level+info -ss 30.000 -i /mnt/Data/downloads/webm/file_example_WEBM_480_900KB.webm -y -frames:v 1 -q:v 1 -f image2 /mnt/Data/downloads/data.jpeg

When I try to repeat this in Jaffree, ffmpeg gets stuck and is never interrupted (see log below). I guess Channels are not the harddisk so there are small differences. No problem. Writing out at position 29500 works. However it is somewhat of a problem, that ffmpeg gets stuck and doesn't throw an Exception. On the console ffmpeg never "freezes" even if you get close or over the video length. It just returns with an error: [warning] Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)

try (SeekableByteChannel inputChannel = Files.newByteChannel(pathToSrc, StandardOpenOption.READ); SeekableByteChannel outputChannel = Files.newByteChannel(pathToDst, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.TRUNCATE_EXISTING) ) { FFmpeg.atPath() .addInput(ChannelInput.fromChannel(inputChannel).setPosition(30000)) .setOverwriteOutput(true) .addArguments("-frames:v", "1") .addArguments("-q:v", "1") .addOutput(ChannelOutput.toChannel(filename, outputChannel).setFormat("image2")) .execute(); }

[main] WARN com.github.kokorin.jaffree.ffmpeg.PipeOutput - It's recommended to use ChannelOutput since ffmpeg requires seekable output for many formats
[main] WARN com.github.kokorin.jaffree.ffmpeg.FFmpeg - ProgressListener isn't set, progress won't be reported
[main] INFO com.github.kokorin.jaffree.process.ProcessHandler - Command constructed:
ffmpeg -loglevel level+info -ss 30.000 -i ftp://127.0.0.1:38773/ -n -frames:v 1 -q:v 1 -f image2 tcp://127.0.0.1:44917
[main] INFO com.github.kokorin.jaffree.process.ProcessHandler - Starting process: ffmpeg
[main] INFO com.github.kokorin.jaffree.process.ProcessHandler - Waiting for process to finish
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] ffmpeg version N-59310-gd115eec979-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2021 the FFmpeg developers
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] built with gcc 8 (Debian 8.3.0-6)
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] libavutil 57. 7.100 / 57. 7.100
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] libavcodec 59. 11.100 / 59. 11.100
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] libavformat 59. 6.100 / 59. 6.100
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] libavdevice 59. 0.101 / 59. 0.101
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] libavfilter 8. 12.100 / 8. 12.100
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] libswscale 6. 1.100 / 6. 1.100
[StdErr] INFO com.github.kokorin.jaffree.ffmpeg.FFmpegResultReader - [info] libswresample 4. 0.100 / 4. 0.100

@kokorin
Copy link
Owner

kokorin commented Oct 11, 2021

Check the log: it says:

PipeOutput - It's recommended to use ChannelOutput since ffmpeg requires seekable output for many formats

In the code snippet there is no PipeOutput. Probably the log is for another snippet.

Also by the following line:

ffmpeg -loglevel level+info -ss 30.000 -i ftp://127.0.0.1:38773/ -n -frames:v 1 -q:v 1 -f image2 tcp://127.0.0.1:44917

I can say that you use ChannelInput and PipeOutput (ftp vs tcp).

Please double check the code in question. If that doesn't help, please, provide minimal project (zip, only source files) which reproduces the issue.

@shoeoffhead
Copy link
Author

shoeoffhead commented Oct 11, 2021

Sorry, I tested with ChannelOutput, OutputStream and output to File. I accidently pasted the wrong Log for OutputStream. But the problem appear with all 3 output types.

You can reproduce it. Input file: https://file-examples-com.github.io/uploads/2020/03/file_example_WEBM_480_900KB.webm

Code using only Channels. For position 30000 ffmpeg freezes. Position 29500 works fine.

    try (SeekableByteChannel inputChannel = Files.newByteChannel(pathToSrc, StandardOpenOption.READ);
         SeekableByteChannel outputChannel = Files.newByteChannel(pathToDst, StandardOpenOption.CREATE,
                         StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.TRUNCATE_EXISTING)
    ) {
        FFmpeg.atPath()
                .addInput(ChannelInput.fromChannel(inputChannel).setPosition(30000))
                .setOverwriteOutput(true)
				.addArguments("-frames:v", "1")
        		.addArguments("-q:v", "1")
                .addOutput(ChannelOutput.toChannel(filename, outputChannel).setFormat("image2"))
                .execute();
    }

@kokorin
Copy link
Owner

kokorin commented Oct 11, 2021

Please provide full code sample to reproduce the issue if you do need help.

Notice that Earth stops spinning in provided video exactly at 30th second and hangs for the rest of video.

kokorin added a commit that referenced this issue Oct 12, 2021
@shoeoffhead
Copy link
Author

Below is the full example. The problem is, ffmpeg gets stuck forever where it should throw an Exception and return control to the calling thread. This should not happen even if you enter a position value that is bigger then the duration of the video.

example.zip

@kokorin
Copy link
Owner

kokorin commented Oct 13, 2021

Thank you, check #235 PR, I found that FTP implementation sometimes doesn't respond with a code expected by ffmpeg.

I'm not sure yet why it fails not every time.

Thank you for the issue!

kokorin added a commit that referenced this issue Oct 16, 2021
@kokorin
Copy link
Owner

kokorin commented Oct 16, 2021

The fix is in develop branch. You could build and use it. I will release ASAP.

@shoeoffhead
Copy link
Author

Thanks. I am not in a rush since I don't need the functionality at the moment. I was just thoroughly testing your project and submitted a few issues. Great project btw. :)

@shoeoffhead
Copy link
Author

Is the release name '0' normal?

https://github.com/kokorin/Jaffree/releases

@kokorin
Copy link
Owner

kokorin commented Oct 19, 2021 via email

@shoeoffhead
Copy link
Author

shoeoffhead commented Nov 3, 2021

I don't know if I should open a different Issue since the problem is Channel based.

Here is a link to a working example (including video input) showing the problem: https://drive.google.com/file/d/1HLxhxyA7DDiegQUjrVUVD-s1bQgDhukj/view?usp=sharing

Writing images with Channels doesn't work for certain container formats. MKV works but TS and TP does not. Writing images without channels works perfectly for TS and TP.

You have to edit the filename from input.mkv to input.ts in the .java file to see the problem with Channels.

@kokorin kokorin reopened this Nov 4, 2021
@kokorin
Copy link
Owner

kokorin commented Nov 4, 2021

@shoeoffhead I have no access to the file you shared. Please upload it here.

@shoeoffhead
Copy link
Author

The file is too big to upload. But I fixed the download problem.

This should work: https://drive.google.com/file/d/1HLxhxyA7DDiegQUjrVUVD-s1bQgDhukj/view?usp=sharing

@kokorin
Copy link
Owner

kokorin commented Nov 6, 2021

@shoeoffhead It looks like problem is related to ChannelInput and TS file. FFmpeg can't seek TS (no syncpoints?), and has to read input file from the beginning looking for required start position.
Check #244 for details. Expect to merge it soon.

@kokorin kokorin linked a pull request Nov 6, 2021 that will close this issue
@kokorin
Copy link
Owner

kokorin commented Nov 8, 2021

Fixed, check latest release

@kokorin kokorin closed this as completed Nov 8, 2021
@shoeoffhead
Copy link
Author

Works :)

@kokorin
Copy link
Owner

kokorin commented Nov 12, 2021

@shoeoffhead it's very interesting to me how do you use Jaffree? Especially how do you use ChannelInput/Output?
Could you share such information?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants