Skip to content

Instantly share code, notes, and snippets.

@defensem3ch
Created January 4, 2021 15:38
Show Gist options
  • Save defensem3ch/04ebf20a8adf3e776841d200ca385599 to your computer and use it in GitHub Desktop.
Save defensem3ch/04ebf20a8adf3e776841d200ca385599 to your computer and use it in GitHub Desktop.
BGB-TV Bash FFmpeg script to generate CRT-stylized output from raw AVI and WAV files from BGB
#!/bin/bash
# A collection of FFmpeg filterchains which can be used to create a stylised
# 'CRT screen' effect on given input, specialized for raw AVI and WAV output
# from BGB Gameboy emulator.
#
# Includes basic demonstration FFmpeg command which takes "$1" input
# of video and audio files without extensions
#
# Requires:
# -FFmpeg compiled with Lensfun
#
# Version: 20210104DM
# Original source https://oioiiooixiii.blogspot.com
# Modifications made by DEFENSE MECHANISM https://defensemech.com
### FILTERCHAINS ###############################################################
# Add noise to each frame of input
noiseFX="noise=c0s=16:allf=t"
# Scale Gameboy
resize="scale=-1:720:flags=neighbor"
# Create RGB chromatic aberration
rgbFX="split=3[r][g][b];
nullsrc=size=800x720[base1];
nullsrc=size=800x720[base2];
nullsrc=size=800x720[base3];
[r]lutrgb=g=0:b=0[red];
[g]lutrgb=r=0:b=0[green];
[b]lutrgb=r=0:g=0[blue];
[base1][red]overlay=x=-2:shortest=1,format=rgb24[x];
[base2][green]overlay=x=0:shortest=1,format=rgb24[y];
[base3][blue]overlay=x=2:shortest=1,format=rgb24[z];
[x][z]blend=all_mode='addition'[xz];
[xz][y]blend=all_mode='addition',
format=gbrp"
# Create YUV chromatic aberration
yuvFX="split=3[y][u][v];
nullsrc=size=800x720[base1];
nullsrc=size=800x720[base2];
nullsrc=size=800x720[base3];
[y]lutyuv=u=0:v=0[Yaxis];
[u]lutyuv=v=0:y=0[Uaxis];
[v]lutyuv=u=0:y=0[Vaxis];
[base1][Yaxis]overlay=x=1:shortest=1[a];
[base2][Uaxis]overlay=x=0:shortest=1[b];
[base3][Vaxis]overlay=x=-1:shortest=1[c];
[a][c]blend=all_mode='lighten'[ac];
[ac][b]blend=all_mode='lighten',
crop=790:720"
# Add interlaced fields effect to input
interlaceFX="scale=-1:360,
split[a][b];
[a] eq=brightness=-0.3 [a];
[b] eq=saturation=1.5 [b];
[a][b] blend=all_expr='if(eq(0,mod(Y,2)+eq(0,Y)),B,A)':shortest=1,
scale=-1:720"
# Brighten center of screen
brighten="[base];
nullsrc=size=790x720:rate=60,
drawtext=
fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf:
text='@':
x=320:
y=270:
fontsize=270:
fontcolor=white@1.0,
boxblur=160 [gauss];
[gauss][base] blend=all_mode=screen:shortest=1"
# Curve input to mimic curve of crt screen
curveImage="
format=gbrp,
lensfun=
make=Canon:
model='Canon EOS 100D':
lens_model='Canon EF-S 18-55mm f/3.5-5.6 IS STM':
scale=1.02:
target_geometry=fisheye_stereographic:
interpolation=lanczos"
# Pad video to center
pad="scale=-1:720,pad=1280:720:180:0"
# Add bloom effect to input [crt screen]
bloomEffect="split [a][b];
[b] boxblur=12,
format=gbrp [b];
[b][a] blend=all_mode=screen:shortest=1"
### FFMPEG COMMAND #############################################################
VIDEO=$(ls | egrep "^$1.*mp4|^$1.*avi$|^$1.*mkv$" | head -n 1)
if [[ -f "$1wav" ]]; then
ffmpeg -hwaccel cuvid \
-i "$1wav" -r 60 -i "$1avi" -vcodec h264_nvenc \
-vf " ${noiseFX},
${resize},
${rgbFX},
${yuvFX},
${interlaceFX}
${brighten},
${curveImage},
${pad},
${bloomEffect}
" -b:a 384k -pix_fmt yuv420p -r 40 -preset slow ${1}_tv.mp4 -y
elif [[ -f "$VIDEO" ]]; then
ffmpeg -hwaccel cuvid \
-r 60 -i "$VIDEO" -vcodec h264_nvenc \
-vf " ${noiseFX},
${resize},
${rgbFX},
${yuvFX},
${interlaceFX}
${brighten},
${curveImage},
${pad},
${bloomEffect}
" -pix_fmt yuv420p -r 40 -preset slow ${VIDEO}_tv.mp4 -y
else
echo "Please provide a filename without extension"
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment