Skip to content

Instantly share code, notes, and snippets.

@kerbeh
Last active February 25, 2019 22:17
Show Gist options
  • Save kerbeh/980a16f64553ff78a66687b4cf344848 to your computer and use it in GitHub Desktop.
Save kerbeh/980a16f64553ff78a66687b4cf344848 to your computer and use it in GitHub Desktop.
Quick Bash script to rebuild videos from the Echo 360 ESS flash format into mp4, highly dependant on framerate so check framerate if video is out of sync
#!/bin/bash
# Process an echo export into MP4 files
# requires FFMPEG -loglevel error -hide_banner and SWFExtract
# Ensure you have swfextract http://www.swftools.org/swfextract.html installed and in your path
# Ensure you have ffmpeg installed and in your path https://www.ffmpeg.org/
# Check if SWFextarct is installed and avaliable
command -v swfextract &>/dev/null || {
echo >&2 "I require swfextract but it's not installed. Aborting."
exit 1
}
# Check if ffmpeg -loglevel error -hide_banner is installed and avaliable
command -v ffmpeg -loglevel error -hide_banner &>/dev/null || {
echo >&2 "I require FFMpeg -loglevel error -hide_banner but it's not installed. Aborting."
exit 1
}
#Assign the first input to a variable named file
file=$1
#Assign the second input to a variable named crop
crop=$2
#Assign the filename without extension to a variable named filename
filename=${file%.zip}
echo $filename
echo "Unzipping"
unzip -qq $file -d temp
screen1=FALSE
screen2=FALSE
#Check if swf style slides exist for screen 1 and extarct the JPEG slides
if [ -d "temp/${filename}_files/slides" ]; then
screen1=TRUE
#Find all swf filed in the slides directory and exrtact the full slide jpg (id 3) from the swf file
find "temp/${filename}_files/slides" -name '*.swf' -exec swfextract -j 3 {} -o {}.jpg \;
else
echo "No Screen found for $filename"
fi
#Check if swf style slides exist for screen 2 and extarct the JPEG slides
if [ -d "temp/${filename}_files/slides2" ]; then
screen2=TRUE
#Find all swf filed in the slides2 directory and exrtact the full slide jpg (id 3) from the swf file
find "temp/${filename}_files/slides2" -name '*.swf' -exec swfextract -j 3 {} -o {}.jpg \;
else
echo "No Second Screen found for $filename"
fi
if [[ $screen1 == TRUE ]]; then
#read the presentation xml file line by line to extract the timestamps for screen 1
echo "Extracting Screen 1 Slides"
slides=FALSE
echo >screen1concat
while IFS= read -r var; do
if [[ "$var" == *"<track type=\"flash-movie\" directory=\"slides\" "* ]]; then
slides=TRUE
fi
if [[ $slides == TRUE ]] && [[ "$var" != *"</track>"* ]]; then
if [[ $var =~ duration=.([0-9]{4,9})..uri=.([0-9]{4,9}) ]]; then
duration="${BASH_REMATCH[1]}"
url="${BASH_REMATCH[2]}"
echo "file temp/${filename}_files/slides/$url.swf.jpg\nduration $((duration / 1000))" >>screen1concat
fi
fi
if [[ "$var" == *"</track>"* ]]; then
slides=FALSE
fi
done \
<"temp/${filename}_files/presentation.xml"
fi
if [[ $screen2 == TRUE ]]; then
#read the presentation xml file line by line to extract the timestamps for screen 2
echo "Extracting Screen 2 Slides"
slides=FALSE
echo >screen2concat
while IFS= read -r var; do
if [[ "$var" == *"<track type=\"flash-movie\" directory=\"slides2\" "* ]]; then
slides=TRUE
fi
if [[ $slides == TRUE ]] && [[ "$var" != *"</track>"* ]]; then
if [[ $var =~ duration=.([0-9]{4,9})..uri=.([0-9]{4,9}) ]]; then
duration="${BASH_REMATCH[1]}"
url="${BASH_REMATCH[2]}"
echo "file temp/${filename}_files/slides2/$url.swf.jpg\nduration $((duration / 1000))" >>screen2concat
fi
fi
if [[ "$var" == *"</track>"* ]]; then
slides=FALSE
fi
done \
<"temp/${filename}_files/presentation.xml"
fi
#create the migration directory and join the images with FFMPEG -loglevel error -hide_banner
echo "Converting slides to MP4"
mkdir ${filename}_Migration
ffmpeg -loglevel error -hide_banner -f concat -safe 0 -i "screen1concat" -c copy ${filename}_Migration/${filename}screen1.mp4
ffmpeg -loglevel error -hide_banner -f concat -safe 0 -i "screen2concat" -c copy ${filename}_Migration/${filename}screen2.mp4
#remove the copyrightsatement from the audio and copy it to the output dir
echo "Trimming copyright statement from audio"
ffmpeg -loglevel error -hide_banner -i "temp/${filename}_files/audio.mp3" -ss 00:00:19 -c copy audio_trim.mp3
cp "audio_trim.mp3" ${filename}_Migration/${filename}audio.mp3
#combine the audio and first screen
echo "Adding audio to screen 1"
ffmpeg -loglevel error -hide_banner -i ${filename}_Migration/${filename}screen1.mp4 -i ${filename}_Migration/${filename}audio.mp3 -c:v copy -c:a copy output.mp4
cp "output.mp4" ${filename}_Migration/${filename}audio_video.mp4
#copy the presentation xml
cp temp/${filename}_files/presentation.xml ${filename}_Migration/presentation.xml
#cleanup the temp files
echo "Cleaning up temp files"
rm "audio_trim.mp3"
rm "output.mp4"
rm "screen1concat"
rm "screen2concat"
rm -rf "temp"
if [ -z "$2" ] && [ "$2" == "crop" ]; then
echo No crop requested
else
# do not reduce the loglevel for this command as need to awk the output for the crop values
cropvalue=$(ffmpeg -ss 00:23:00 -i ${filename}_Migration/${filename}audio_video.mp4 -vframes 10 -vf cropdetect=24:16:0 -f null - 2>&1 | awk '/crop/ { print $NF }' | tail -1)
IFS=':' read -r -a array <<<"$cropvalue"
width=$((array[3] + array[0]))
echo "cropping to: $cropvalue"
echo "crop=$width:${array[1]}:0:${array[3]}"
ffmpeg -loglevel error -hide_banner -i ${filename}_Migration/${filename}audio_video.mp4 -vf "crop=$width:${array[1]}:$((array[3])):${array[3]}" -c:a copy ${filename}_Migration/${filename}audio_video_croppped.mp4
fi
echo "DONE"
echo
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment