Skip to content
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

Merged
merged 56 commits into from Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
36f5732
feat(sipi): upload video
kilchenmann Nov 5, 2021
ee0fd34
Merge branch 'main' into wip/dev-25-upload-video-support
kilchenmann Nov 10, 2021
69a1431
feat(sipi): upload video
kilchenmann Nov 15, 2021
c0e3f0f
feat(sipi): upload video
kilchenmann Nov 15, 2021
c55908d
Merge branch 'main' into wip/dev-25-upload-video-support
kilchenmann Nov 15, 2021
5e715c4
build: bump sipi version to one with updated knora.json
subotic Nov 29, 2021
7b20d30
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Nov 29, 2021
5ba618f
build: bump testcontainers
subotic Nov 29, 2021
5191657
Merge branch 'wip/dev-25-upload-video-support' of https://github.com/…
kilchenmann Nov 29, 2021
0358166
feat(sipi): add shell lua
kilchenmann Nov 30, 2021
afd5b01
feat(sipi): store video
kilchenmann Nov 30, 2021
0c18ee1
feat(sipi): support video upload
kilchenmann Nov 30, 2021
008950a
test: activate for video representation
subotic Nov 30, 2021
2f66142
test: add debugging output
subotic Nov 30, 2021
808d38b
build: fix missing env file
subotic Dec 1, 2021
2352752
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Dec 1, 2021
c50d795
refactor(sipi): restore store.lua script
kilchenmann Dec 2, 2021
2020085
feat(sipi): support video upload
kilchenmann Dec 2, 2021
7e145dc
Merge branch 'wip/dev-25-upload-video-support' of https://github.com/…
kilchenmann Dec 2, 2021
ae089bc
refactor(sipi): restore store.lua script
kilchenmann Dec 2, 2021
f769858
refactor(sipi): clean up video upload
kilchenmann Dec 2, 2021
379f39f
build: add new sipi version with knora.info video support
subotic Dec 3, 2021
d3c8919
chore(sipi): hardcoded fps in case of video
kilchenmann Dec 9, 2021
200bbb4
chore(deps): update sipi
kilchenmann Dec 10, 2021
a4d0aa0
feat(upload): more on video upload
kilchenmann Dec 14, 2021
c08af16
Merge branch 'main' into wip/dev-25-upload-video-support
kilchenmann Dec 14, 2021
6546197
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Feb 1, 2022
34cecad
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Mar 2, 2022
2b8975f
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Mar 7, 2022
55e792d
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Mar 7, 2022
d4c9656
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Mar 9, 2022
e113e5a
refactor: remove properties from moving image file value
subotic Mar 10, 2022
383da6a
test: regenerate ontology test responses
subotic Mar 10, 2022
c1fb6f2
deps(sipi): bump to newer version with video information support
subotic Mar 18, 2022
67fadd6
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Mar 18, 2022
dc809d4
refactor(gh-ci): format indent
kilchenmann Apr 1, 2022
841fa28
chore(deps): bump sipi to latest (incl. bc and imagemagick)
kilchenmann Apr 1, 2022
18e514a
refactor(sipi): clean up and improve upload script
kilchenmann Apr 1, 2022
bf78ac5
refactor(sipi): clean up and improve upload script
kilchenmann Apr 1, 2022
cc77e23
refactor(sipi): clean up and improve upload script
kilchenmann Apr 1, 2022
b518632
refactor(sipi): clean up and improve store script
kilchenmann Apr 1, 2022
c1e7ab8
feat(sipi): add script to export frames from video
kilchenmann Apr 1, 2022
b5ea2d2
Merge branch 'main' into wip/dev-25-upload-video-support
kilchenmann Apr 2, 2022
e578bee
test(ontologie): regenerate test data
subotic Apr 2, 2022
02412c9
refactor(sipi): remove commented code
kilchenmann Apr 5, 2022
bc704e3
refactor(sipi): add missing newline
kilchenmann Apr 5, 2022
3e8f588
refactor(sipi): update comment
kilchenmann Apr 5, 2022
60f7cec
refactor(sipi): remove author from shell script
kilchenmann Apr 5, 2022
0a7dab5
refactor(sipi): remove unused script
kilchenmann Apr 5, 2022
fe87c1c
refactor(sipi): fix typo in coment
kilchenmann Apr 5, 2022
9d6781b
refactor(sipi): update comment
kilchenmann Apr 5, 2022
5a7f056
refactor(sipi): delete empty and unused function
kilchenmann Apr 5, 2022
3b8d6df
Merge branch 'wip/dev-25-upload-video-support' of https://github.com/…
kilchenmann Apr 5, 2022
ef47752
Merge branch 'main' into wip/dev-25-upload-video-support
kilchenmann Apr 5, 2022
4ab6d5e
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Apr 5, 2022
cf231cd
Merge branch 'main' into wip/dev-25-upload-video-support
subotic Apr 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Expand Up @@ -187,7 +187,7 @@ jobs:
{"type": "chore", "section": "Maintenance", "hidden": false },
{"type": "refactor", "section": "Maintenance", "hidden": false },
{"type": "docs", "section": "Documentation", "hidden": false }
]'
]'

