Skip to content

Commit

Permalink
Add debugging output to export-moving-image-frames.sh
Browse files Browse the repository at this point in the history
Add app to docker-compose.yaml

move moving images testdata

Mount scripts folder into sipi for local dev purposed

Introduce $DEBUG for the export script as a way to turn on debug out

extract printSeperator function

declare function with function keyword

formatting - use spaces instead of tabs akin to scala source code

fix mimetype check being skipped/failing

Failed with
+ file -b --mime-type ./1.mp4 -ne video/mp4
Usage: file [-bcCdEhikLlNnprsSvzZ0] [--apple] [--extension] [--mime-encoding]
            [--mime-type] [-e <testname>] [-F <separator>]  [-f <namefile>]
            [-m <magicfiles>] [-P <parameter=value>] <file> ...
       file -C [-m <magicfiles>]
       file [--help]

comments

use double in order to prevent globbing and word splitting

remove unused function collect

remove unused num variable

formatting

fix typo in frame_rate variable name

fix warning for read without -r
https://github.com/koalaman/shellcheck/wiki/SC2162

Remove unused framestart variable

use double quote

simplify calculation and rename number_of_frame_files

Fix rounding error in calculation of number of matrix files to created

fix processing of very short moving images

start extracting keyframes at time unit 0, i.e. the beginning of the file and use the first extract frame as the start of the matrix

Remove big binary test data
  • Loading branch information
seakayone committed Nov 24, 2022
1 parent 93179d5 commit 210d5cf
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 101 deletions.
1 change: 1 addition & 0 deletions docker-compose.yml
Expand Up @@ -33,6 +33,7 @@ services:
- ${LOCAL_HOME}/sipi/config:/sipi/config:delegated
- ${LOCAL_HOME}/sipi/images:/sipi/images:delegated
- ${LOCAL_HOME}/sipi/server:/sipi/server:delegated
- ${LOCAL_HOME}/sipi/scripts:/sipi/scripts:delegated
networks:
- knora-net
environment:
Expand Down
182 changes: 81 additions & 101 deletions sipi/scripts/export-moving-image-frames.sh
Expand Up @@ -7,98 +7,75 @@
# - max. 36 frames per matrix
# - one matrix file corresponds to 6 minutes of film

set -e

dir=$(pwd)
sep='---------------------------------'
if [ "${DEBUG:false}" == true ]; then
set -ex
else
set -e
fi

die() {
echo >&2 "$@"
exit 1
function printSeparator() {
echo "---------------------------------"
}

usage() {
echo "usage: <command> -i [infile]>"
echo ${sep}
echo "-i = Inpute file"
echo ${sep}
function die() {
echo >&2 "$@"
exit 1
}

collect() {
film=''
cnt=1
#for b in `ls`; do
for file in *.$1; do
[ -f ${file} ]
name=$2

for c in ${cnt}; do
if [ "$film" == '' ] || [ "$film" == 'VIDEO_TS.VOB' ]; then
film=${file}
else
case $3 in
true) film="$film|$file" ;;
esac
fi
done
cnt=$(expr ${cnt} + 1)
done
needle="|"
num=$(grep -o "$needle" <<<"$film" | wc -l)
num=$(expr ${num} + 1)
function usage() {
echo "usage: <command> -i [infile]>"
printSeparator
echo "-i = Inpute file"
printSeparator
}

# default variables
# current directory
dir=$(pwd)
# name of the input file for which the keyframes should be extracted
infile=''

# alternative to get some information from the source file:
# ffprobe -v quiet -print_format json -show_format -show_streams ~/sourceFile.mov

while getopts ':i:' OPTION; do
case ${OPTION} in
i) infile=$OPTARG ;;
*) echo 'Unknown Parameter' ;;
esac
case ${OPTION} in
i) infile=$OPTARG ;;
*) echo 'Unknown Parameter' ;;
esac
done

