1.Installation
- 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
- 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
ffmpeg -i originalVideo.mp4 -vf reverse reversedVideo.mp4
|
|