make a video from a subset of images and audio - video-processing

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

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?

Drop some parts of video and re-make key frames (c++ + libav)

I'm trying to drop some parts of video in my app using libav, for example in a video that has 00:08:00 length, I try to drop frames 100-250 and 400-500 (Just for example).
I wrote this code that copy AVPacket and drop some packets, But there is a problem! In our videos every keyframe followed by 29 non-key frames. So when my code goes to drop frames 100-250 the frame 100 may be is a non-key frame, in this case the parts that are going to join (In this example frame 250 to frame 400) the frame 400 is positioned after a keyframe that is not belogs to.
In this section video frames shown garbled,
Video cutting speed is so important in my code, so I can't decode/re-encode all of video frames.
The question is that, How can I decode encode begin of each parts (from begin frame to first key frame) and make another frames copy without decode?
Or, Is there any another FAST solution for splitting/merging (Dropping some parts of video)?
The question is that, How can I decode encode begin of each parts (from begin frame to first key frame) and make another frames copy without decode?
You can't. It doesn't work that way.
Start to think about time, not in frames
you can get new videos fast in parts of base_video.mp4, for example,
ffmpeg -ss 00:00:00.000 -i base_video.mp4 -t 8.000 -c copy -strict -2 new_video_8seconds_fromstart.mp4
-ss 00:00:00.000 is the time to start the new video
-t is the duration in seconds and miliseconds, example, for 8 seconds of duration you have to use 8.000
-an if you dont want audio
-strict -2 if for copy some files codecs like DTS
but if you want with re-encoding remove -c copy but it never will be fast!
ffmpeg -ss 00:00:00.000 -i base_video.mp4 -t 8.000 new_video_8seconds_fromstart.mp4

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.

Out of memory on ffmpeg when converting to H265

I've a bunch of video files, mostly H264. To save storage, I wrote a batch script, that converts all of them to H265 using ffmpeg. Problem: Some files cause ffmpeg to use ALL my memory (24 GB). Then it crashes (cause it try to allocate even more RAM), which stops the converting process.
I think that these files are corrupt in some kind. Because with other files, it works well with low memory consumption. Now I want to reject those broken ones, so that unattended converting is possible.
How is it possible to detect such corruption? Can ffmpeg do this, or is a third party tool required?
My ffmpeg call
set crf=20
set codec=265
ffmpeg -hide_banner -i "!fullSourcePath!" -c:v libx%codec% -crf %crf% "%targetPath%\!targetFileName!"
mkvalidator can't help
mkvalidator says that a corrupt file is valid:
mkvalidator.exe "V:\Filme\_LegacyFormat\22 Jump Street.mkv"
........................................................................................................................
WRN0D0: There are 5306 bytes of void data..
mkvalidator 0.5.0: the file appears to be valid
file created with libebml v1.3.0 + libmatroska v1.4.1 / mkvmerge v6.9.1 ('Blue Panther') 64bit built on Apr 18 2014 18:23:38
eac3to331 can't help, too
I found the tool eac3to331, which has a check flag. But it gave me no errors, although the tested file seems corrupt (cause my PC to crash after several minutes running ffmpeg)
eac3to.exe -check "V:\Filme\_LegacyFormat\22 Jump Street.mkv"
MKV, 1 video track, 2 audio tracks, 1 subtitle track, 1:51:57, 24p /1.001
1: h264/AVC, English, 1920x808 24p /1.001 (240:101)
2: DTS, German, 5.1 channels, 1509kbps, 48kHz
3: DTS, English, 5.1 channels, 1509kbps, 48kHz
4: Subtitle (SRT), German
v01 Extracting video track number 1...
a02 Extracting audio track number 2...
a03 Extracting audio track number 3...
s04 Extracting subtitle track number 4...
Video track 1 contains 161039 frames.
eac3to processing took 1 minute, 26 seconds.
Done.

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