FFmpeg pipe input for concat

I am trying to make a real time video recorder with ffmpeg (not screen recorder, unity player recorder of Specific dimensions)

I am able to get the ARGB data, and so far I have been writing it to a bunch of bmps and then running ffmpegs concat command like

ffmpeg -i files.txt -i pictures/pic%06d.bmp output.mp4

With different codecs etc, and my files.txt is essentially (pseudo)

ffconcat version 1.0 file pic000000.bmp duration 0.016 #etc, basically the durations were generated from time stamps

Anyways that all works believe it or not, but writing the files to disk as bmp (or even encoding them as a compressed format then writing that to disk) takes up a lot of extra time and I would prefer to pipe the data directly to ffmpeg

I know in some cases you can input a file by using the - operator then in whatever programming language the prices was started from pass on the byte data though stdin I am pretty sure, although the problem:

I have only been able to find out how to do this with a set framerate, but not with the concat, and I (think?) I need to use concat here because it's very important that the images have an exact time stamp on the body to line up with audio, as there will be a slight delay when capturing the frames, and so far I have been calculatabling each frames duration based on their timestamps (and the last one has no duration), in order to line them up perfectly with the audio, but as far as I can find the concat feature seems to require the files to already be written to the disk and then specified in a text file..

So is there any way to get a custom frame rate for each frame without writing the frames to disk first, and just piping them in? Does concat in any way support -? Is there another way I can line up the frames with audio? Do other video recording softwares face similar issues?

Upvotes: 5

Views: 1989

Answers (1)

llogan
llogan

Reputation: 133883

Pipe

I don't have access to your image/video/data generator, so I can't tell what it is doing, but you can at least try a pipe:

your_data_process - | ffmpeg -f rawvideo -framerate 25 -pixel_format argb -video_size 640x480 -i - output.mp4
  • your_data_process in this example is just a placeholder example for whatever is generating the video.
  • -f should be whatever format your_data_process is outputting. See ffmpeg -demuxers for a long list. This example assumes raw video.
  • A frame rate must be set but it does not necessarily mean it will mess up your timing.
  • If your player does like the output then add the -vf format=yuv420p output option.

Image

Another approach is to output to a single image file and atomically overwrite the file for each change. ffmpeg will then use the file as an input and will notice when it gets updated.

ffmpeg -f image2 -loop 1 -framerate 25 -i input.bmp output.mp4
  • Usually you don't have to manually set -f image2 for most image inputs. You have to in this case or it won't notice the image update. This is because it will select a simpler demuxer for some image formats.

  • In this example ffmpeg will duplicate frames to fill 25 fps until the next image update so the timing should be preserved.

  • If your player does like the output then add the -vf format=yuv420p output option.

Upvotes: 1

Related Questions