# set the working space
#
# on Linux/Mac/Windows Terminal or WSL/Windows locally

cd Desktop

# on Windows on OneDrive Cloud

cd OneDrive



# generate exercise files

ffmpeg -f lavfi -i mandelbrot -t 10 -c:v rawvideo -pix_fmt uyvy422 mandelbrot.avi

ffplay mandelbrot.avi

ffmpeg -f lavfi -i "sine=frequency=440" -t 10 -c:a pcm_s16le -ar 48k -ac 2 la.wav

ffplay la.wav

ffmpeg -i mandelbrot.avi -i la.wav -c:v copy -c:a copy mandela.avi

ffplay mandela.avi

ffprobe mandela.avi

ffprobe -show_format -show_streams mandela.avi

ffprobe -show_format -show_streams -print_format flat mandela.avi

ffprobe -show_format -show_streams -print_format xml mandela.avi

ffprobe -show_format -show_streams -print_format json mandela.avi

ffprobe -show_format -show_streams -print_format json mandela.avi > mandela.txt

mediainfo mandela.avi



# find help

ffmpeg -h

ffmpeg -codecs

ffmpeg -decoders

ffmpeg -h decoder=aac

ffmpeg -encoders

ffmpeg -h encoder=libx264

ffmpeg -filters

ffmpeg -pix_fmts



# modify container

ffmpeg -i mandelbrot.avi -c copy mandelbrot.mov



# generate checksums at frame level

ffmpeg -i mandelbrot.avi -f framemd5 mandelbrot_avi_framemd5.txt

ffmpeg -i mandelbrot.mov -f framemd5 mandelbrot_mov_framemd5.txt



# compare checksum files
#
# on Linux/Mac/Windows Terminal or WSL

diff -s mandelbrot_avi_framemd5.txt mandelbrot_mov_framemd5.txt

# on Windows

fc mandelbrot_avi_framemd5.txt mandelbrot_mov_framemd5.txt



# play a single image sequence

ffplay -loop 0 DUFAY_TIFF/Dufay_%06d.tif



# from master to mezzanine (ProRes)

ffmpeg -f image2 -framerate 24 -i DUFAY_TIFF/Dufay_%06d.tif -filter:v "scale=1440:1080:flags=lanczos, pad=1920:1080:240:0" -c:v prores_ks -profile:v 4 Dufay_ProRes.mkv

# from master to mezzanine (AVID)

ffmpeg -h encoder=dnxhd

ffmpeg -f image2 -framerate 24 -i DUFAY_TIFF/Dufay_%06d.tif -filter:v "scale=1440:1080:flags=lanczos, pad=1920:1080:240:0" -c:v dnxhd -profile:v dnxhr_444 -pix_fmt yuv444p10le Dufay_DNxHR.mxf



# from mezzanine (ProRes) to access

ffmpeg -i Dufay_ProRes.mkv -pix_fmt yuv420p -c:v libx264 -preset veryslow -crf 30 -movflags +faststart+write_colr Dufay_ProRes_H264.mp4

# from mezzanine (AVID) to access

ffmpeg -i Dufay_DNxHR.mxf -pix_fmt yuv420p -c:v libx264 -preset veryslow -crf 30 -movflags +faststart+write_colr Dufay_DNxHR_H264.mp4

# from master to access

ffmpeg -f image2 -framerate 24 -i DUFAY_TIFF/Dufay_%06d.tif -filter:v "scale=1440:1080:flags=lanczos, pad=1920:1080:240:0" -pix_fmt yuv420p -c:v libx264 -preset veryslow -crf 30 -movflags +faststart+write_colr Dufay_master_H264.mp4



# split screen master/ProRes

ffmpeg -i Dufay_master_H264.mp4 -i Dufay_ProRes_H264.mp4 -filter_complex "[0]crop=iw/2:ih:0:0[left]; [1]crop=iw/2:ih:iw/2:0[right]; [left][right]hstack" Dufay_split_ProRes.mp4

# split screen master/AVID

ffmpeg -i Dufay_master_H264.mp4 -i Dufay_DNxHR_H264.mp4 -filter_complex "[0]crop=iw/2:ih:0:0[left]; [1]crop=iw/2:ih:iw/2:0[right]; [left][right]hstack" Dufay_split_DNxHR.mp4

# split screen ProRes/AVID

ffmpeg -i Dufay_ProRes_H264.mp4 -i Dufay_DNxHR_H264.mp4 -filter_complex "[0]crop=iw/2:ih:0:0[left]; [1]crop=iw/2:ih:iw/2:0[right]; [left][right]hstack" Dufay_split_mezzanine.mp4



# test filter

ffplay -vf "negate" Dufay_master_H264.mp4

# difference file master/ProRes

ffmpeg -i Dufay_master_H264.mp4 -i Dufay_ProRes_H264.mp4 -filter_complex "[1] format=yuva444p, lut=c3=128, negate [1_with_alpha]; [0][1_with_alpha] overlay" Dufay_delta_ProRes.mp4

# difference file master/AVID

ffmpeg -i Dufay_master_H264.mp4 -i Dufay_DNxHR_H264.mp4 -filter_complex "[1] format=yuva444p, lut=c3=128, negate [1_with_alpha]; [0][1_with_alpha] overlay" Dufay_delta_DNxHR.mp4

# difference file ProRes/AVID

ffmpeg -i Dufay_ProRes_H264.mp4 -i Dufay_DNxHR_H264.mp4 -filter_complex "[1] format=yuva444p, lut=c3=128, negate [1_with_alpha]; [0][1_with_alpha] overlay" Dufay_delta_mezzanine.mp4



# generate a sound file

ffmpeg -f lavfi -i "anoisesrc=color=brown" -filter:a "tremolo=f=0.1:d=0.9" -c:a pcm_s24le -ar 96k -ac 2 -t 60 seashore_good.wav

# play the sound file

ffplay seashore_good.wav

# damage the sound file

ffmpeg -i seashore_good.wav -c copy -bsf:a "noise=amount=-1" seashore_bad.wav

# play the damaged sound file

ffplay seashore_bad.wav



# show volume

ffplay -f lavfi "amovie=seashore_good.wav, asplit [a][out1]; [a] showvolume=c=VOLUME:w=1000:h=100:ds=log [out0]"

ffplay -f lavfi "amovie=seashore_good.wav, asplit [a][out1]; [a] showvolume=c=VOLUME:w=1000:h=100:ds=lin [out0]"

ffplay -f lavfi "amovie=seashore_bad.wav, asplit [a][out1]; [a] showvolume=c=VOLUME:w=1000:h=100:ds=lin [out0]"



# show waves

ffplay -f lavfi "amovie=seashore_good.wav, asplit [a][out1]; [a] showwaves=mode=point [out0]"

ffplay -f lavfi "amovie=seashore_good.wav, asplit [a][out1]; [a] showwaves=mode=p2p [out0]"

ffplay -f lavfi "amovie=seashore_good.wav, asplit [a][out1]; [a] showwaves=mode=cline [out0]"

ffplay -f lavfi "amovie=seashore_bad.wav, asplit [a][out1]; [a] showwaves=mode=cline [out0]"



# show spectrum

ffplay -f lavfi "amovie=seashore_good.wav, asplit [a][out1]; [a] showspectrum=mode=separate:color=intensity:slide=1:scale=cbrt [out0]"

ffplay -f lavfi "amovie=seashore_bad.wav, asplit [a][out1]; [a] showspectrum=mode=separate:color=intensity:slide=1:scale=cbrt [out0]"



# extract metadata

ffprobe -show_format -show_streams -print_format json seashore_good.wav

mediainfo seashore_good.wav

mediainfo --Details=1 seashore_good.wav



# show which fonts are installed
#
# on macOS

ls /Library/Fonts

# on Windows

dir \Windows\Fonts



# add watermark

