Created repo

main
Matt McWilliams 1 year ago
commit bde2e319bd
  1. 3
      .gitignore
  2. 222
      README.md
  3. BIN
      audio/spring.mp3
  4. 22
      bash/arguments.sh
  5. 28
      bash/cat.sh
  6. 26
      bash/functions.sh
  7. 72
      bash/ifelse.sh
  8. 50
      bash/paths.sh
  9. 33
      bash/variables.sh
  10. 23
      download.sh
  11. 28
      ffmpeg/audio/audiovideo.sh
  12. 21
      ffmpeg/audio/extract.sh
  13. 35
      ffmpeg/audio/stillaudio.sh
  14. 23
      ffmpeg/basic/info.sh
  15. 55
      ffmpeg/basic/prores.sh
  16. 61
      ffmpeg/basic/reencode.sh
  17. 74
      ffmpeg/basic/social.sh
  18. 24
      ffmpeg/basic/support.sh
  19. 24
      ffmpeg/basic/trim.sh
  20. 41
      ffmpeg/filter/bipack.sh
  21. 58
      ffmpeg/filter/bipack_steps.sh
  22. 27
      ffmpeg/filter/brightness.sh
  23. 25
      ffmpeg/filter/desaturate.sh
  24. 25
      ffmpeg/filter/grayscale.sh
  25. 25
      ffmpeg/filter/negative.sh
  26. 98
      ffmpeg/filter/title.sh
  27. 30
      ffmpeg/frames/basic.sh
  28. 41
      ffmpeg/frames/frameloom.sh
  29. 39
      ffmpeg/frames/loop.sh
  30. 53
      ffmpeg/frames/primitive.sh
  31. 42
      im/title.sh
  32. BIN
      img/mac_terminal.png
  33. BIN
      img/sonicseasonings.jpg
  34. BIN
      img/windows_10_admin.png
  35. BIN
      img/windows_10_enable.png
  36. BIN
      img/windows_10_install.png
  37. BIN
      img/windows_10_terminal.png
  38. BIN
      img/windows_10_turn_windows_features.png
  39. BIN
      img/windows_10_ubuntu.png
  40. BIN
      img/windows_10_wsl.png
  41. 84
      node/index.js
  42. 860
      node/package-lock.json
  43. 15
      node/package.json
  44. 111
      stream/capture.sh
  45. 20
      text/all.txt
  46. 1
      text/cat1.txt
  47. 7
      text/cat2.txt
  48. 9
      text/cat3.txt

3
.gitignore vendored

@ -0,0 +1,3 @@
videos
output
node/node_modules