# publish only on release
publish:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -37,6 +37,8 @@ dependencies.txt
/client-test-data.zip
/sipi/images/082E/*
/sipi/images/originals/082E/*
sipi/images/1111/*
sipi/images/originals/1111/*
Comment on lines +40 to +41
Copy link
Collaborator

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?

Copy link
Contributor

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.

/dependencies.bzl

.idea/
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Expand Up @@ -31,7 +31,7 @@ services:
environment:
- TZ=Europe/Zurich
- SIPI_EXTERNAL_PROTOCOL=http
- SIPI_EXTERNAL_HOSTNAME=localhost
- SIPI_EXTERNAL_HOSTNAME=0.0.0.0
- SIPI_EXTERNAL_PORT=1024
- SIPI_WEBAPI_HOSTNAME=api
- SIPI_WEBAPI_PORT=3333
Expand Down
22 changes: 2 additions & 20 deletions knora-ontologies/knora-base.ttl
Expand Up @@ -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
Copy link
Collaborator

Choose a reason for hiding this comment

The 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

Copy link
Contributor

Choose a reason for hiding this comment

The 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 .

Expand Down Expand Up @@ -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 .

Expand Down
2 changes: 1 addition & 1 deletion project/Dependencies.scala
Expand Up @@ -15,7 +15,7 @@ object Dependencies {
val akkaHttpVersion = "10.2.8"
val jenaVersion = "4.4.0"
val metricsVersion = "4.0.1"
val sipiImage = "daschswiss/sipi:3.3.4" // base image the knora-sipi image is created from
val sipiImage = "daschswiss/sipi:3.5.0" // base image the knora-sipi image is created from
val fusekiImage = "daschswiss/apache-jena-fuseki:2.0.8" // should be the same version as in docker-compose.yml

// ZIO
Expand Down
222 changes: 222 additions & 0 deletions sipi/scripts/export-moving-image-frames.sh
@@ -0,0 +1,222 @@
#!/bin/bash

# Export moving image frames for preview in search results and on timeline
# Author: André Kilchenmann, a.kilchenmann@unibas.ch

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have the author here? In all other scripts we always just used the licence in the top part of the file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot to remove it. Resolved in 60f7cec

# 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'

# check the outpath for the matrix files;
# if exists, delete it and create new
# if [ -d "matrix" ]
# then
# rm -rf ./matrix
# fi
# mkdir -p 'matrix'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can probably be removed, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved in 02412c9


# 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}
12 changes: 8 additions & 4 deletions sipi/scripts/file_info.lua
Expand Up @@ -144,10 +144,14 @@ function make_audio_file_info(extension)
end

function make_video_file_info(extension)
return {
media_type = VIDEO,
extension = extension
}
if not table.contains(video_extensions, extension) then
return nil
else
return {
media_type = VIDEO,
extension = extension
}
end
end

function make_text_file_info(extension)
Expand Down