Skip to content

Instantly share code, notes, and snippets.

@ethernet8023
Last active September 30, 2016 01:26
Show Gist options
  • Select an option

  • Save ethernet8023/f90b41d2de614362b45cb796c814d3e7 to your computer and use it in GitHub Desktop.

Select an option

Save ethernet8023/f90b41d2de614362b45cb796c814d3e7 to your computer and use it in GitHub Desktop.
Gavino Scripto

splice.sh

This silly script will take two video files, and spit out a new video file with the frames of each interlaces so you can watch two movies at the same time!!! It also puts the audio from each video in one ear.

It'll probably take a ridiculously long time to generate any video file of substance, so I've uploaded a sample video of two movie trailers run through this script: https://my.mixtape.moe/qzddsq.mp4

Some useful stuff:

  • Both the videos MUST have identical framerates
  • The longer the videos, the longer it takes to generate the combined one (though that's kinda a given)
  • Similar resolutions will look the best
  • Quality might be low, that can be changed by editing the last command to change the output format for video and audio.

Usage:

  • This script requires some version of Linux, with ffmpeg and sox installed. You can install those by running sudo apt-get install ffmpeg sox.
  • Put the script in a new folder, because it creates a bunch of files.
  • Place the two video files you want to combine in that folder.
  • cd to the folder, and then run chmod +x splice.sh, then ./splice.sh video1.mov video2.mov, where video1.mov and video2.mov are the filenames of your two videos.
  • Wait (probably for a long time), and then check out combined.mp4!
  • I'm sorry (you're welcome).
#!/bin/sh
die () {
echo >&2 "$@"
exit 1
}
[ "$#" -eq 2 ] || die "2 arguments required (video1, video2), $# provided"
rm -rf video1
rm -rf video2
rm -rf combinedvideo
rm -rf audio
rm -f combined.mp4
mkdir video1
mkdir video2
mkdir combinedvideo
mkdir audio
echo "Creating a mono audio file from video 1..."
ffmpeg -i $1 -ac 1 audio/audio1.flac -hide_banner -v quiet -stats
lenAudio1=$(sox audio/audio1.flac -n stat 2>&1 | grep -E '\(seconds\):\s+[0-9]+(.[0-9]+)?' | sed 's/Length (seconds): *//g')
echo "Creating a mono audio file from video 2..."
ffmpeg -i $2 -ac 1 audio/audio2.flac -hide_banner -v quiet -stats
lenAudio2=$(sox audio/audio2.flac -n stat 2>&1 | grep -E '\(seconds\):\s+[0-9]+(.[0-9]+)?' | sed 's/Length (seconds): *//g')
result=$(awk -vn1="$lenAudio1" -vn2="$lenAudio2" 'BEGIN{print (n1>n2)?1:0 }')
if [ "$result" -eq 1 ];then
lenAudio=$lenAudio1
else
lenAudio=$lenAudio2
fi
# Get the longest of the 2 audio files' length
echo $lenAudio
samples=$(echo $lenAudio*44100 | bc)
echo "Creating a stereo audio file from both audio files..."
ffmpeg -i audio/audio1.flac -i audio/audio2.flac -filter_complex "[0]apad=whole_len=$samples[a];[1]apad=whole_len=$samples[b];[a][b]amerge=inputs=2[aout]" -map "[aout]" audio/output.wav -hide_banner -v quiet -stats
echo "Splitting video 1 into frames..."
ffmpeg -i $1 video1/frame%04d.png -hide_banner -v quiet -stats
echo "Splitting video 2 into frames..."
ffmpeg -i $2 video2/frame%04d.png -hide_banner -v quiet -stats
echo "Renaming frames from video 1..."
ls video1 | cat -n | while read n f; do mv video1/"$f" combinedvideo/frame$(printf "%04d" $(($n * 2 - 1))).png; done
echo "Renaming frames from video 2..."
ls video2 | cat -n | while read n f; do mv video2/"$f" combinedvideo/frame$(printf "%04d" $(($n * 2 ))).png; done
echo "Filling missing frames..."
cd combinedvideo
lastFrameIndex=$(ls | tail --lines=1 | tr -dc "0-9")
for nr in $(seq 1 $lastFrameIndex); do
fle=$(printf "frame%04d.png" ${nr})
if ! [ -e ${fle} ]; then
echo ${fle} "does not exist"
echo "cp $(printf "frame%04d.png" $(($nr - 1))) $fle"
cp $(printf "frame%04d.png" $(($nr - 1))) $fle
fi
done
cd ..
echo "Creating combined video file..."
fps=$(ffmpeg -i $1 -hide_banner 2>&1 | grep -Eo '[0-9]+(.[0-9]+)?\sfps' | sed 's/\sfps//')
echo "Original framerate is $fps fps"
ffmpeg -framerate $(echo $fps*2 | bc) -i combinedvideo/frame%04d.png -i audio/output.wav -c:v libx264 -c:a aac -strict experimental -b:a 192k -pix_fmt yuv420p combined.mp4 -hide_banner -v quiet -stats
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment