bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.59k stars 1.59k forks source link

[Help] How can I make hls stream from webcam video (or other video stream). #1745

Closed Grednoud closed 2 years ago

Grednoud commented 2 years ago

I'm trying to make an HLS stream from an input video stream from a webcam. I expect the recorder to create an index.m3u8 file and .ts chunks as frames are saved. But the files are created only after the recorder is closed. Why is this happening? Can you suggest the best way to do this?

Sample scala code to reproduce:

import org.bytedeco.javacv._

object Test extends App {
  val grabber = FrameGrabber.createDefault(0)
  grabber.start()
  val recorder = FFmpegFrameRecorder.createDefault("index.m3u8", grabber.getImageWidth(), grabber.getImageHeight())
  recorder.setFormat("hls")
  recorder.setOption("hls_list_size", "4")
  recorder.setOption("hls_time", "5")
  recorder.start()

  for (_ <- 1 to 500) {
    recorder.record(grabber.grab())
  }

  grabber.close()
  recorder.close()

}

Thank you for your advice.

saudet commented 2 years ago

I guess that format doesn't support streaming. If you need good streaming support, try another format like matroska (mkv).

Grednoud commented 2 years ago

I guess that format doesn't support streaming. If you need good streaming support, try another format like matroska (mkv).

HLS - HTTP Live Striming, it's good for streaming. When I use ffmpeg directly, the conversion happens quite correctly.

.\ffmpeg.exe -y -f vfwcap -r 25 -i 0 -f hls -hls_time 5 -segment_time 5 -hls_list_size 5 index.m3u8

saudet commented 2 years ago

Ok, so you could use the ffmpeg program if it does everything you need. It's quite easy to use it from Java: http://bytedeco.org/javacpp-presets/ffmpeg/apidocs/org/bytedeco/ffmpeg/ffmpeg.html

Grednoud commented 2 years ago

Ok, so you could use the ffmpeg program if it does everything you need. It's quite easy to use it from Java: http://bytedeco.org/javacpp-presets/ffmpeg/apidocs/org/bytedeco/ffmpeg/ffmpeg.html

Thanks for the advice. I try like in the example:

val ffmpeg = Loader.load(classOf[org.bytedeco.ffmpeg.ffmpeg])
val pb = new ProcessBuilder(ffmpeg, "-y", "-f", "vfwcap", "-r", "25", "-i", "0", "-f", "hls", "-hls_time", "10", "-hls_delete_threshold", "3", "./index.m3u8")
pb.inheritIO().start().waitFor()

In this case, I get nothing in the output, only increasing the memory consumption. My guess is that something is being buffered, but no output files are being created.

Grednoud commented 2 years ago

Is there a difference between calling ffmpeg in the console and through the ProcessBuilder? In the first case, I get a continuous stream of conversion, in the second I see only a growing amount of buffered data. Is it possible to somehow reduce the buffer or force the data to be saved via flush()?

saudet commented 2 years ago

There is no difference. Maybe the bundled version is missing a feature or something. If you know which one it is, we can enable it.

Grednoud commented 2 years ago

The problem seems to be the different behavior of ffmpeg 4.4 which comes with javacv and ffmpeg 5 installed in my path.

saudet commented 2 years ago

FFmpeg 5.0 is available in the snapshots: http://bytedeco.org/builds/

Grednoud commented 2 years ago

FFmpeg 5.0 is available in the snapshots: http://bytedeco.org/builds/

Thanks for the help. But why does ffmpeg 5 shipped with javacv, like 4.4, only buffer but not create files in case of hls? Unlike the official release of ffmpeg. Official release image ffmpeg 5 shipped with javacv image

saudet commented 2 years ago

You're using libx264. If you want to use libx264 with JavaCV as well, you need to add a dependency on ffmpeg-platform-gpl as shown in the README.md file: https://github.com/bytedeco/javacv/#sample-usage

Grednoud commented 2 years ago

Many thanks. This solved the problem.

You're using libx264. If you want to use libx264 with JavaCV as well, you need to add a dependency on ffmpeg-platform-gpl as shown in the README.md file: https://github.com/bytedeco/javacv/#sample-usage