New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(sipi): upload video support (DEV-771 / DEV-207) #1952
Changes from all commits
36f5732
ee0fd34
69a1431
c0e3f0f
c55908d
5e715c4
7b20d30
5ba618f
5191657
0358166
afd5b01
0c18ee1
008950a
2f66142
808d38b
2352752
c50d795
2020085
7e145dc
ae089bc
f769858
379f39f
d3c8919
200bbb4
a4d0aa0
c08af16
6546197
34cecad
2b8975f
55e792d
d4c9656
e113e5a
383da6a
c1fb6f2
67fadd6
dc809d4
841fa28
18e514a
bf78ac5
cc77e23
b518632
c1e7ab8
b5ea2d2
e578bee
02412c9
bc704e3
3e8f588
60f7cec
0a7dab5
fe87c1c
9d6781b
5a7f056
3b8d6df
ef47752
4ab6d5e
cf231cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1195,11 +1195,9 @@ | |
|
||
:fps rdf:type owl:DatatypeProperty ; | ||
|
||
rdfs:label "Frames per second"@en ; | ||
|
||
rdfs:subPropertyOf :valueHas ; | ||
|
||
:subjectClassConstraint :MovingImageFileValue ; | ||
:subjectClassConstraint :FileValue ; | ||
Comment on lines
-1202
to
+1200
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why was this changed? IMO, fps should only exist on moving images, not generally on files There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think @subotic changed it. Because we no longer store the necessary moving image metadata such as width, height, duration and fps in the database. We get this information from the sidecar file from sipi. |
||
|
||
:objectDatatypeConstraint xsd:decimal . | ||
|
||
|
@@ -2183,23 +2181,7 @@ | |
|
||
:MovingImageFileValue rdf:type owl:Class ; | ||
|
||
rdfs:subClassOf :FileValue , | ||
[ rdf:type owl:Restriction ; | ||
owl:onProperty :dimX ; | ||
owl:cardinality "1"^^xsd:nonNegativeInteger | ||
] , | ||
[ rdf:type owl:Restriction ; | ||
owl:onProperty :dimY ; | ||
owl:cardinality "1"^^xsd:nonNegativeInteger | ||
] , | ||
[ rdf:type owl:Restriction ; | ||
owl:onProperty :fps ; | ||
owl:maxCardinality "1"^^xsd:nonNegativeInteger | ||
] , | ||
[ rdf:type owl:Restriction ; | ||
owl:onProperty :duration ; | ||
owl:maxCardinality "1"^^xsd:nonNegativeInteger | ||
] ; | ||
rdfs:subClassOf :FileValue ; | ||
|
||
rdfs:comment "Represents a moving image file"@en . | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
#!/bin/bash | ||
|
||
# Export moving image frames for preview in search results and on timeline | ||
# Extract frames from mp4 file: | ||
# - 6 frames per minute | ||
# Create matrix file: | ||
# - max. 36 frames per matrix | ||
# - one matrix file corresponds to 6 minutes of film | ||
|
||
set -e | ||
|
||
dir=$(pwd) | ||
sep='---------------------------------' | ||
|
||
die() { | ||
echo >&2 "$@" | ||
exit 1 | ||
} | ||
|
||
usage() { | ||
echo "usage: <command> -i [infile]>" | ||
echo ${sep} | ||
echo "-i = Inpute file" | ||
echo ${sep} | ||
} | ||
|
||
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) | ||
} | ||
|
||
# default variables | ||
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 | ||
done | ||
|
||
if [ $# -eq 0 ]; then | ||
usage | ||
die '' | ||
fi | ||
|
||
# check the arguments: if they exist | ||
num='^[0-9]+$' | ||
|
||
# infile must be given and has to be an mp4 | ||
if [ -z "${infile}" ]; then | ||
# 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" | ||
fi | ||
|
||
# get the right output path, the file and the filename (without extension) | ||
dir=$(dirname "${infile}") | ||
file=$(basename "${infile}") | ||
name="${file%.*}" | ||
|
||
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 | ||
|
||
# -- | ||
# 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}") | ||
|
||
IFS="/" read -a array <<<"$framerate" | ||
numerator="${array[0]}" | ||
denumerator="${array[1]}" | ||
|
||
fps=$(expr "scale=2;${numerator}/${denumerator}" | bc) | ||
|
||
# -- | ||
# read aspect ratio from input file | ||
aspect=$(ffprobe -v error -select_streams v:0 -show_entries stream=display_aspect_ratio -of csv=s=x:p=0 ../"${file}") | ||
|
||
echo $aspect | ||
|
||
# -- | ||
# split the aspect ratio to have two separated numbers for calculating | ||
IFS=':' read -a array <<<"$aspect" | ||
aspectW="${array[0]}" | ||
aspectH="${array[1]}" | ||
|
||
# -- | ||
# framesize | ||
framewidth='256' | ||
frameheight=$(($framewidth * $aspectH / $aspectW)) | ||
framesize=${framewidth}'x'${frameheight} | ||
|
||
echo ${sep} | ||
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 | ||
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 | ||
|
||
echo 'Done' | ||
echo ${sep} | ||
|
||
# -- | ||
# create the matrix files | ||
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[@]} | ||
|
||
image="${name}_f_1.jpg" | ||
|
||
# check if file exists | ||
if [[ ! -f "${image}" ]]; then | ||
die "File not found: ${image}" | ||
fi | ||
|
||
# grab the identify string, make sure it succeeded | ||
# IMG_CHARS=$(identify "${image}" 2> /dev/null) || die "${image} is not a proper image" | ||
# grab width and height | ||
IMG_CHARS=$(echo "${IMG_CHARS}" | sed -n 's/\(^.*\)\ \([0-9]*\)x\([0-9]*\)\ \(.*$\)/\2 \3/p') | ||
|
||
width=$(echo "${IMG_CHARS}" | awk '{print $1}') | ||
height=$(echo "${IMG_CHARS}" | awk '{print $2}') | ||
|
||
ar=$(echo "scale=6; ${width}/${height}" | bc) | ||
# width for the whole output matrix image: 960px | ||
# so one preview image has a width of 160px | ||
# calculate the height for the output matrix image form the aspect ratio | ||
matrix_width="960" | ||
matrix_height=$(echo "scale=0; ${matrix_width}/${ar}" | bc) | ||
matrix_size="${matrix_width}x${matrix_height}" | ||
|
||
frame_width="160" | ||
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) | ||
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 | ||
|
||
done | ||
|
||
echo 'Done' | ||
echo ${sep} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we shouldn't ignore all things here, and explicitly un-ignore what we want to have?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we define it in a separate task. Because for me it's not clear, which folder should be kept and maybe it has to be discussed.