run ffmpeg in a loop on pngs for efficiency? - arrays

I am using ffmpeg to embed production data as text overlay into separate frames of animation saved as png files.
At the moment its very inefficient as I need to sample values from the animation scene such as current frame and camera focal length, and so I have a loop that samples the information each frame, runs ffmpeg to embed the text for that frame, then closes ffmpeg and repeats until complete.
If I have two given string list arrays (such as frame number and focal length), is there a way to ask ffmpeg to run a single instance but for each png from its given list it also references the next item from the array to print the text and therefore operate only once the entire set of frames?

Use the concat demuxer.
Make input.txt:
file '01.png'
file_packet_metadata length=50mm
duration 0.04
file '02.png'
file_packet_metadata length=35mm
duration 0.04
file '03.png'
file_packet_metadata length=18mm
duration 0.04
Encode, using the drawtext filter to add text:
ffmpeg -f concat -i input.txt -vf "drawtext=text='%{metadata\:length}':fontsize=22:fontcolor=white:x=w-tw-10:y=h-th-10,format=yuv420p" output.mp4
For positioning see How to position drawtext text.

Related

Merge two videos with different HTTP Range header bytes

I want to save 10 seconds from any part of a video by using its URL (without downloading it completely).
the server supports the Range header and it's possible to get specific byte ranges, the video is ok when I save it with something like Range: bytes=0-102400 but when I change the start byte and save a video with Range: bytes=307200-614400 it's no longer playable.
I know maybe it lacks a MIME/header type that should be at the beginning of a file, but the first bytes are not in this response to specify the correct format of the file.
so I saved the video from 0-102400, which is ok and playable, and wanted to get that specific range and somehow append it after the first file to have both a correct file header (less than 1 sec) and that middle part of the video.
first.webm Range: bytes=0-102400 (valid playable file)
middle.webm Range: bytes=307200-614400 (not playable file)
I tried to merge them using this command recommended by this answer
ffmpeg -f concat -i list.txt -c copy merged.webm
logs:
[matroska,webm # 000002143c3e77c0] File ended prematurely00 bitrate=3752.0kbits/s speed=N/A
[matroska,webm # 000002143c429e40] Format matroska,webm detected only with low score of 1, misdetection possible!
[matroska,webm # 000002143c429e40] EBML header parsing failed
[concat # 000002143c3dda80] Impossible to open 'middle.webm'
list.txt: Invalid data found when processing input
frame= 42 fps=0.0 q=-1.0 Lsize= 10kB time=00:00:01.64 bitrate= 48.7kbits/s speed= 231x
video:9kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 8.500000%
generated video only shows the first video (which was already playable before merging) and ends.
I inspired this idea from this answer and don't want to download the complete video. If I can't merge them is it possible and how to write a MIME/header for the middle.webm manually to make it a valid playable video?

How can I simulate OpenFile in FFmpeg?

Most gif capture software capture screen and then save them one by one single frame picture file on disk,then read them into memory and combine them to gif,makes the whole procdure very slowly.
I got a idea to capture screen with DirectX(so we could also capture directx window faster since it direct operate the screen d3d device)API to got the bitmap,then save them to memory(such as buffer),then passing the memory location to ffmpeg to produce a video so we don't need disk storge as a middle buffer so it could be ten more faster since the disk is now most slowly part on pc now.
the directx capture screen part is already.But I found that ffmpeg using OpenFile to read the picture file,so here may we can simulate the OpenFile?
If answer is yes,how could we do it?
You can open a named pipe and use that as a source.
An example:
ffmpeg -f rawvideo -vcodec ravideo -s $width$x$height$ -r $framerate -pix_fmt $pixelFormat$ -i "\\.\pipe\$pipeName$" Output.gif
You have to fix the format of the frames you are going to feed FFmpeg, hence the -s and the -pix_fmt parameters.

make a video from a subset of images and audio

I want to create a video of three images and three audio files but the duration time of each image should be the time of the corresponding audio file.
Lets say I have three images image_0.png, image_1.png and image_2.png and three audio files audio_0.mp3 (length 10 seconds) , audio_1.mp3 (length 15 seconds), audio_2.mp3 (length 12 seconds).
I want to create a video showing first image_0.png with audio_0.mp3 for 10 seconds, then image_1.png with audio_1.mp3 for 15 seconds and in the end image_2.png with audio_2.mp3 for 12 seconds.
I tried to make this with avconv. I tried different variations of -i commands
avconv -i imageInputFile.png -i audioInputFile.mp3 -c copy output.avi
nothing worked. Indeed, I could make for each image+audio a single avi video, but I failed concatenating all single avi files... Besides this is not the best way I think because of quality loss.
How would you do this? Is this even possible with avconv?
first concatenate all your .mp3 in one single .mp3
then name your .png something like img01.png, img02.png ... imgxx.png
then try:
mencoder 'mf://img*.png' -oac mp3lame -ovc lavc -fps 1 -ofps 25 -vf harddup -audiofile audio.mp3 -o test.avi
obviously replace lavc with your preferred codec and 1 with a reasonable value to fit the frames in your audio track.
some may argue that it's stupid to recompress audio again and I can use -oac copy instead but when converting from multiple sources it can cause issues.
this command creates a 25 fps video stream with 15-26 duplicated frames per second, if you remove -ofps 25 you will avoid duplicate frames but some decoders could hang, especially when seeking

processing .raw file image with ffmpeg api or C code

I am trying to process a .raw image file captured using vrl2, it's a h264 encoded image with yuv422 color space from a Logitech c920 webcam, dcraw is not working for me however from my previous question this command is working fine with low performance (a 32kb jpg image however using opencv capture I get a 900kb image for the same 640x480 resolution):
ffmpeg -f rawvideo -s 640x480 -pix_fmt yuyv422 -i frame-1.raw
frame-1.jpg
I need a code written in C or the ffmpeg api/OpenCV etc .. to do the same as this command,I don't want to use QProcess in Qt(I am working on a server using Qt where I am trying to send the raw file from a Raspberry PI to the server and process it their), dcraw output is a corrupted image.
http://ffmpeg.org/doxygen/trunk/examples.html
There should be some api samples in there that show how to get the image out with that specific encoding.
When interacting with a RAW file, I have also used IrfanView. If you know the headersize of the file and the width and the height and the bits per pixel per color, you can see what it looks like quickly that way.
EDIT: I tried using Irfanview with your RAW, and I got something close, but not quite. The coloring was always off. I don't think it can handle that particular encoding of a RAW file right now.

FFMpeg: Take Certain Amount of Screenshots Between X and X?

Is there any way to get ffmpeg to take X number of screenshots between X time and X time? The way I'm doing my command line code now is like this:
ffmpeg -ss 79 -i 1.avi -r 1/2.15 -f image2 1_%%05d.jpg
This method only starts taking screenshots starting at 79 seconds, but I can't figure out a way to set an ending time (before the video ends).
Also, I will be displaying these video screenshots on a website and want there to be the same amount of screenshots per video file for consistency purposes. Is there a way to set how many screenshots I want from a video? As in, ffmpeg figures out how much time is between the two points I specify, then figures out how often to take a screenshot based on how many I want total from a video?
There is a -vframes option to control, how many frames of input ffmpeg should work with.
There is also a -t option to control, how many seconds of content to process.
Use any one of them.

Resources