@ -0,0 +1,222 @@
---
header-includes:
- \hypersetup{colorlinks=true,
allbordercolors={0 0 1},
pdfborderstyle={/S/U/W 1}}
---
# UNIX FOR ARTISTS
### Fun with FFMPEG
## Requirements
The following applications and runtime environments are needed to run the scripts used in the workshop.
Installation instructions are available below, broken down by operating system.
* [Bash](https://www.gnu.org/software/bash/) - *You probably have it already!*
* [FFMPEG](https://www.ffmpeg.org/)
* [ImageMagick](https://imagemagick.org/index.php)
* [Youtube-dl](https://ytdl-org.github.io/youtube-dl/index.html)
* [Golang](https://golang.org/)
* \*[Python3](https://www.python.org/downloads/) (*optional*)
* \*[Node.js](https://nodejs.org/en/) (*optional*)
It's very helpful to have a text editor that you can comfortably read and edit scripts in.
This selection of text editors ranges from free and open source to "free to use" and "free to try".
You can also use TextEdit or Notepad or any text editing application you prefer as long as it's capable of editing in plaintext.
* [Atom](https://atom.io/) - Free. *macOS, Windows and Linux.*
* [GNU Emacs](https://www.gnu.org/software/emacs/download.html) - Free. *Linux, macOS and Windows.*
* [Visual Studio Code](https://code.visualstudio.com/download) - Free. *macOS, Windows and Linux.*
* [Sublime Text 3](https://www.sublimetext.com/3) - Free to evaluate. *macOS, Windows and Linux.*
* [Notepad++](https://notepad-plus-plus.org/downloads/) - Free to use. *Windows only.*
* [BBEdit](http://www.barebones.com/products/bbedit/download.html) - Freemium. *macOS only.*
-------
## macOS
![The macOS Terminal](img/mac_terminal.png "The macOS Terminal")
Open the Terminal app located in your Applications folder.
Bash 3.2 is available by default on macOS.
##### Install Homebrew
Go to [https://brew.sh](https://brew.sh) and run the command under the "Install Homebrew" heading after pasting it into your Terminal.
You will be asked to confirm a few things while Homebrew installs.
Once the installation process is complete you can install the applications we will be using in this workshop by running the following commands:
```bash
brew install ffmpeg imagemagick youtube-dl
```
Optionally, you can install Node.js for a single example that we will be covering in the workshop.
```bash
brew install node
```
Make sure that you have a compatible version of Python installed by running the following command:
```bash
python3 --version
```
It should print out a value similar to `Python 3.8.2`.
Anything higher than 3.7.0 will work.
##### Install Golang on macOS
Go to the [Golang download site](https://golang.org/doc/install).
Select the "Mac" tab under "2. Go install." if not already selected and download the .pkg installer using the "Download Go for Mac" button.
Open the installer and follow the instructions.
Confirm that Go is installed by running the following command in Terminal:
```bash
go version
```
If Golang has been installed correctly you can now install `primitive`.
```bash
go get -u github.com/fogleman/primitive
```
-------
## Windows 10
Windows has its own command-line interpreter, but in order to keep code and examples consistent across different operating systems you will need to install the Windows Subsystem for Linux (WSL).
##### Enable WSL
Open the "Turn Windows Features on or off" dialog by searching in your command bar.
![Turn Windows features on or off](img/windows_10_turn_windows_features.png "Turn Windows features on or off")
Enable "Virtual Machine Platform" and "Windows Subsystem for Linux" by selecting the checkboxes next to the items and hit "OK".
![Enable WSL and Virtual Machine Platform](img/windows_10_enable.png "Enable WSL and Virtual Machine Platform")
Restart your computer for changes to apply.
##### Install Ubuntu 20.04 LTS
Open the Microsoft Store and search for "Ubuntu".
For the latest LTS version, install `Ubuntu 20.04`.
![Install Ubuntu 20.04](img/windows_10_install.png "Install Ubuntu 20.04 through the Microsoft Store")
Other versions of Ubuntu or openSUSE may work, but will be subject to differences in behavior.
![Select the Ubuntu shell](img/windows_10_ubuntu.png "Select the Ubuntu shell")
Once you've installed Ubuntu, you can open the shell and begin running commands using Bash.
##### Install Requirements on Windows 10
![The Ubuntu shell on Windows 10](img/windows_10_terminal.png "The Ubuntu shell on Windows 10")
You can now run the following commands to install the applications for this workshop:
```bash
sudo apt update
sudo apt install -y ffmpeg imagemagick youtube-dl
```
Optionally install Node.js.
```bash
sudo apt install -y nodejs npm
```
##### Install Golang on Windows 10
Go to the [Golang download site](https://golang.org/doc/install).
Select the "Windows" tab under "2. Go install." if not already selected and download the .msi installer by using the "Download Go for Windows" button.
Confirm that Go is installed by running the following command in your shell:
```bash
go version
```
If Golang has been installed correctly you can now install `primitive`.
```bash
go get -u github.com/fogleman/primitive
```
-------
Additional tutorials for installing Bash on Windows 10.
* [How to Install Linux Bash Shell on Windows 10](https://itsfoss.com/install-bash-on-windows/)
* [Install Bash on Windows 10](https://bayton.org/docs/linux/ubuntu/install-bash-on-windows-10-build-14316/)
-------
## Linux
Open up your preferred terminal application and install the required applications on a Debian-based system.
```bash
sudo apt install -y ffmpeg imagemagick youtube-dl
```
Or, if your distribution uses the `yum` package manager.
```bash
yum install ffmpeg imagemagick youtube-dl
```
Optionally install Node.js.
```bash
sudo apt install -y nodejs npm
```
Or using yum.
```
yum install nodejs
```
##### Install Golang on Linux
Go to the [Golang download site](https://golang.org/doc/install).
Select the "Linux" tab under "2. Go install." if not already selected and download the .tar.gz archive using the "Download Go for Linux" button.
Navigate to the folder you downloaded the archive into.
For the following commands, `go1.16.3.linux-amd64.tar.gz` can be replaced by the filename of the version that you just downloaded.
```bash
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.16.3.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin
```
Either restart your terminal or run the command `source $HOME/.profile` to apply the changes just made to your system.
Confirm that Go is installed by running the following command:
```bash
go version
```
If Golang has been correctly installed you can now install `primitive`.
```bash
go get -u github.com/fogleman/primitive
```

Binary file not shown.

@ -0,0 +1,22 @@
#!/bin/bash -e
#####################################################
#
# Arguments are provided to commands and scripts usually
# separated by a space. They can be read and used within
# bash scripts by referencing them with the "$#" notation.
#
# Usage: bash bash/arguments.sh <first> <second> <third> <etc>
#
#####################################################
echo "You entered \"$1\" as the first argument"
# Using a slightly different notation
if [ "${2}" != "" ]; then
echo "You entered \"${2}\" as the second argument"
fi
if [ "${3}" != "" ]; then
echo "All of the arguments you entered \"${@}\""
fi

@ -0,0 +1,28 @@
#!/bin/bash -e
#####################################################
#
# "cat" is an application that prints text files
# into your terminal and allows you to concatinate
# multiple files together.
#
# Usage: bash bash/cat.sh
#
#####################################################
cat "text/cat1.txt"
sleep 2
# Concatinate multiple files and print the result
cat "text/cat2.txt" "text/cat3.txt"
sleep 2
# Concatinate all files into a new file using the ">" redirect operator
cat "text/cat1.txt" "text/cat2.txt" "text/cat3.txt" > "text/all.txt"
sleep 2
# Print the contents of this file
cat bash/cat.sh

@ -0,0 +1,26 @@
#!/bin/bash -e
#####################################################
#
# Functions can be defined using the "name () {}"
# notation where the code is contained within the
# brackets. Functions receive arguments the same way
# a script does, using the "$#" notation.
#
#####################################################
myFunction () {
if [ "${1}" != "" ]; then
echo "Your first argument is \"${1}\""
else
echo "Called myFunction with no arguments"
fi
}
# Invoke your function as if it were any other command
# or application located in your $PATH.
myFunction
sleep 2
myFunction "First argument"

@ -0,0 +1,72 @@
#!/bin/bash -e
#####################################################
#
# If/else statements allow you to run select commands
# if conditions are met or if they are not.
#
# Usage: bash bash/ifelse.sh
#
#####################################################
NUMBER=3
COMPARE="Compare this string"
SUBSTRING="not"
SUBSTRING2="this"
# Evaluate whether two numbers are equal with the "-eq" operator
if [ ${NUMBER} -eq 3 ]; then
echo "Variable \$NUMBER is equal to 3"
else
echo "Variable \$NUMBER is NOT equal to 3"
fi
sleep 2
# Evaluate whether a string contains substrings. Uses the
# "elif" operator to check if a second condition is met if
# the first one fails.
if [[ "${COMPARE}" == *"${SUBSTRING}"* ]]; then
echo "String \$COMPARE contains substring \"${SUBSTRING}\""
elif [[ "${COMPARE}" == *"${SUBSTRING2}"* ]]; then
echo "String \$COMPARE contains substring \"${SUBSTRING2}\""
else
echo "String \$COMPARE contains none of the substrings"
fi
sleep 2
# Evaluate whether a file exists with the "-f" operator
if [ -f "text/cat1.txt" ]; then
echo "File text/cat1.txt exists. Here are the contents:"
cat text/cat1.txt
else
echo "File text/cat1.txt does NOT exist"
fi
sleep 2
# Evaluate whether a directory exists with the "-d" operator
if [ -d "not_here" ]; then
echo "Directory not_here exists. Here are the contents:"
ls not_here
else
echo "Directory not_here does NOT exist"
fi
# Evaluate whether or not one condition OR another
# is met using the "||" operators.
# The "-gt" operator determines if a number is
# greater than a compared number and "-lt" for
# less than.
if [ $NUMBER -gt 1 ] || [ $NUMBER -lt 5]; then
echo "Variable \$NUMBER is greater than 1 or less than 5"
fi
# Evaluate whether both conditions are met using
# the AND operator "&&"
if [[ "${COMPARE}" == *"${SUBSTRING}"* ]] && [[ "${COMPARE}" == *"${SUBSTRING2}"* ]]; then
echo "String \$COMPARE contains both substrings"
else
echo "String \$COMPARE does not contain both substrings"
fi

@ -0,0 +1,50 @@
#!/bin/bash -e
#####################################################
#
# The commands "cd",
#
# Usage: bash bash/paths.sh
#
#####################################################
THIS_DIRECTORY=`pwd`
echo "${THIS_DIRECTORY}"
sleep 2
# Go to your "home" directory for your user
cd ~/
echo "You are now in:"
pwd
sleep 2
# Go to the root of your filesystem
cd /
echo "You are now in:"
pwd
sleep 2
# List all files and directories in "long" and "readable" format
ls -lh
sleep 10
# Return to the directory you started in
cd "${THIS_DIRECTORY}"
echo "You are now back in:"
pwd
sleep 2
# Go into the "bash" sub-directory
cd bash
echo "You are now in:"
pwd
# Return to the parent directory, the one you started in,
# by using the double period ".." notation
cd ../
echo "You are now back in:"
pwd

@ -0,0 +1,33 @@
#!/bin/bash -e
#####################################################
#
# Variables are stored values that can be set locally
# in the script or inherited from your environment.
#
# Usage: bash bash/variables.sh
#
#####################################################
# Set this variable to run the script
VARIABLE=""
NUMBER=3
# Save output of the command "pwd" to a variable
# by running it in a subshell
CURRENT_DIR=`pwd`
# A different notation for subshells, this time
# saving the contents of a text file to a variable
FILE=$(cat text/cat1.txt)
if [ "${VARIABLE}" != "" ]; then
echo "Your variable: ${VARIABLE}"
echo "Your number: ${NUMBER}"
echo "Your current dir: ${CURRENT_DIR}"
# $PATH is an environment variable set by your system
echo "Your username: ${USER}"
echo "Your system \$PATH: ${PATH}"
else
echo "Please create within the quotes on line 13"
fi

@ -0,0 +1,23 @@
#!/bin/bash -e
VIDEOS=(
bear.mkv
bird.mkv
flower.mkv
ice.mkv
metamorphosis.mkv
negative.mkv
net.mkv
pig.mkv
stream.mkv
surface.mkv
water.mkv
)
mkdir -p videos
mkdir -p output
for video in ${VIDEOS[@]}; do
curl "https://sixteenmillimeter.com/unix4artists/${video}" -o "videos/${video}"
sleep 2
done

@ -0,0 +1,28 @@
#!/bin/bash -e
#####################################################
#
# This script will combine the audio from one file and the
# video from another file.
#
# Usage: bash ffmpeg/audio/audiovideo.sh <input audio> <input video> <output video>
#
#####################################################
AUDIO="${1}"
VIDEO="${2}"
OUTPUT="${3}"
# Check if output file extension is .mkv
if [[ "${OUTPUT}" != *".mkv" ]]; then
echo "Please use an .mkv extension on your output file argument"
exit 1
fi
ffmpeg -i "${VIDEO}" \
-i "${AUDIO}" \
-c copy \
-map 0:v:0 \
-map 1:a:0 \
-shortest \
"${OUTPUT}"

@ -0,0 +1,21 @@
#!/bin/bash -e
#####################################################
#
# This script will extract the audio from a video
# losslessly into a .wav file.
#
# Usage: bash ffmpeg/audio/extract.sh <input video> <output audio>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if output file extension is .wav
if [[ "${OUTPUT}" != *".wav" ]]; then
echo "Please use an .wav extension on your output file argument"
exit 1
fi
ffmpeg -i "${INPUT}" -vn "${OUTPUT}"

@ -0,0 +1,35 @@
#!/bin/bash -e
#####################################################
#
# This script will take an audio file and an image and
# combine them to create a video.
#
# Usage: bash ffmpeg/audio/stillaudio.sh <input audio> <input image> <output video>
#
#####################################################
AUDIO="${1}"
IMAGE="${2}"
OUTPUT="${3}"
# Check if file extension is .mkv or .MKV
if [[ "${OUTPUT}" != *".mkv" ]]; then
echo "Please use an .mkv extension on your output file argument"
exit 1
fi
ffmpeg -loop 1 \
-framerate 2 \
-i "${IMAGE}" \
-i "${AUDIO}" \
-c:v libx264 \
-preset slow \
-tune stillimage \
-pix_fmt yuv420p \
-crf 12 \
-vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:-1:-1:color=black" \
-c:a aac \
-b:a 192k \
-shortest \
"${OUTPUT}"

@ -0,0 +1,23 @@
#!/bin/bash -e
#####################################################
#
# "ffprobe" is an application that comes bundled with
# the ffmpeg installation. It will print file
# information about the streams within video and audio
# files.
#
# Usage: bash ffmpeg/basic/info.sh <file>
#
#####################################################
if [ "${1}" == "" ]; then
echo "Please include a path to a file as the first argument"
exit 1
fi
if [ "${2}" != "json" ]; then
ffprobe -v quiet -show_format -show_streams "${1}"
else
ffprobe -v quiet -print_format json -show_format -show_streams "${1}"
fi

@ -0,0 +1,55 @@
#!/bin/bash -e
#####################################################
#
# This command will re-encode a video into an MOV
# container with a ProRes HQ (422) video stream and
# audio preserved in its original format.
#
# -i "${INPUT}"
# Sets the first argument, saved as variable "$INPUT"
# as the input file that ffmpeg will re-encode. Must
# go at the beginning of your command.
#
# -c:v prores_ks
# Sets the video codec of the output video to be ProRes
# using the "prores_kostya" library.
#
# -profile:v 3
# Sets the ProRes profile to 3 or "HQ" use on the output
# video stream. The profiles available: 0 = proxy (PR),
# 1 = light (LT), 2 = standard (ST), 3 = high quality (HQ),
# 4 = 4444, 5 = 4444 (XQ)
#
# -c:a copy
# Copies the audio stream and preserves the format
# and codec from the original file.
#
# "${OUTPUT}"
# The output video file, which should be the last
# argument you provide.
#
# More info: https://avpres.net/FFmpeg/im_ProRes.html
# https://codecs.multimedia.cx/2012/03/a-few-words-about-my-prores-encoder/
#
# Usage: bash ffmpeg/basic/prores.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if input and output arguments are supplied
if [ "${INPUT}" == "" ] || [ "${OUTPUT}" == "" ]; then
echo "Please provide input and output files as your first and second arguments"
exit 1
fi
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 2
fi
# Command to re-encode the input video into ProRes
ffmpeg -i "${INPUT}" -c:v prores_ks -profile:v 3 -c:a copy "${OUTPUT}"

@ -0,0 +1,61 @@
#!/bin/bash -e
#####################################################
#
# This command will re-encode a video into an MP4
# container with H264 video and AAC audio encoded to
# 96K. Each of the arguments are explained as follows:
#
# -i "${INPUT}"
# Sets the first argument, saved as variable "$INPUT"
# as the input file that ffmpeg will re-encode. Must
# go at the beginning of your command.
#
# -codec:video libx264
# Sets the video codec to libx264, which is the library
# ffmpeg uses to encode H264 video streams.
#
# -preset slow
# Sets the preset of the H264 encoding process to run
# slow, which can yield higher quality imagery at the
# expense of speed. Available options:
# ultrafast, superfast, veryfast, faster, medium (default),
# slow, slower, veryslow, placebo
#
# -crf 22
# Sets the Constant Rate Factor of the video stream,
# which determines the data rate. The range of -crf
# values range from 0 to 51, with 0 being visually
# lossless and 51 being extremely compressed.
#
# -codec:audio aac
# Sets the codec of the output audio stream to AAC.
#
# -b:a
# Sets the data rate of the audio to 192kbit/s.
#
# "${OUTPUT}"
# The output video file, which should be the last
# argument you provide.
#
# Usage: bash ffmpeg/basic/reencode.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if input and output arguments are supplied
if [ "${INPUT}" == "" ] || [ "${OUTPUT}" == "" ]; then
echo "Please provide input and output files as your first and second arguments"
exit 1
fi
# Check if file extension is .mp4
if [[ "${OUTPUT}" != *".mp4" ]]; then
echo "Please use an .mp4 extension on your output file argument"
exit 2
fi
# Command to re-encode the input video into H264/AAC
ffmpeg -i "${INPUT}" -codec:video libx264 -preset slow -crf 22 -codec:audio aac -bitrate:audio 192k "${OUTPUT}"

@ -0,0 +1,74 @@
#!/bin/bash -e
#####################################################
#
# Youtube: https://trac.ffmpeg.org/wiki/Encode/YouTube
# Vimeo: https://vimeo.zendesk.com/hc/en-us/articles/360056550451-Video-and-audio-compression-guidelines
#
# Usage: bash ffmpeg/basic/social.sh <input video>
#
#####################################################
INPUT=`realpath "${1}"`
FILENAME=`basename "${INPUT}"`
FILE="${FILENAME%.*}"
INPUTDIR=`dirname "${INPUT}"`
if [ "${INPUT}" == "" ]; then
echo "Please provide an input video as your first argument"
exit 1
fi
YOUTUBE="${INPUTDIR}/${FILE}-youtube.mkv"
VIMEO="${INPUTDIR}/${FILE}-vimeo.mkv"
TWITTER="${INPUTDIR}/${FILE}-twitter.mp4"
INSTAGRAM="${INPUTDIR}/${FILE}-instagram.mp4"
# Encode a video for YouTube
ffmpeg -i "${INPUT}" \
-vcodec libx264 \
-preset slow \
-vf "pad=ceil(iw/2)*2:ceil(ih/2)*2" \
-pix_fmt yuv420p \
-crf 12 \
-c:a aac \
-b:a 192k \
"${YOUTUBE}"
# Encode a video for Vimeo using the
# recommended settings for 720p video
ffmpeg -i "${INPUT}" \
-vcodec libx264 \
-preset slow \
-pix_fmt yuv420p \
-profile:v main \
-b:v 7500k \
-minrate 5000k \
-maxrate 10000k \
-c:a aac \
-ar 48000 \
"${VIMEO}"
# Encode video for Twitter
ffmpeg -i "${INPUT}" \
-pix_fmt yuv420p \
-vcodec libx264 \
-acodec aac \
-vb 2048k\
-minrate 1024k \
-maxrate 4096k \
-bufsize 1024k \
-ar 44100 \
-ac 2 \
-strict experimental \
"${TWITTER}"
# Crop and encode for Instagram
ffmpeg -i "${INPUT}" \
-vf "crop=w='min(iw\,ih)':h='min(iw\,ih)',setsar=1" \
-framerate 30 \
-vcodec mpeg4 \
-vb 8000k \
-strict experimental \
-q:v 0 \
"${INSTAGRAM}"

@ -0,0 +1,24 @@
#!/bin/bash -e
#####################################################
#
# These commands print out the formats and codecs that
# your installation of ffmpeg supports. You can customize
# ffmpeg to support additional formats, codecs and features
# by using installation options or flags when compiling
# from source.
#
# Mac (Homebrew): https://gist.github.com/Piasy/b5dfd5c048eb69d1b91719988c0325d8
# Linux & Windows: https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
#
# Usage: bash ffmpeg/format/support.sh
#
#####################################################
echo "Formats your FFMPEG install supports:"
ffmpeg -formats
sleep 10
echo "Codecs your FFMPEG install supports:"
ffmpeg -codecs

@ -0,0 +1,24 @@
#!/bin/bash -e
#####################################################
#
# This script will trim your video to a 5 second length
# starting 2 seconds into it and write the output as a
# ProRes video file.
#
# Usage: bash ffmpeg/basic/trim.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 2
fi
# Trim the video using the "-t" argument with the value 5 (seconds)
# and starting at 00:00:02 (h:m:s) using the "-ss" seeking argument
ffmpeg -ss 00:00:02 -i "${INPUT}" -t 5 -c:v prores_ks -profile:v 3 -c:a copy "${OUTPUT}"

@ -0,0 +1,41 @@
#!/bin/bash -e
#####################################################
#
# Bipack.sh will simulate the optical printing effect
# of superimposing video A over video B with a third
# video (the matte) as the alpha layer.
#
# Usage: bash ffmpeg/filter/bipack.sh <input video A> <input video B> <input video matte> <output video>
#
#####################################################
A=${1}
B=${2}
MATTE=${3}
OUTPUT_FILE=${4}
CONTRAST=100
W=1280
H=720
RATE=24
echo "Running bipack on image sources ${A} and ${B} with ${MATTE} as the matte layer..."
time ffmpeg -y -i $A -i $B -i $MATTE \
-filter_complex "
color=0x000000:size=${W}x${H}, format=rgb24[bla];
[0] fps=${RATE},scale=${W}:${H}:force_original_aspect_ratio=decrease,format=rgb24 [a];
[1] fps=${RATE},scale=${W}:${H}:force_original_aspect_ratio=decrease,format=rgb24 [b];
[2] fps=${RATE},scale=${W}:${H}:force_original_aspect_ratio=decrease,format=gray,
smartblur=1, eq=contrast=$CONTRAST, format=rgb24 [maska];
[2] fps=${RATE},scale=${W}:${H}:force_original_aspect_ratio=decrease,format=gray,
smartblur=1, eq=contrast=$CONTRAST, negate, format=rgb24 [maskb];
[bla][a][maska] maskedmerge, format=rgb24 [pass1];
[pass1][b][maskb] maskedmerge, format=rgb24
" \
-r $RATE \
-c:v prores_ks \
-profile:v 3 \
-shortest \
$OUTPUT_FILE

@ -0,0 +1,58 @@
#!/bin/bash
set -e
W=1280
H=720
A=${1}
B=${2}
MATTE=${3}
OUTPUT=${4}
MATTE1=matte1.mov
MATTE2=matte2.mov
PASS1=pass1.mov
PASS2=pass2.mov
echo "Generating mattes from $MATTE..."
ffmpeg -y -i "$MATTE" -vf eq=saturation=0:contrast=100,smartblur=1 -c:v prores_ks -profile:v 4 "$MATTE1"
ffmpeg -y -i "$MATTE1" -vf negate -c:v prores_ks -profile:v 4 "$MATTE2"
echo "Applying matte to $A..."
ffmpeg -y -i "$A" -i "$MATTE1" \
-filter_complex 'color=0x000000:size=1280x720,format=rgb24[bla];[bla][0][1]maskedmerge' \
-c:v prores_ks \
-profile:v 4 \
-shortest \
"$PASS1"
echo "Applying matte to $B..."
ffmpeg -y -i "$B" -i "$MATTE2" \
-filter_complex 'color=0x000000:size=1280x720,format=rgb24[bla];[bla][0][1]maskedmerge' \
-c:v prores_ks \
-profile:v 4 \
-shortest \
"$PASS2"
echo "Cleaning up tmp matte files..."
rm "$MATTE1"
rm "$MATTE2"
echo "Combining matted layers together into $OUTPUT_FILE..."
ffmpeg -y -i "$PASS1" -i "$PASS2" \
-filter_complex "[0][1]blend=all_mode='lighten'" \
-c:v prores_ks \
-profile:v 3 \
-shortest \
"$OUTPUT"
echo "Cleaning up temp files..."
rm "$PASS1"
rm "$PASS2"

@ -0,0 +1,27 @@
#!/bin/bash -e
#####################################################
#
# This script will increase the contrast of an input
# video by 2 (acceptable values -1000 to 1000) and
# increases the brightness by 0.4 (-1 to 1)
#
# Usage: bash ffmpeg/filter/brightness.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
ffmpeg -i "${INPUT}" \
-vf eq=contrast=2:brightness=0.4 \
-c:v prores_ks \
-profile:v 3 \
"${OUTPUT}"

@ -0,0 +1,25 @@
#!/bin/bash -e
#####################################################
#
# This script will convert a color video to black &
# white by reducing color saturation to 0.
#
# Usage: bash ffmpeg/filter/desaturate.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
ffmpeg -i "${INPUT}" \
-vf hue=s=0 \
-c:v prores_ks \
-profile:v 3 \
"${OUTPUT}"

@ -0,0 +1,25 @@
#!/bin/bash -e
#####################################################
#
# This script will convert a color video to black &
# white by converting to grayscale format.
#
# Usage: bash ffmpeg/filter/grayscale.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
ffmpeg -i "${INPUT}" \
-vf format=gray \
-c:v prores_ks \
-profile:v 3 \
"${OUTPUT}"

@ -0,0 +1,25 @@
#!/bin/bash -e
#####################################################
#
# This script will invert all colors of a video and
# save the output in a ProRes video.
#
# Usage: bash ffmpeg/filter/negative.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
ffmpeg -i "${INPUT}" \
-vf negate \
-c:v prores_ks \
-profile:v 3 \
"${OUTPUT}"

@ -0,0 +1,98 @@
#!/bin/bash -e
#####################################################
#
# This script will create a 10 second title and
# overlay it on a video with a blend mode:
#
# addition
# grainmerge
# and
# average
# darken
# difference
# grainextract
# divide
# dodge
# freeze
# exlusion
# extremity
# glow
# hardlight
# hardmix
# heat
# lighten
# linearlight
# multiply
# multiply128
# negation
# normal
# or
# overlay
# pheonix
# pinlight
# reflect
# screen
# softlight
# subtract
# vividlight
# xor
#
# Usage: bash ffmpeg/filter/title.sh <title text> <input video> <output video> <blendmode> "invert" (optional)
#
#####################################################
W=720
H=480
TEXT="${1}"
INPUT="${2}"
OUTPUT="${3}"
BLENDMODE="${4}"
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
if [ "${BLENDMODE}" == "" ]; then
BLENDMODE="multiply"
fi
if [ "${5}" == "invert" ]; then
convert -size ${W}x${H} \
-background white \
-fill black \
-gravity Center \
-weight 700 \
-pointsize 100 \
label:"${TEXT}" \
title.png
else
convert -size ${W}x${H} \
-background black \
-fill white \
-gravity Center \
-weight 700 \
-pointsize 100 \
label:"${TEXT}" \
title.png
fi
ffmpeg -y -loop 1 \
-framerate 24 \
-f image2 \
-i title.png \
-s ${W}x${H} \
-c:v prores_ks \
-profile:v 3 \
-t 10 \
"title.mov"
ffmpeg -i "${INPUT}" -i "title.mov" -filter_complex "[0][1]blend=${BLENDMODE}" "${OUTPUT}"
# Clean up by removing the image and title video
rm title.png
rm title.mov

@ -0,0 +1,30 @@
#!/bin/bash -e
#####################################################
#
# This script splits a video into an image sequence
# and then stitches the image sequence back into a
# ProRes video.
#
# Usage: bash ffmpeg/frames/basic.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
mkdir -p frames
ffmpeg -i "${INPUT}" frames/frame-%06d.png
sleep 20
ffmpeg -f image2 -i frames/frame-%06d.png -c:v prores_ks -profile:v 3 "${OUTPUT}"
rm -rf frames

@ -0,0 +1,41 @@
#!/bin/bash -e
#####################################################
#
# Frameloom is a script that exports all frames from
# two videos and alternates them in
#
# Usage: bash ffmpeg/frames/frameloom.sh <input video1> <input video2> <output video>
#
#####################################################
TMPDIR=`mktemp -d`
i=0
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] ;
then
echo "Not enough arguments supplied"
fi
# Check if output file extension is .mov
if [[ "${3}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
mkdir -p $TMPDIR
ffmpeg -i "$1" -compression_algo raw -pix_fmt rgb24 "${TMPDIR}export-%08d_a.tif"
ffmpeg -i "$2" -compression_algo raw -pix_fmt rgb24 "${TMPDIR}export-%08d_b.tif"
#rm -r $TMP
for filename in ${TMPDIR}*.tif; do
value=`printf %08d $i`
mv "$filename" "${TMPDIR}render_${value}.tif"
i=`expr $i + 1`
done
ffmpeg -r 24 -f image2 -s 1280x720 -i "${TMPDIR}render_%08d.tif" -c:v prores_ks -profile:v 3 -y "$3"
rm -r "$TMPDIR"

@ -0,0 +1,39 @@
#!/bin/bash -e
#####################################################
#
# This script exports all frames of your video into
# a directory named "frames" and then runs a convert
# command which does edge detection on each frame.
# Then all frames are stitched back into a ProRes
# video.
#
# Usage: bash ffmpeg/frames/loop.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
mkdir -p frames
ffmpeg -i "${INPUT}" frames/frame-%06d.png
FRAMES=frames/*.png
for frame in ${FRAMES}; do
echo "Running edge detection on $frame..."
convert "${frame}" -edge 1 "${frame}"
done
sleep 10
ffmpeg -f image2 -i frames/frame-%06d.png -c:v prores_ks -profile:v 3 "${OUTPUT}"
rm -rf frames

@ -0,0 +1,53 @@
#!/bin/bash -e
#####################################################
#
# This script will export your video to frames and
# use the application "primitive" to reproduce the
# image with polygonal primitive shapes. Then the
# converted frames are p
#
# The modes available for the -m argument are:
# 0=combo
# 1=triangle
# 2=rect
# 3=ellipse
# 4=circle
# 5=rotatedrect
# 6=beziers
# 7=rotatedellipse
# 8=polygon
#
# primitive repo : https://github.com/fogleman/primitive
#
# Usage: bash ffmpeg/frames/primitive.sh <input video> <output video>
#
#####################################################
INPUT="${1}"
OUTPUT="${2}"
MODE=1
NUMBER=100
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
mkdir -p frames
ffmpeg -i "${INPUT}" frames/frame-%06d.png
FRAMES=frames/*.png
for frame in ${FRAMES}; do
echo "Processing $frame with primitive..."
# Run the "primitive" application on every frame
primitive -i "${frame}" -o "${frame}" -n 200 -m 4
done
ffmpeg -f image2 -i frames/frame-%06d.png -c:v prores_ks -profile:v 3 "${OUTPUT}"
rm -rf frames

@ -0,0 +1,42 @@
#!/bin/bash -e
#####################################################
#
# This script will create a 15 second title with a
# 5 second fade in and a 5 second fade out
#
# Usage: bash im/title.sh <title text> <output video>
#
#####################################################
TEXT="${1}"
OUTPUT="${2}"
# Check if output file extension is .mov
if [[ "${OUTPUT}" != *".mov" ]]; then
echo "Please use an .mov extension on your output file argument"
exit 1
fi
convert -size 1280x720 \
-background black \
-fill white \
-gravity Center \
-weight 700 \
-pointsize 200 \
label:"${TEXT}" \
title.png
ffmpeg -loop 1 \
-framerate 24 \
-f image2 \
-i title.png \
-s 1280x720 \
-vf "fade=t=in:st=0:d=5,fade=t=out:st=10:d=5" \
-c:v prores_ks \
-profile:v 3 \
-t 15 \
"${OUTPUT}"
# Clean up by removing the image
rm title.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

@ -0,0 +1,84 @@
'use strict';
const PORT = typeof process.env.PORT !== 'undefined' ? parseInt(process.env.PORT) : 3000;
const express = require('express');
const bodyParser = require('body-parser');
const { execSync } = require('child_process');
const app = express();
const HOME = `<html>
<head><title>FFMPEG demo</title></head>
<body>
<form method="POST">
<input name="title" />
<input type="submit" />
</form>
</body>
</html>`;
const VIDEO = `<html>
<head><title>FFMPEG demo</title></head>
<body>
<video controls autoplay>
<source src="/title.mp4" type="video/mp4" />
</video>
</body>
</html>`
function generateTitle (text) {
const title = `convert \
-size 720x480 \
-background black \
-fill white \
-gravity Center \
-weight 700 \
-pointsize 100 \
label:"${text}" \
title.png`;
const ffmpeg = `ffmpeg -y \
-loop 1 \
-framerate 24 \
-f image2 \
-i title.png \
-s 720x480 \
-vf "fade=t=in:st=0:d=5,fade=t=out:st=10:d=5" \
-c:v libx264 \
-preset slow \
-crf 22 \
-f mp4 \
-strict -2 \
-pix_fmt yuv420p \
-t 15 \
-an \
title.mp4`;
const cleanup = `rm title.png`;
execSync(title);
execSync(ffmpeg);
execSync(cleanup);
}
app.use(express.static('./'));
app.use(bodyParser.urlencoded({ extended : true }));
app.get('/', (req, res, next) => {
res.end(HOME);
return next();
});
app.post('/', (req, res, next) => {
generateTitle(req.body.title);
res.end(VIDEO);
return next();
});