ffmpeg -i Dufay_master_H264.mp4 -filter:v "drawtext=text='watermark':fontfile='/Library/Fonts/Arial.ttf':fontsize=35:fontcolor=white:alpha=0.25:x=(w-text_w)/2:y=(h-text_h)/2" with_watermark.mp4



# add timecode

ffmpeg -i Dufay_master_H264.mp4 -filter:v "drawtext=timecode='01\:00\:30\:00':rate=25:fontfile='/Library/Fonts/Arial.ttf':fontsize=35:fontcolor=white:x=(w-text_w)/2:y=h/1.2" with_timecode.mp4



# add logo

ffmpeg -i Dufay_master_H264.mp4 -i logo.png -filter_complex "overlay=10:main_h-overlay_h-10" with_logo.mp4



# delve deep into the file structure with "fq"
#
# see: https://github.com/wader/fq

fq . seashore_good.wav

fq d seashore_good.wav



# play a 1000 Hz test sound

ffplay -f lavfi -i "sine=frequency=1000"

# play Mandelbrot without creating the file

ffplay -f lavfi -i mandelbrot

# generate the SMPTE bars for HD

ffmpeg -f lavfi -i "smptehdbars=1920x1080" -f lavfi -i "sine=frequency=1000" -t 30 SMPTE_HD.mkv



# visualise each single bit of two seconds of Mandelbrot
#
# this works on Linux and macOS, untested on Windows

ffmpeg -f lavfi -i mandelbrot -t 2 -pix_fmt yuv420p -f h264 - | xxd -b -c 1 | grep -o '[01]\{8\}' | echo $(tr -d '\n')



# show histogram of Dufay

ffmpeg -f image2 -i DUFAY_TIFF/Dufay_%06d.tif -c:v rawvideo -pix_fmt uyvy422 -f nut - | ffplay -vf "histogram=display_mode=overlay" -x 640 -y 480 -



# generate image and sound for test DCP

ffmpeg -f lavfi -i "smptehdbars=1920x1080" -filter:v "hue=H=0.2*t" -c:v rawvideo -t 30 hue.mkv

ffmpeg -f lavfi -i "anoisesrc=colour=brown" -filter:a "tremolo=f=0.1:d=0.9" -c:a pcm_s24le -ar 96k -t 30 tremolo.wav

ffmpeg -i hue.mkv -i tremolo.wav -c:v copy -c:a copy hue_and_tremolo.mkv



# low-pass filter

ffplay -af "lowpass=f=3200" seashore_bad.wav

# high-pass filter

ffplay -af "highpass=f=3200" seashore_bad.wav

# sound noise reduction

ffmpeg -i seashore_bad.wav -filter:a "afftdn=nr=10:nf=-25:tn=1" -c:a pcm_s24le seashore_bad_denoised.wav



# adjust audio volume

ffplay -af "volume=volume=10dB" seashore_good.wav

ffmpeg -i seashore_good.wav -filter:a "volume=volume=10dB" seashore_good_louder.wav

ffplay -af "volume=volume=-10dB" seashore_good.wav

ffmpeg -i seashore_good.wav -filter:a "volume=volume=-10dB" seashore_good_quieter.wav



# screen/cam lossless recording in SD
#
# on Linux with "x11grap" and "ALSA" or "pulse"
# on macOS with "avfoundation"
# on Windows with "DirectShow"
#
# the following two commands are for macOS

# list the available devices

ffmpeg -f avfoundation -list_devices true -i ""

# record

ffmpeg -video_size 640x480 -framerate 25 -f avfoundation -i "0:0" -c:v libx264rgb -preset ultrafast -crf 0 -color_range 2 -c:a pcm_s24le -ar 96k -ac 2 output_archive.mkv

# lossy re-encoding with subtitles in SRT format

ffmpeg -i output_archive.mkv -filter:v "subtitles=subtitles.srt" -c:v libx264 -preset veryslow -crf 18 -pix_fmt yuv420p -c:a aac -ar 48k -movflags +faststart+write_colr output_streaming.mp4