FFMPEG Tutorial basics

1.Installation

  1. Download link:

https://github.com/BtbN/FFmpeg-Builds/releases as shown in https://ffmpeg.org/download.html#build-windows

Make sure that environment variable PATH contains path of ffmpeg.exe

2. Add Subtitles

ffmpeg -i file1.mp4 -vf subtitles=subtitles.srt videoWithSubtitles.mp4

subtitles.srt

1
00:00:02,000 --> 00:00:04,400
Welcome

2
00:00:06,600 --> 00:00:20,800
This is Cool IT Help

3
00:00:21,100 --> 00:00:23,800
How are you?

addSubtitle.bat file

@echo off
setlocal

ffmpeg -i file1.mp4 -vf subtitles=subtitles.srt videoWithSubtitlesSimple.mp4

"C:\Program Files (x86)\VideoLAN\VLC\vlc" videoWithSubtitlesSimple.mp4

set /p id="Press any key to continue: "

3. Add Texts

ffmpeg -i file1.mp4 -vf "[in]drawtext=fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF:fontsize=40:fontcolor=yellow:x=(w-text_w)/2:y=(h-text_h)/2:textfile='hello.txt':enable='between(t,2,6)',drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:fontsize=40:fontcolor=yellow:x=(w-text_w)/2:y=(h-text_h)/2:textfile='hello2.txt':enable='between(t,7,9)'[out]" -c:v libx264 -t 10 output.mp4

addTexts.bat

@echo off
setlocal

ffmpeg -i file1.mp4 -vf "[in]drawtext=fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF:fontsize=40:fontcolor=yellow:x=(w-text_w)/2:y=(h-text_h)/2:textfile='hello.txt':enable='between(t,2,6)',drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:fontsize=40:fontcolor=yellow:x=(w-text_w)/2:y=(h-text_h)/2:textfile='hello2.txt':enable='between(t,7,9)'[out]" -c:v libx264 -t 10 output.mp4

"C:\Program Files (x86)\VideoLAN\VLC\vlc" output.mp4

set /p id="Press any key to continue: "

4. Add Image/Thumbnail

addImage.bat

@echo off
rem ffmpeg -i file1.mp4 -i plus-48.png -filter_complex "overlay=20:20" output.mp4
ffmpeg -i file1.mp4 -i plus-48.png -filter_complex "overlay=main_w-(overlay_w+10):main_h-(overlay_h+10)" output.mp4

rem below code adjusts image size to fit in video , see video in bigger canvas section
rem ffmpeg -i interim.mp4 -i vedas2.jpg -b:v 1M -filter_complex "[1:v]scale=426x212 [ovrl], [0:v][ovrl]overlay=(main_w-overlay_w):(main_h-overlay_h), drawtext=fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF: text='Test Text': x=1: y=1: fontsize=30" output.mp4

"C:\Program Files (x86)\VideoLAN\VLC\vlc" output.mp4

set /p id="Prss any key to continue: "

5. Text Scrolling

@echo off

rem R2L bottom
rem ffmpeg -i file1.mp4 -vf drawtext="fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF:fontsize=40:fontcolor=yellow:text='Cool IT help':y=h-line_h-10:x=w-t*100" output.mp4
rem R2L top
rem ffmpeg -i file1.mp4 -vf drawtext="fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF:fontsize=40:fontcolor=yellow:text='Cool IT help':y=20-10:x=w-t*100" output.mp4
rem L2R top
rem ffmpeg -i file1.mp4 -vf drawtext="fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF:fontsize=40:fontcolor=yellow:text='Cool IT help':y=20-10:x=0+t*100" output.mp4
rem T2B Left
rem ffmpeg -i file1.mp4 -vf drawtext="fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF:fontsize=40:fontcolor=yellow:text='Cool IT help':y=0+t*100:x=20" output.mp4
rem T2B right
rem ffmpeg -i file1.mp4 -vf drawtext="fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF:fontsize=40:fontcolor=yellow:text='Cool IT help':y=0+t*100:x=w-text_w-10" output.mp4
rem L2R **LOOP*** bottom
rem x=(mod(5*n\,w+tw)-tw)
ffmpeg -i file1.mp4 -vf drawtext="fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF:fontsize=40:fontcolor=yellow:box=1:boxcolor=black@0.4:shadowcolor=white:shadowx=2:shadowy=2:text='Cool IT help':y=h-line_h-10:x=(mod(.5*n\,w+tw)-tw)" output.mp4

"C:\Program Files (x86)\VideoLAN\VLC\vlc" output.mp4
set /p id="Prss any key to continue: "

6. Video from Image

6.a. still image video

rem Example 1
ffmpeg -loop 1 -i vedas2.jpg -c:v libx264 -t 15 -pix_fmt yuv420p -vf scale=320:240 output.mp4
"C:\Program Files (x86)\VideoLAN\VLC\vlc" output.mp4

rem Example 2: crop image and make video
set OUTPUT_FILE="output.mp4"
set CROP_WIDTH=578
set CROP_HEIGHT=434
set CROP_STARTX=155
set CROP_STARTY=188
ffmpeg -loop 1 -i 1.png -filter:v "crop=%CROP_WIDTH%:%CROP_HEIGHT%:%CROP_STARTX%:%CROP_STARTy%" -c:v libx264 -t 5 -pix_fmt yuv420p  %OUTPUT_FILE% -y
set /p id="Press any key to continue: "

6.b. zooming image video

@echo off
setlocal

rem https://stackoverflow.com/questions/54547061/ffmpeg-animation-zoom-in-and-zoom-out

set OUTPUT_FILE="output2.mp4"

rem the ERROR could be ignored : ffmpeg deprecated pixel format used, make sure you did set range correctly
rem adding -pix_fmt yuvj422p  removes it in some cases but not always
rem In each 60-frame cycle, this will zoom in for first 30 frames, and zoom out the rest.
ffmpeg -loop 1 -i vedas2.jpg -vf "scale=iw*4:ih*4,zoompan=z='if(lte(mod(on,60),30),zoom+0.002,zoom-0.002)':x='iw/2-(iw/zoom)/2':y='ih/2-(ih/zoom)/2':d=25*5" -c:v libx264 -t 5 -s "1280x720" %OUTPUT_FILE% -y

"C:\Program Files (x86)\VideoLAN\VLC\vlc" %OUTPUT_FILE%

set /p id="Press any key to continue: "

"C:\Program Files (x86)\VideoLAN\VLC\vlc" %OUTPUT_FILE%

set /p id="Press any key to continue: "

7. Audio

7a. Add Audio

7b. Remove Audio

7c. Replace Audio

7d. Extract Audio

7e. Add Audio at particular time

check the below .bat which contains all above options

@echo off