if [ $# -eq 0 ]; then
usage
die ''
usage
die ''
fi

# check the arguments: if they exist
num='^[0-9]+$'

# infile must be given and has to be an mp4
# infile must be given and has to be an mp4 by checking if mime-type is video/mp4
if [ -z "${infile}" ]; then
# must be given
usage
die "ERROR: The Input File (-i) is missing"
# must be given
usage
die "ERROR: The Input File (-i) is missing"
fi

# check if mime-type is video/mp4
if file -b --mime-type "${infile}" -ne "video/mp4"; then
die "ERROR: The Input File (-i) is not mp4"
if [ "$(file -b --mime-type "${infile}")" != "video/mp4" ]; then
die "ERROR: The Input File (-i) is not mp4"
fi

# get the right output path, the file and the filename (without extension)
dir=$(dirname "${infile}")
file=$(basename "${infile}")
name="${file%.*}"

cd $dir
cd "${dir}"

# --
# store the frames and matrix files in specific folder;
# folder has same unique name as the uploaded file
mkdir -p $name
cd $name
mkdir -p "${name}"
cd "${name}"

# --
# read frame rate from input file
framerate=$(ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate ../"${file}")
frame_rate=$(ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate ../"${file}")

IFS="/" read -a array <<<"$framerate"
IFS="/" read -ra array <<<"$frame_rate"
numerator="${array[0]}"
denumerator="${array[1]}"

Expand All @@ -110,35 +87,35 @@ aspect=$(ffprobe -v error -select_streams v:0 -show_entries stream=display_aspec

# if aspect ratio does not exist in video file metadata
if [ ! -z {$aspect} ]; then
# get aspect ratio from video dimension (width and height)
aspectW=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of csv=s=x:p=0 ../"${file}")
aspectH=$(ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=s=x:p=0 ../"${file}")
else
IFS=':' read -a array <<<"$aspect"
aspectW="${array[0]}"
aspectH="${array[1]}"
# get aspect ratio from video dimension (width and height)
aspectW=$(ffprobe -v error -select_streams v:0 -show_entries stream=width -of csv=s=x:p=0 ../"${file}")
aspectH=$(ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=s=x:p=0 ../"${file}")
else
IFS=':' read -a array <<<"$aspect"
aspectW="${array[0]}"
aspectH="${array[1]}"
fi

# --
# framesize
# calculate frame width, height and size
framewidth='256'
frameheight=$(($framewidth * $aspectH / $aspectW))
framesize=${framewidth}'x'${frameheight}

echo ${sep}
# --
printSeparator
echo 'Start with frame export'
# check the outpath for the frames;
# if exists, delete it and create new
if [ -d "frames" ]; then
rm -rf ./frames
rm -rf ./frames
fi
mkdir -p 'frames'

framestart=$(echo ${start} + 1 | bc)
ffmpeg -i ../${file} -an -ss 1 -f image2 -s ${framesize} -vf framestep=${fps} frames/${name}'_f_%d.jpg' 2>&1
ffmpeg -i ../"${file}" -an -ss 0 -f image2 -s ${framesize} -vf framestep="${fps}" frames/"${name}"'_f_%d.jpg' 2>&1

echo 'Done'
echo ${sep}
printSeparator

# --
# create the matrix files
Expand All @@ -147,15 +124,14 @@ echo 'Start with creating matrix file'
# change directory frames
cd frames
# Get the number of files: one image = one second of movie
# numfiles is equivalent to the movie duration (in seconds)
numfiles=(*)
numfiles=${#numfiles[@]}
# number_of_frame_files is equivalent to the movie duration (in seconds)
readonly number_of_frame_files=$(find . -type f | wc -l)

image="${name}_f_1.jpg"

# check if file exists
if [[ ! -f "${image}" ]]; then
die "File not found: ${image}"
die "File not found: ${image}"
fi

# grab the identify string, make sure it succeeded
Expand All @@ -179,38 +155,42 @@ frame_height=$(echo "scale=0; ${matrix_height}/6" | bc)
frame_size="${frame_width}x${frame_height}"
# get every 10th image; start with the image number 5;
# how many matrixes will it produce?
calcmatrix=$(echo "scale=4; (${numfiles}/10)/36" | bc)
calcmatrix=$(echo "scale=4; (${number_of_frame_files}/10)/36" | bc)
# Round the exact fraction to the to the next highest integer
# for the number of matrix files to create 'nummatrix'
readonly interim=$(echo "${calcmatrix}+1"|bc)
readonly nummatrix=${interim%.*}

echo '#Matrix (calculated) '${calcmatrix}
nummatrix=$(echo ${calcmatrix} | awk '{printf("%.0f\n",$1 + 0.75)}')
echo '#Matrix (rounded) '${nummatrix}

t=0
while [ ${t} -lt ${nummatrix} ]; do
echo 'Matrix nr '${t}
firstframe=$(echo "scale=0; ${t}*360+5" | bc)
MATRIX=$(find *_${firstframe}.jpg)' '

c=1
while [ ${c} -lt 36 ]; do
sec=$(echo "scale=0; ${firstframe}+(${c}*10)" | bc)
if [ $sec -lt $numfiles ]; then
img="${name}_f_${sec}.jpg"
if [ -f ${img} ]; then
MATRIX+=${img}' '
fi
fi

let c=c+1
done

# here we make the montage of every matrix file
# montage -size 320x180 DB_4_5.jpg DB_4_15.jpg DB_4_25.jpg DB_4_35.jpg -geometry +0+0 montage1.jpg
# $(echo "montage -size ${matrix_size} ${MATRIX} -tile 6x6 -geometry +0+0 -resize ${frame_size} ../matrix/${name}'_m_'${t}'.jpg'")
montage -size ${matrix_size} ${MATRIX} -tile 6x6 -geometry +0+0 -resize ${frame_size} ../${name}'_m_'${t}'.jpg' 2>&1

let t=t+1
echo 'Matrix nr '${t}
firstframe=$(echo "scale=0; ${t}*360+1" | bc)
MATRIX=$(find *_${firstframe}.jpg)' '

c=1
while [ ${c} -lt 36 ]; do
sec=$(echo "scale=0; ${firstframe}+(${c}*10)" | bc)
if [ $sec -lt $number_of_frame_files ]; then
img="${name}_f_${sec}.jpg"
if [ -f ${img} ]; then
MATRIX+=${img}' '
fi
fi

let c=c+1
done

# here we make the montage of every matrix file
# montage -size 320x180 DB_4_5.jpg DB_4_15.jpg DB_4_25.jpg DB_4_35.jpg -geometry +0+0 montage1.jpg
# $(echo "montage -size ${matrix_size} ${MATRIX} -tile 6x6 -geometry +0+0 -resize ${frame_size} ../matrix/${name}'_m_'${t}'.jpg'")
montage -size ${matrix_size} ${MATRIX} -tile 6x6 -geometry +0+0 -resize ${frame_size} ../${name}'_m_'${t}'.jpg' 2>&1

let t=t+1

done

echo 'Done'
echo ${sep}
printSeparator

0 comments on commit 210d5cf

Please sign in to comment.