rem mix audio
rem ffmpeg -i file1.mp4 -i indianBG.mp3 -filter_complex "[0:a][1:a]amerge=inputs=2[a]" -map 0:v -map "[a]" -c:v copy -ac 2 -shortest output.mp4
rem muted https://superuser.com/questions/268985/remove-audio-from-video-file-with-ffmpeg
rem ffmpeg -i file1.mp4 -c copy -an output.mp4
rem extract audio https://stackoverflow.com/questions/9913032/how-can-i-extract-audio-from-video-with-ffmpeg
rem ffmpeg -i file1.mp4 -q:a 0 -map a output.mp3
rem extract audio portion
rem ffmpeg -i file1.mp4 -ss 00:00:05 -t 00:00:10.0 -q:a 0 -map a output_portion.mp3
rem replace audio https://superuser.com/questions/1137612/ffmpeg-replace-audio-in-video
set OUTPUT_FILE="audio_replaced2.mp4"
ffmpeg -i file1.mp4 -i indianBG.mp3 -c:v copy -map 0:v:0 -map 1:a:0 -shortest %OUTPUT_FILE%

rem repeat audio till end https://superuser.com/questions/1319945/ffmpeg-mixing-new-audio-with-video-repeat-audio-until-video-finishes
rem ffmpeg -i inputVideoFilePath -filter_complex "amovie=inputAudioFilePath:loop=0,asetpts=N/SR/TB[aud];[0:a][aud]amix[a]" -map 0:v -map '[a]' -c:v copy -c:a aac -b:a 256k -shortest outputVideoFilePath

rem if you need only a part of audio,       replace loop=0,         with        loop=startTime,aselect=between(t\\\,startTimeOfAudio\\,endTimeOfAudio)

rem eg: ffmpeg -i "screenshots/mpc01/intelligenceIntro/intelligenceIntro.mp4" -filter_complex "amovie='BGs/BorrowTheHappiness.mp3':loop=114,aselect=between(t\,114\,180),asetpts=N/SR/TB[a]" -map 0:v -map [a] -c:v copy -c:a aac -b:a 256k -shortest screenshots/mpc01/intelligenceIntro/intelligenceIntroWithAudio.mp4 -y

rem another format

rem ffmpeg -i "screenshots/mpc01/intelligenceIntro/intelligenceIntroWithAudio.mp4"  -i "BGs/BorrowTheHappiness.mp3" -filter_complex "[1]aselect=between(t\,114\,180)[aud];[0][aud]amix" -c:v copy -shortest screenshots/mpc01/intelligenceIntro/out.mp4 -y 

rem replace existing audio with new short audio at particular time https://superuser.com/questions/708125/add-audio-at-specific-time-in-video-using-ffmpeg
rem ffmpeg -y -i outputWithAudio.mp4 -itsoffset 00:00:30 -i "G:\studio\soundEffects\ting.mp3" -map 0:0 -map 1:0 -c:v copy -preset ultrafast -async 1 outWithTing.mp4 -y

rem mix at particular time eg: 30 seconds https://stackoverflow.com/questions/48169031/how-to-add-audio-to-existing-video-using-ffmpeg-at-specific-time
rem ffmpeg -i outputWithAudio.mp4 -i "G:\studio\soundEffects\ting.mp3" -filter_complex "[1]adelay=30000|30000[aud];[0][aud]amix" -c:v copy outWithTing.mp4 -y

rem mix multiple audios
rem ffmpeg -i outputWithAudio.mp4 -i "G:\studio\soundEffects\ting.mp3" -i "G:\studio\soundEffects\waterDrops.mp3" -filter_complex "[1]adelay=30000|30000[aud1];[2]adelay=90000|90000[aud2];[0][aud1][aud2]amix=3" -c:v copy outWithMutlipleMix.mp4

"C:\Program Files (x86)\VideoLAN\VLC\vlc" %OUTPUT_FILE%
set /p id="Prss any key to continue: "

7.e Check if Video has Audio

rem https://stackoverflow.com/questions/21446804/find-if-video-file-has-audio-present-in-it
ffprobe -i chickenCurry.mp4 -show_streams -select_streams a -of json -loglevel error
{
    "streams": [

    ]
}

ffprobe -i outputWithAudio.mp4 -show_streams -select_streams a -of json -loglevel error
{
    "streams": [
        {
            "index": 1,
            "codec_name": "aac",
            "codec_long_name": "AAC (Advanced Audio Coding)",
            "profile": "LC",
            "codec_type": "audio",
.
.
.

7a. Add Audio with filter_complex

7a.1 Add audio to a silent video

ffmpeg -i %OUTPUT_FILE% -filter_complex "amovie=%BG%:loop=0,asetpts=N/SR/TB[a]" -map 0:v -map [a] -c:v copy -c:a aac -b:a 256k -shortest %OUTPUT_FILE_WITH_AUDIO% -y

7a. Mix audio to the existing audio of a video(not tested)

ffmpeg -i %OUTPUT_FILE% -filter_complex "amovie=%BG%:loop=0,asetpts=N/SR/TB[aud];[0:a][aud]amix[a]" -map 0:v -map '[a]' -c:v copy -c:a aac -b:a 256k -shortest %OUTPUT_FILE_WITH_AUDIO% -y


8. Crop Video

@echo off
rem https://video.stackexchange.com/questions/4563/how-can-i-crop-a-video-with-ffmpeg
set OUTPUT_FILE="output.mp4"
set CROP_WIDTH=in_w
set CROP_HEIGHT=in_h/2
set CROP_STARTX=0
set CROP_STARTY=0

ffmpeg -i PSC.mp4 -filter:v "crop=%CROP_WIDTH%:%CROP_HEIGHT%:%CROP_STARTX%:%CROP_STARTy%" %OUTPUT_FILE%

"C:\Program Files (x86)\VideoLAN\VLC\vlc" %OUTPUT_FILE%
set /p id="Prss any key to continue: "

9. Other Video Operations

9.a. Trim/Cut Videos

@echo off

ffmpeg -i file1.mp4 -ss 00:00:03 -t 00:00:08 -async 1 cut.mp4

set /p id="Press any key to continue: "

9.a.2 Trim to multiple parts with equal duration

rem https://unix.stackexchange.com/questions/148602/ffmpeg-split-video-multiple-parts
rem not tested 
rem fff.avi is the name of the source clip. Change -segment_time 40 to the general duration you want for each segment. If you want each clip to be about 10 seconds, then use -segment_time 10. Use -an after -map 0 if you don't want the resulting clips to have sound.

ffmpeg -i outputWithAudio.mp4 -acodec copy -f segment -segment_time 40 -vcodec copy -reset_timestamps 1 -map 0 fff%d.mp4

9.a.3 Trim into different duration

rem https://trac.ffmpeg.org/wiki/Creating%20multiple%20outputs
rem without audio
ffmpeg -i outputWithAudio.mp4 -y -filter_complex "[0:v]split=3[out1][out2][out3]" -map "[out1]" -ss 0 -t 10 -acodec -vcodec  output1.mp4 -map "[out2]" -ss 20 -t 5 -acodec -vcodec  output2.mp4 -map "[out3]" -ss 30 -t 15  -acodec -vcodec  output3.mp4

rem with audio, -map 0  maps ALL streams from the first input file to output
ffmpeg -i outputWithAudio.mp4 -y -filter_complex "split=3[out1][out2][out3]" -map "[out1]" -ss 0 -t 10 -map 0  output1.mp4 -map "[out2]" -ss 20 -t 5 -map 0  output2.mp4 -map "[out3]"  -ss 30 -t 15  -map 0  output3.mp4

9.b Video in bigger canvas

@echo off
rem https://superuser.com/questions/547296/resizing-videos-with-ffmpeg-avconv-to-fit-into-static-sized-player
set OUTPUT_FILE="output.mp4"
set CROP_WIDTH=in_w
set CROP_HEIGHT=in_h/2
set CROP_STARTX=0
set CROP_STARTY=0

rem ffmpeg -i cropped.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1:color=black" %OUTPUT_FILE%
rem ffmpeg -i cropped.mp4 -vf "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:-1:-1:color=pink" %OUTPUT_FILE%
rem ffmpeg -i cropped.mp4 -vf "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=iw:ih*2:-1:0:color=white" %OUTPUT_FILE%

rem vedas 538x392 interm.mp4 426x424
rem ffmpeg -i interim.mp4 2>&1 | python -c "import sys,re;[sys.stdout.write(str(re.findall(r'(\d+x\d+)', line))) for line in sys.stdin]"

rem put the video 'cropped.mp4' in bigger canvas and add the image vedas2.jpg in the bottom, ensuring that the image fits in the video
ffmpeg -i cropped.mp4  -vf "scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=iw:ih*2:-1:0:color=white" interim.mp4
ffmpeg -i interim.mp4 -i vedas2.jpg  -filter_complex [1:v]scale=320:240 [ovrl],[0:v][ovrl] "overlay=0:main_h-(overlay_h)" %OUTPUT_FILE%

rem ffmpeg -i interim.mp4 -i vedas2.jpg -b:v 1M -filter_complex "[1:v]scale=426x212 [ovrl], [0:v][ovrl]overlay=(main_w-overlay_w):(main_h-overlay_h), drawtext=fontfile=C\\:/Windows/Fonts/ITCBLKAD.TTF: text='Test Text': x=1: y=1: fontsize=30" output.mp4

rem ffmpeg -i cropped.mp4 -filter:v "scale=iw*min(%width%/iw\,%height%/ih):ih*min(%width%/iw\,%height%/ih), pad=%width%:%height%:(%width%-iw*min(%width%/iw\,%height%/ih))/2:(%height%-ih*min(%width%/iw\,%height%/ih))/2" %OUTPUT_FILE%

"C:\Program Files (x86)\VideoLAN\VLC\vlc" %OUTPUT_FILE%
set /p id="Prss any key to continue: "

9.c. Video inside video

@echo off
setlocal

rem https://www.youtube.com/watch?v=YFlDRVE-Cug

rem main_h :  base video height
rem main_w :  base video width
rem overlay_h : overlay video height
rem overlay_w : overlay video width

set OUTPUT_FILE="output2.mp4"
rem OVERLAY_SCALE is proportioner to size of overlay
set OVERLAY_SCALE="100:-1"
rem OVERLAY_STARTX & OVERLAY_STARTY to overlay in bottom right corner with padding space 10
set OVERLAY_STARTX= main_w - overlay_w - 10
set OVERLAY_STARTY= main_h - overlay_h - 10
rem ffmpeg -i   file1.mp4    -vf   "movie=cropped.mp4, scale=%OVERLAY_SCALE% [inner]; [in][inner] overlay =%OVERLAY_STARTX%: %OVERLAY_STARTY% [out]" %OUTPUT_FILE% -y
rem ffmpeg -i   file1.mp4    -vf   "movie=Sample_10_Transition_test.mp4, scale=%OVERLAY_SCALE% [inner]; [in][inner] overlay =%OVERLAY_STARTX%: %OVERLAY_STARTY% [out]" %OUTPUT_FILE% -y

rem overlay with chroma key https://ffmpeg.org/ffmpeg-filters.html#colorkey
rem https://stackoverflow.com/questions/8299252/ffmpeg-chroma-key-greenscreen-filter-for-images-video
rem ffmpeg -i <base-video> -i <overlay-video> -filter_complex '[1:v]colorkey=0x<color>:<similarity>:<blend>[ckout];[0:v][ckout]overlay[out]' -map '[out]' <output-file>
rem ffmpeg -i file1.mp4 -i Sample_10_Transition_test.mp4 -filter_complex "[1:v]colorkey=0xFF0000:0.3:0.2[ckout];[0:v][ckout]overlay[out]" -map "[out]" %OUTPUT_FILE% -y

rem chroma key after reducing size
ffmpeg -i Sample_10_Transition_test.mp4 -vf "scale=iw/4:ih/4" resized.mp4 -y
ffmpeg -i file1.mp4 -i resized.mp4   -filter_complex "[1:v]colorkey=0x00FF00:0.3:0.2[ckout];[0:v][ckout]overlay[out]" -map "[out]" %OUTPUT_FILE% -y

"C:\Program Files (x86)\VideoLAN\VLC\vlc" %OUTPUT_FILE%

set /p id="Press any key to continue: "

9.d Compress Video

There are 3 ways as in https://unix.stackexchange.com/questions/28803/how-can-i-reduce-a-videos-size-with-ffmpeg

  1. by changing codec, if the video uses old 264 codec
ffmpeg -i input.mp4 -vcodec libx265 -crf 28 output.mp4

2 by reducing bit rate

ffmpeg -i input.mp4 -b 800k output.mp4

3. By reducing frame size

eg:

ffmpeg -i input.mkv -vf "scale=iw/2:ih/2" half_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/3:ih/3" a_third_the_frame_size.mkv
ffmpeg -i input.mkv -vf "scale=iw/4:ih/4" a_fourth_the_frame_size.mkv

9.e. Get height and width of video

The following .bat code may be be used.

Python must be installed

@echo off
rem with python, Output will be like [][][][][][][][][][][][][][][][][][][]['0x31637661', '426x424'][][][]['0x6134706'][][][][]
ffmpeg -i interim.mp4 2>&1 | python -c "import sys,re;[sys.stdout.write(str(re.findall(r'(\d+x\d+)', line))) for line in sys.stdin]"

rem with ffprobe ,  https://superuser.com/questions/841235/how-do-i-use-ffmpeg-to-get-the-video-resolution , o/p will be like 1920 × 1080
ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 out.mp4
set /p id="Press any key to continue: "

9.f.Zooming in and out a Image/Video

@echo off
setlocal

rem https://stackoverflow.com/questions/54547061/ffmpeg-animation-zoom-in-and-zoom-out

set OUTPUT_FILE="output2.mp4"

rem the ERROR could be ignored : ffmpeg deprecated pixel format used, make sure you did set range correctly
rem adding -pix_fmt yuvj422p  removes it in some cases but not always
rem In each 60-frame cycle, this will zoom in for first 30 frames, and zoom out the rest.
rem ffmpeg -loop 1 -i vedas2.jpg -vf "scale=iw*4:ih*4,zoompan=z='if(lte(mod(on,60),30),zoom+0.002,zoom-0.002)':x='iw/2-(iw/zoom)/2':y='ih/2-(ih/zoom)/2':d=25*5" -c:v libx264 -t 5 -s "1280x720" %OUTPUT_FILE% -

rem simply enlarge an image after cropping

rem ffmpeg -i cropped.mp4 -vf "scale=2*iw:-1, crop=iw/2:ih/2"  %OUTPUT_FILE% -y

rem zoom in and out a video
rem https://ffmpeg.org/ffmpeg-filters.html#Examples-126
ffmpeg  -i cropped.mp4 -vf "scale=iw*4:ih*4,zoompan=z='if(lte(mod(on,60),30),zoom+0.002,zoom-0.002)':x='iw/2-(iw/zoom)/2':y='ih/2-(ih/zoom)/2':d=25*5" -c:v libx264 -t 5 -ss 5 -s "1280x720" %OUTPUT_FILE% -y

rem zoom out (big to small)
rem ffmpeg -loop 1 -i vedas2.jpg -vf "zoompan=z='if(lte(zoom,1.0),1.5,max(1.001,zoom-0.0015))':d=125" -c:v libx264 -t 5 -s "800x450" %OUTPUT_FILE% -y

rem zoom in https://superuser.com/questions/1411832/ffmpeg-how-to-zoom-in-a-video
rem ffmpeg -loop 1 -i vedas2.jpg -vf "zoompan=z=pzoom+0.01:x='iw/2-iw/zoom/2':y='ih/2-ih/zoom/2':d=1:s=1280x720:fps=5" -c:v libx264 -t 5 -s "800x450" %OUTPUT_FILE% -y

rem smooth zoom in , but no control of duration . video stops at 6 seconds. 
rem don't use this to zoom videos
rem ffmpeg -i vedas2.jpg -vf "scale=8000:-1,zoompan=z='min(zoom+0.0015,1.5)':x='iw/2-iw*(1/2-88/100)*on/150-iw/zoom/2':y='ih/2-ih*(1/2-94/100)*on/150-ih/zoom/2':d=150" -c:v libx264 -t 20 -s "800x450" %OUTPUT_FILE% -y

"C:\Program Files (x86)\VideoLAN\VLC\vlc" %OUTPUT_FILE%

set /p id="Press any key to continue: "

9.g Screen record

rem https://stackoverflow.com/questions/6766333/capture-windows-screen-with-ffmpeg
set OUTPUT_FILE=screenRecord.mp4
rem more options at https://askubuntu.com/questions/745975/ffmpeg-unrecognized-option-draw-mouse
ffmpeg -f gdigrab -draw_mouse 1 -framerate 10 -i desktop %OUTPUT_FILE% -y
rem ffmpeg -f gdigrab -framerate 10 -i title="Calculator"  %OUTPUT_FILE% -y

"C:\Program Files (x86)\VideoLAN\VLC\vlc" %OUTPUT_FILE%

set /p id="Press any key to continue: "

9.g.2 recording audio alone and with screen video

rem record audio only https://scribbleghost.net/2019/01/09/record-microphone-with-ffmpeg-in-windows/
rem ffmpeg -f dshow -i audio="Microphone (2- High Definition Audio Device)" -c:a libmp3lame -ar 44100 -b:a 320k -ac 1 output.mp3

rem record both audio and video combining above examples
rem to restrict recording to a particular region, use -offset_x 50 -offset_y 100 -video_size 320x240 
ffmpeg -f gdigrab -draw_mouse 1 -framerate 10 -i desktop -f dshow -i audio="Microphone (2- High Definition Audio Device)" -c:a libmp3lame -ar 44100 -b:a 320k -ac 1 %OUTPUT_FILE%

9.h Chromakey / Green Screen Effect

@echo off
setlocal

rem main_h :  base video height
rem main_w :  base video width
rem overlay_h : overlay video height
rem overlay_w : overlay video width

set OUTPUT_FILE="output2.mp4"
rem OVERLAY_SCALE is proportioner to size of overlay
set OVERLAY_SCALE="300:-1"
rem OVERLAY_STARTX & OVERLAY_STARTY to overlay in bottom right corner with padding space 10

rem set OVERLAY_STARTX= main_w - overlay_w - 10
rem set OVERLAY_STARTY= main_h - overlay_h - 10
set OVERLAY_STARTX=  10
set OVERLAY_STARTY=  10

rem resize video to overlay
ffmpeg -i Sample_10_Transition_test.mp4 -vf "scale=iw/2:ih/2" resized.mp4 -y

rem https://video.stackexchange.com/questions/30334/ffmpeg-crop-and-chromakey-not-working-together
rem [1:v] is stream specifier https://ffmpeg.org/ffmpeg.html#Stream-specifiers-1
rem overlay and chromakey

ffmpeg -i baseVideo.mp4 -i resized.mp4    -filter_complex "[1]scale=%OVERLAY_SCALE%[inner];[0][inner]overlay=%OVERLAY_STARTX%: %OVERLAY_STARTY%[ovout]; [ovout]colorkey=0x000000:0.02:0.03[ckout];[0:v][ckout]overlay[out]"  -map "[out]" -map 0:a  %OUTPUT_FILE% -y

rem http://manpages.ubuntu.com/manpages/bionic/man1/ffmpeg-filters.1.html
rem ffmpeg -i file1.mp4 -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" %OUTPUT_FILE% -y

"C:\Program Files (x86)\VideoLAN\VLC\vlc" %OUTPUT_FILE%

set /p id="Press any key to continue: "

9.i Video Record

@echo off
setlocal

rem ffmpeg -list_devices true -f dshow -i dummy

rem [dshow @ 0000018ed4bde540] DirectShow video devices (some may be both video and audio devices)
rem [dshow @ 0000018ed4bde540]  "Integrated Webcam"
rem [dshow @ 0000018ed4bde540]     Alternative name "@device_pnp_\\?\usb#vid_1bcf&pid_28c0&mi_00#6&b246cf2&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
rem [dshow @ 0000018ed4bde540] DirectShow audio devices
rem [dshow @ 0000018ed4bde540]  "Microphone (2- High Definition Audio Device)"
rem [dshow @ 0000018ed4bde540]     Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{21588D3D-4D22-49AA-A6A5-4DC8D8F71B31}"

rem https://trac.ffmpeg.org/wiki/Capture/Webcam
rem -i 0 is the index (zero based) in the list of present capture devices (Driver 0 in this instance).
rem ffmpeg -y -f vfwcap -r 25 -i 0 out.mp4
rem ffmpeg -y  -f vfwcap -r 25 -i 0 -f dshow  -i audio="Microphone (2- High Definition Audio Device)" -c:a libmp3lame -ar 44100 -b:a 320k -ac 1 out.mp4
rem https://ffmpeg.org/ffmpeg-devices.html#dshow
ffmpeg -f dshow -show_video_device_dialog true -crossbar_video_input_pin_number 0 -crossbar_audio_input_pin_number 3  -i video="Integrated Webcam":audio="Microphone (2- High Definition Audio Device)"   -vf scale=320:-1  out.mp4 -y

set /p id="Press any key to continue: "

9.i Streaming

rem streaming  command in http://4youngpadawans.com/stream-camera-video-and-audio-with-ffmpeg/
rem receive stream with vlc player using udp://@0.0.0.0:5000
rem ffmpeg -f dshow -i video="Integrated Webcam":audio="Microphone (2- High Definition Audio Device)" -profile:v high -pix_fmt yuvj420p -level:v 4.1 -preset ultrafast -tune zerolatency -vcodec libx264 -r 10 -b:v 512k -s 640x360 -acodec aac -ac 2 -ab 32k -ar 44100 -f mpegts -flush_packets 0 udp://127.0.0.1:5000?pkt_size=1316

9.j. Getting Duration

rem https://stackoverflow.com/questions/6239350/how-to-extract-duration-time-from-ffmpeg-output
rem It will output the duration in seconds, such as: 154.388000

ffprobe -i outputWithAudio.mp4 -show_entries format=duration -v quiet -of csv="p=0"

9.k Custom Thumbnail

rem setting custom thumbnail

ffmpeg -i chickenFriedRice.mp4 -i chickenFriedRice.jpg -map 1 -map 0 -c copy -disposition:0 attached_pic out.mp4

9.l. Image Scroll

rem move image from one point to another https://video.stackexchange.com/questions/24330/how-to-have-an-overlay-move-to-specific-points-at-specific-frames-using-ffmpeg
rem using frame number is smootther than time 
rem ffprobe -v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate outputWithAudio.mp4
rem abve command will return fraction 2997/100
rem ffmpeg -i chickenFriedRice.mp4 -i chickenFriedRice.jpg -y -filter_complex "[0:v][1:v]overlay=x='if(eq(n,0),50,0)':y='if(eq(n,9),50,0)':enable='eq(n,8)+eq(n,9)'[out]"  -map [out] -map 0  composit.mp4

rem for certain period https://stackoverflow.com/questions/45869889/ffmpeg-move-overlay-from-point-a-to-b-to-c-to-d
rem ffmpeg -i chickenFriedRice.mp4 -i chickenFriedRice.jpg -y -filter_complex "[0]scale=320:240[over];[1][over]overlay=enable='between=(t,0,50)':x=20+t*30:y=20+t*20" -s 1280:720 -c:a copy -y composit.mp4

rem start after 10 seconds
rem seconds ffmpeg -i chickenFriedRice.mp4 -i chickenFriedRice.jpg -y -filter_complex "[0]scale=320:240,setpts=PTS+10/TB[over2];[1][over2]overlay=x=if(gte(t\,10)\,20+t*30\,20+10*30):y=if(gte(t\,10)\,20+t*20\,20+10*20)" -s 1280:720 -c:a copy -y composit.mp4
rem move till 10 seconds 
rem ffmpeg -i outputWithAudio.mp4 -i chickenFriedRice.jpg -y -filter_complex "[0]scale=320:240[over2];[1][over2]overlay=x=if(lte(t\,10)\,20+t*30\,20+10*30):y=if(lte(t\,10)\,20+t*20\,20+10*20)" -s 1280:720 -c:a copy -y composit.mp4

rem not working https://superuser.com/questions/727379/how-to-make-left-right-transition-of-overlay-image-ffmpeg
rem ffmpeg -f lavfi -i "\color=black:d=15:s=1920x1080[background]; movie=outputWithAudio.mp4[overlay]; [background][overlay]overlay='min(W-n\,0):(H-h)/2' " output.mp4 -y

10. Concatenate

10.a Without Transition

@echo off
setlocal

rem w/o transition
rem ffmpeg-concat    -o  outputWithCli.mp4  file1.mp4  file2.mp4

rem https://stackoverflow.com/questions/7333232/how-to-concatenate-two-mp4-files-using-ffmpeg
rem solution 1 (when 100% same codec, same resolution, same type)
rem (echo file 'file1.mp4' & echo file 'file2.mp4' )>list.txt
rem ffmpeg -safe 0 -f concat -i list.txt -c copy outputWithSimpleFFMPEG.mp4

rem solution 2 (when 100% same codec, same resolution, same type)
rem ffmpeg -i "concat:file1.mp4|file2.mp4" -codec copy outputSimple.mp4

rem solution 3
rem If they are not exactly same (100% same codec, same resolution, same type) MP4 files, then you have to trans-code them into intermediate streams at first:

ffmpeg -i myfile1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp1.ts
ffmpeg -i myfile2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts temp2.ts

rem now join
ffmpeg -i "concat:temp1.ts|temp2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

rem NOTE!: Output will be like first file ( and not a second one)

set /p id="Press any key to continue: "

10.a.2 Concat parts of files

rem concat parts of files https://superuser.com/questions/1229945/ffmpeg-split-video-and-merge-back
rem ffmpeg -i chickenCurry.mp4 -i chickenFriedRice.mp4 -filter_complex " [0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; [1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; [0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; [v0][v1][v2]concat=n=3:v=1:a=0[out]" -map "[out]" partsConcat.mp4 -y

rem concat parts with audio
rem  Media type mismatch between the 'Parsed_setpts_3' filter output pad 0 (video) and the 'Parsed_concat_6' filter input pad 1 (audio)

rem https://stackoverflow.com/questions/48478595/when-concatenating-video-segments-ffmpeg-shows-error-media-type-mismatch-betwe
rem 1. Add atrim filters:
rem [0:a]trim=start=0:10,asetpts=PTS-STARTPTS[a0];[1:a]trim=0:5,asetpts=PTS-STARTPTS[a1];[0:a]trim=15:30,setpts=PTS-STARTPTS[a2];
rem 2. Then reference them in the concat filter:
rem [v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1:unsafe=1 [v_concatenado][a_concatenado]

rem https://superuser.com/questions/1242039/trim-and-concat-two-videos-with-audio-streams
rem ffmpeg -i outputWithAudio.mp4 -i chickenFriedRice.mp4 -filter_complex "[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; [0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; [1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; [1:a]atrim=0:5,asetpts=PTS-STARTPTS[a1]; [0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; [0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; [v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" 1.mp4

rem when any of the videos doesnt have audio
rem https://stackoverflow.com/questions/48577309/ffmpeg-version-2-6-8-stream-specifier-a-in-filtergraph-description-matches
rem Stream specifier ':a' in filtergraph description matches no streams.
rem Your other inputs don't have audio. A dummy audio has to be supplied.eg: lavfi -t 0.1 -i anullsrc

ffmpeg -i outputWithAudio.mp4 -i chickenFriedRice.mp4 -f lavfi -t 0.1 -i anullsrc -filter_complex "[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; [0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; [1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; [0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; [0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; [v0][a0][v1][2:a][v2][a2]concat=n=3:v=1:a=1[outv][outa]" -map "[outv]" -map "[outa]" 1.mp4


10.a.3 Concatenate different parts of same file to form a short file

rem https://stackoverflow.com/questions/50594412/cut-multiple-parts-of-a-video-with-ffmpeg
rem not tested
ffmpeg -i video \
       -vf "select='between(t,4,6.5)+between(t,17,26)+between(t,74,91)',
            setpts=N/FRAME_RATE/TB" \
       -af "aselect='between(t,4,6.5)+between(t,17,26)+between(t,74,91)',
            asetpts=N/SR/TB" out.mp4

10.b With Transition(with npm, ffmpeg_concat and node js)

Solution is based on

https://www.youtube.com/watch?v=PWp14WLzxDI&list=PL2EKpjm0bX4Khu04fG__4os58XR7I30po&index=18

Install 
npm
ffmpeg 
    pre requisites
    ================
    install  python https://www.python.org/
    install microsoft visual studio (with "production windows-build-tools" checked)
        https://visualstudio.microsoft.com/downloads/
        npm install --global --production windows-build-tools
        npm install --global node-gyp , node-gyp is a tool which compiles Node. js Addons. Node. js Addons are native Node. js Modules, written in C or C++, which therefore need to be compiled on your machine.

        to install ffmpeg-concat in C:\Program Files\nodejs\node_modules\npm\node_modules (default location). there is another location C:\Users\user\node_modules
        go to C:\Program Files\nodejs\node_modules\npm (or add this in PATH environment variable)
        and run npm install --save ffmpeg-concat

        otherwise Error will aqppear "npm WARN enoent ENOENT: no such file or directory, open 'C:\Users\Nuwanst\package.json'"

        othervise run 'npm init' (to create package.json)
    

index.js

<pre class="wp-block-syntaxhighlighter-code">//https://stackoverflow.com/questions/2727167/how-do-you-get-a-list-of-the-names-of-all-files-present-in-a-directory-in-node-j
//https://www.npmjs.com/package/ffmpeg-concat
//https://stackabuse.com/executing-shell-commands-with-node-js/

//node --trace-warnings readDirSync.js

const testFolder = 'chickenCurryImages/';
/*const fs = require('fs');
var files   = [];
fs.readdirSync(testFolder).forEach(file => {
  console.log(file);
  files.push(file);
});
*/
/*
https://gl-transitions.com/gallery
    directional,displacement,windowslice,bowtievertical,bowtiehorizontal
    fade
    fadegrayscale
    circleopen
    directionalwarp
    directionalwipe
    crosswarp
    crosszoom
    dreamy
    squareswire
    angular
    radial
    cube
    swap

*/
const concat = require('ffmpeg-concat');
var glob = require("glob")
var inputs = "chickenCurry";//"chickenFriedRice"
var inputsFolder = inputs + "Images/";//'chickenCurryImages/';
var outputsFolder = inputs + "Videos/";//'chickenCurryVideos/';
var files   = [];
var totalFiles = 0;
var videos   = [];
var transistions = [];
var availableTransistions = ["invertedpagecurl","directional","displacement","windowslice","bowtievertical","bowtiehorizontal","fade","fadegrayscale","circleopen","directionalwarp","directionalwipe","crosswarp","crosszoom","dreamy","squareswire","angular","radial","cube","swap"];
var totalAvailableTransitions = availableTransistions.length;
var totalMp4sMade = 0;
var filesMade = 0;
function execShellCommand(fileName, fileIndex)//https://stackabuse.com/executing-shell-commands-with-node-js/
{

    //ffmpeg -loop 1 -i image.jpg -r 29.970 -c:v libx264 -t 15 -pix_fmt yuv420p -profile:v high -level 4.2 -vf "scale=1920:1080, drawtext = text='Resumes in %{eif\:15-t\:d}': x=200: y=100: fontsize=30: fontcolor=black@0.7: box=1: boxcolor=red@0.2" out.mp4

    // working command is ffmpeg -loop 1 -i chickenCurryImages/IMG_20200408_120734.jpg -r 29.970 -c:v libx264 -t 15 -pix_fmt yuv420p -profile:v high -level 4.2 -vf scale=320:-1,drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:text='26':x=200:y=100:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2 chickenCurryVideos/IMG_20200408_120734.jpg.mp4 -y

    //let shellCommand = 'ffmpeg -loop 1 -i '+inputsFolder+fileName+' -r 29.970 -c:v libx264 -t 5 -pix_fmt yuv420p -profile:v high -level 4.2 -vf "scale=320:-1,drawtext=fontfile=C\\\\:/Windows/Fonts/arial.ttf:text=\''+(fileIndex+1)+'\':x=20: \y=10:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2" '+outputsFolder +fileName+'.mp4 -y'
    let shellCommand = "crop \""+fileName+ "\" " + (fileIndex+1) 
    console.log(shellCommand);
    //-vf "drawtext=text='My text starting at 640x360':x=640:y=360:fontsize=24:fontcolor=white" -c:a copy 
    /* let writeTextFilter = ',drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:fontsize=40:fontcolor=yellow:x=200:y=100:text='+(fileIndex+1)+' -c:a copy ';
    let shellCommand = "ffmpeg -loop 1 -i "+inputsFolder+fileName+" -c:v libx264 -t 3 -pix_fmt yuv420p -vf scale=320:240"+writeTextFilter+" chickenCurryVideos/"+fileName+".mp4 -y"; */
    const { spawn } = require("child_process");
//https://ffmpeg.org/ffmpeg-filters.html#drawtext-1
//const ls = spawn("ffmpeg",['-loop', 1, '-i',inputsFolder+fileName,'-r', 29.970, '-c:v', 'libx264', '-t', 5, '-pix_fmt', 'yuv420p', '-profile:v', 'high', '-level', 4.2, '-vf', "scale=320:-1,drawtext=fontfile=C\\\\:/Windows/Fonts/arial.ttf:text=\'"+(fileIndex+1)+"\':x=20: \y=10:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2",  outputsFolder +fileName+'.mp4', '-y']);
//let fileNameArg = "'" + fileName + "'";
let fileNameArg = fileName ;
const ls = spawn("crop.bat",[fileNameArg, (fileIndex+1)]);//,"-y"

ls.stdout.on("data", data => {
    console.log(<code>stdout: ${data}</code>);
});

ls.stderr.on("data", data => {
    console.log(<code>stderr: ${data}</code>);
});

ls.on('error', (error) => {
    console.log(<code>error: ${error.message}</code>);
});

ls.on("close", code => {
    filesMade++;
    console.log(fileIndex +" mp4 command execute complete, filesMade is " + filesMade + ", files.length is " + totalFiles);
    if(filesMade == totalFiles)
    {
        doConcat();
    }
});

}
function execShellCommandWithExec(fileName, fileIndex)
{
    const { exec } = require("child_process");
    //ffmpeg -loop 1 -i image.jpg -r 29.970 -c:v libx264 -t 15 -pix_fmt yuv420p -profile:v high -level 4.2 -vf "scale=1920:1080, drawtext = text='Resumes in %{eif\:15-t\:d}': x=200: y=100: fontsize=30: fontcolor=black@0.7: box=1: boxcolor=red@0.2" out.mp4

    // working command is ffmpeg -loop 1 -i chickenCurryImages/IMG_20200408_120734.jpg -r 29.970 -c:v libx264 -t 15 -pix_fmt yuv420p -profile:v high -level 4.2 -vf scale=320:-1,drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:text='26':x=200:y=100:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2 chickenCurryVideos/IMG_20200408_120734.jpg.mp4 -y

    let shellCommand = 'ffmpeg -loop 1 -i '+inputsFolder+fileName+' -r 29.970 -c:v libx264 -t 5 -pix_fmt yuv420p -profile:v high -level 4.2 -vf "scale=320:-1,drawtext=fontfile=C\\\\:/Windows/Fonts/arial.ttf:text=\''+(fileIndex+1)+'\':x=20: \y=10:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2" chickenCurryVideos/'+fileName+'.mp4 -y'
    //-vf "drawtext=text='My text starting at 640x360':x=640:y=360:fontsize=24:fontcolor=white" -c:a copy 
    /* let writeTextFilter = ',drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:fontsize=40:fontcolor=yellow:x=200:y=100:text='+(fileIndex+1)+' -c:a copy ';
    let shellCommand = "ffmpeg -loop 1 -i "+inputsFolder+fileName+" -c:v libx264 -t 3 -pix_fmt yuv420p -vf scale=320:240"+writeTextFilter+" chickenCurryVideos/"+fileName+".mp4 -y"; */

        console.log(totalMp4sMade +" mp4 commands executed");
    exec(shellCommand, (error, stdout, stderr) => {
        if (error) {
            console.log(<code>error: ${error.message}</code>);
            return;
        }
        if (stderr) {
            console.log(<code>stderr: ${stderr}</code>);
            return;
        }
        console.log(<code>stdout: ${stdout}</code>);
        totalMp4sMade++;
        console.log(totalMp4sMade +" mp4 commands executed");
        if(totalMp4sMade >= (files.length-1))
        {
            doConcat();
        }//if(totalMp4sMade >= files.length)
    });
}//function execShellCommand(fileName, fileIndex)
function doConcat()
{
    console.log("doConcat() called");
  concat({
      output: "target/output.mp4",
      videos: videos,
      transitions: transistions
    })
}//function doConcat()

// options is optional
//glob(inputsFolder+"IMG*.jpg", null, function (er, files) {
glob("source/*.png", null, function (er, files) {
  // files is an array of filenames.
  // If the <code>nonull</code> option is set, and nothing
  // was found, then files is ["**/*.js"]
  // er is an error object or null.
  //let videos = [];
  //files.sort();
  totalFiles = files.length;
  //console.log(JSON.stringify(files));//output like ["chickenCurryImages/IMG_20200408_113822.jpg",...
  let transitionIndex = 0;
  let fileName = "";
  let video2Push = "";
  let filesSorted = [];
  for(let i=0;i<= files.length;i++)
  {
      let filePrefix = "source/"+(i+1)+"-";
      files.forEach(element => {
          //console.log("element is "+ element);
          if(element.startsWith(filePrefix)){filesSorted.push(element);
          }})
  }  
  files = filesSorted;
  console.log(JSON.stringify(files));
  for(let i=0;i< files.length;i++)
  {
        /*{
            duration: 1000,
            name: 'fade'
          }*/
          if(transitionIndex >= totalAvailableTransitions)
          {
              transitionIndex = 0;            
          }//if(transitionIndex < totalAvailableTransitions)

        if(i< (files.length-1))transistions.push({duration:1000,name:availableTransistions[transitionIndex]});
        transitionIndex++;
        fileName = files[i].replace(inputsFolder,"");
        video2Push = "target/"+(i+1)+".mp4";
        videos.push(video2Push);
        execShellCommand(fileName, i);

  }//for(let i=0;i< files.length;i++)
     // execShellCommand(fileName, 12);
  //files.push(files[files.length-1]);
    //videos.push(outputsFolder +fileName+".mp4");
    //videos.push(video2Push);
    //doConcat();
})
</pre>

.bat file

@echo off
setlocal

echo NODE_PATH is %NODE_PATH%
rem node index.js
rem node indexNoTransition.js

rem to use command line mode ffmpeg_concat cli version must be installed
rem cli version command is  ffmpeg-concat  -t  angular -d 5000  -o  outputWithCli.mp4  file1.mp4  file2.mp4

rem ffmpeg-concat  -t  angular -d 5000  -o  outputWithCli.mp4  file1.mp4  file2.mp4

set /p id="Press any key to continue: "

Complex Node JS

<pre class="wp-block-syntaxhighlighter-code">//https://stackoverflow.com/questions/2727167/how-do-you-get-a-list-of-the-names-of-all-files-present-in-a-directory-in-node-j
//https://www.npmjs.com/package/ffmpeg-concat
//https://stackabuse.com/executing-shell-commands-with-node-js/

const testFolder = 'chickenCurryImages/';
/*const fs = require('fs');
var files   = [];
fs.readdirSync(testFolder).forEach(file => {
  console.log(file);
  files.push(file);
});
*/
/*
https://gl-transitions.com/gallery
    directional,displacement,windowslice,bowtievertical,bowtiehorizontal
    fade
    fadegrayscale
    circleopen
    directionalwarp
    directionalwipe
    crosswarp
    crosszoom
    dreamy
    squareswire
    angular
    radial
    cube
    swap

*/
const concat = require('ffmpeg-concat');
var glob = require("glob")
var inputs = "chickenCurry";//"chickenFriedRice"
var inputsFolder = inputs + "Images/";//'chickenCurryImages/';
var outputsFolder = inputs + "Videos/";//'chickenCurryVideos/';
var files   = [];
var totalFiles = 0;
var videos   = [];
var transistions = [];
var availableTransistions = ["invertedpagecurl","directional","displacement","windowslice","bowtievertical","bowtiehorizontal","fade","fadegrayscale","circleopen","directionalwarp","directionalwipe","crosswarp","crosszoom","dreamy","squareswire","angular","radial","cube","swap"];
var totalAvailableTransitions = availableTransistions.length;
var totalMp4sMade = 0;
var filesMade = 0;
function execShellCommand(fileName, fileIndex)//https://stackabuse.com/executing-shell-commands-with-node-js/
{

    //ffmpeg -loop 1 -i image.jpg -r 29.970 -c:v libx264 -t 15 -pix_fmt yuv420p -profile:v high -level 4.2 -vf "scale=1920:1080, drawtext = text='Resumes in %{eif\:15-t\:d}': x=200: y=100: fontsize=30: fontcolor=black@0.7: box=1: boxcolor=red@0.2" out.mp4

    // working command is ffmpeg -loop 1 -i chickenCurryImages/IMG_20200408_120734.jpg -r 29.970 -c:v libx264 -t 15 -pix_fmt yuv420p -profile:v high -level 4.2 -vf scale=320:-1,drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:text='26':x=200:y=100:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2 chickenCurryVideos/IMG_20200408_120734.jpg.mp4 -y

    let shellCommand = 'ffmpeg -loop 1 -i '+inputsFolder+fileName+' -r 29.970 -c:v libx264 -t 5 -pix_fmt yuv420p -profile:v high -level 4.2 -vf "scale=320:-1,drawtext=fontfile=C\\\\:/Windows/Fonts/arial.ttf:text=\''+(fileIndex+1)+'\':x=20: \y=10:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2" '+outputsFolder +fileName+'.mp4 -y'
    //-vf "drawtext=text='My text starting at 640x360':x=640:y=360:fontsize=24:fontcolor=white" -c:a copy 
    /* let writeTextFilter = ',drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:fontsize=40:fontcolor=yellow:x=200:y=100:text='+(fileIndex+1)+' -c:a copy ';
    let shellCommand = "ffmpeg -loop 1 -i "+inputsFolder+fileName+" -c:v libx264 -t 3 -pix_fmt yuv420p -vf scale=320:240"+writeTextFilter+" chickenCurryVideos/"+fileName+".mp4 -y"; */
    const { spawn } = require("child_process");
//https://ffmpeg.org/ffmpeg-filters.html#drawtext-1
const ls = spawn("ffmpeg",['-loop', 1, '-i',inputsFolder+fileName,'-r', 29.970, '-c:v', 'libx264', '-t', 5, '-pix_fmt', 'yuv420p', '-profile:v', 'high', '-level', 4.2, '-vf', "scale=320:-1,drawtext=fontfile=C\\\\:/Windows/Fonts/arial.ttf:text=\'"+(fileIndex+1)+"\':x=20: \y=10:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2",  outputsFolder +fileName+'.mp4', '-y']);

ls.stdout.on("data", data => {
    console.log(<code>stdout: ${data}</code>);
});

ls.stderr.on("data", data => {
    console.log(<code>stderr: ${data}</code>);
});

ls.on('error', (error) => {
    console.log(<code>error: ${error.message}</code>);
});

ls.on("close", code => {
    filesMade++;
    console.log(fileIndex +" mp4 command execute complete, filesMade is " + filesMade + ", files.length is " + totalFiles);
    if(filesMade == totalFiles)
    {
        doConcat();
    }
});

}
function execShellCommandWithExec(fileName, fileIndex)
{
    const { exec } = require("child_process");
    //ffmpeg -loop 1 -i image.jpg -r 29.970 -c:v libx264 -t 15 -pix_fmt yuv420p -profile:v high -level 4.2 -vf "scale=1920:1080, drawtext = text='Resumes in %{eif\:15-t\:d}': x=200: y=100: fontsize=30: fontcolor=black@0.7: box=1: boxcolor=red@0.2" out.mp4

    // working command is ffmpeg -loop 1 -i chickenCurryImages/IMG_20200408_120734.jpg -r 29.970 -c:v libx264 -t 15 -pix_fmt yuv420p -profile:v high -level 4.2 -vf scale=320:-1,drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:text='26':x=200:y=100:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2 chickenCurryVideos/IMG_20200408_120734.jpg.mp4 -y

    let shellCommand = 'ffmpeg -loop 1 -i '+inputsFolder+fileName+' -r 29.970 -c:v libx264 -t 5 -pix_fmt yuv420p -profile:v high -level 4.2 -vf "scale=320:-1,drawtext=fontfile=C\\\\:/Windows/Fonts/arial.ttf:text=\''+(fileIndex+1)+'\':x=20: \y=10:fontsize=30:fontcolor=yellow@0.7:box=1:boxcolor=red@0.2" chickenCurryVideos/'+fileName+'.mp4 -y'
    //-vf "drawtext=text='My text starting at 640x360':x=640:y=360:fontsize=24:fontcolor=white" -c:a copy 
    /* let writeTextFilter = ',drawtext=fontfile=C\\:/Windows/Fonts/arial.ttf:fontsize=40:fontcolor=yellow:x=200:y=100:text='+(fileIndex+1)+' -c:a copy ';
    let shellCommand = "ffmpeg -loop 1 -i "+inputsFolder+fileName+" -c:v libx264 -t 3 -pix_fmt yuv420p -vf scale=320:240"+writeTextFilter+" chickenCurryVideos/"+fileName+".mp4 -y"; */

        console.log(totalMp4sMade +" mp4 commands executed");
    exec(shellCommand, (error, stdout, stderr) => {
        if (error) {
            console.log(<code>error: ${error.message}</code>);
            return;
        }
        if (stderr) {
            console.log(<code>stderr: ${stderr}</code>);
            return;
        }
        console.log(<code>stdout: ${stdout}</code>);
        totalMp4sMade++;
        console.log(totalMp4sMade +" mp4 commands executed");
        if(totalMp4sMade >= files.length)
        {
            doConcat();
        }//if(totalMp4sMade >= files.length)
    });
}//function execShellCommand(fileName, fileIndex)
function doConcat()
{
    console.log("doConcat() called");
  concat({
      output: inputs+'.mp4',
      videos: videos,
      transitions: transistions
    })
}//function doConcat()

// options is optional
glob(inputsFolder+"IMG*.jpg", null, function (er, files) {
  // files is an array of filenames.
  // If the <code>nonull</code> option is set, and nothing
  // was found, then files is ["**/*.js"]
  // er is an error object or null.
  //let videos = [];

  totalFiles = files.length;
  console.log(JSON.stringify(files));//output like ["chickenCurryImages/IMG_20200408_113822.jpg",...
  let transitionIndex = 0;
  let fileName = "";
  for(let i=0;i< files.length;i++)
  {
        /*{
            duration: 1000,
            name: 'fade'
          }*/
          if(transitionIndex >= totalAvailableTransitions)
          {
              transitionIndex = 0;            
          }//if(transitionIndex < totalAvailableTransitions)

        transistions.push({duration:1000,name:availableTransistions[transitionIndex]});
        transitionIndex++;
        fileName = files[i].replace(inputsFolder,"");
        videos.push(outputsFolder +fileName+".mp4");
        execShellCommand(fileName, i);

  }//for(let i=0;i< files.length;i++)
     // execShellCommand(fileName, 12);
  //files.push(files[files.length-1]);
    videos.push(outputsFolder +fileName+".mp4");
    //doConcat();
})
</pre>

11.Reversing a video

reference

ffmpeg -i originalVideo.mp4 -vf reverse reversedVideo.mp4