cshum / imagorvideo

imagor video thumbnail server in Go and ffmpeg C bindings
Apache License 2.0
178 stars 13 forks source link

Long thumbnail generation time for S3 loader #89

Open blitss opened 2 weeks ago

blitss commented 2 weeks ago

I'm testing imagorvideo along with s3 storage loader and generating a thumbnail (uncached) consistently takes a very long time, more than 20 seconds every time.

image

And that is when running on beefy dedicated Hetzner server which I use for encoding the videos. Is there any way to optimize that time and is that expected? I'm running pretty much the default settings and only set seek to 10 seconds, e.g.:

http://localhost:8000/unsafe/1920x1080/filters:seek(10s)/sl/obj_01j6fxp6ggf2pbarp9276sc4fa.mp4

downloading the same file itself in full is taking only 5 seconds:

$ time curl --output /dev/null % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 232M 100 232M 0 0 42.8M 0 0:00:05 0:00:05 --:--:-- 45.0M curl --output /dev/null 0.31s user 0.50s system 14% cpu 5.431 total

so I guess a lot of time is spent on generating the thumbnail, what can I do to reduce that? the video info:

Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 creation_time : 2024-08-25T16:17:54.000000Z encoder : Blackmagic Design DaVinci Resolve Studio Duration: 00:00:58.11, start: 0.000000, bitrate: 33523 kb/s Stream #0:00x1: Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 3840x2160 [SAR 1:1 DAR 16:9], 33333 kb/s, 23.98 fps, 23.98 tbr, 24k tbn (default)

I'm also using avif + webp auto settings but that seem to have no impact for performance

cshum commented 2 weeks ago

Would you please try this docker build, which I am testing imagor with seekable s3 read stream. See if it makes any difference: https://github.com/cshum/imagorvideo/pkgs/container/imagorvideo/266301862?tag=master

ghcr.io/cshum/imagor@sha256:31a24a7cc2eba7efbbc59050358932b4654a22d763237228fe8a0fdcf356d634
blitss commented 2 weeks ago

Would you please try this docker build, which I am testing imagor with seekable s3 read stream. See if it makes any difference: https://github.com/cshum/imagorvideo/pkgs/container/imagorvideo/266301862?tag=master

ghcr.io/cshum/imagor@sha256:31a24a7cc2eba7efbbc59050358932b4654a22d763237228fe8a0fdcf356d634

Doesn't make any difference, it's still above 20s For experiment I tried using frame(n) instead of automatic frame selection and that does seem to make no difference either

Used this image: shumc/imagorvideo@sha256:31a24a7cc2eba7efbbc59050358932b4654a22d763237228fe8a0fdcf356d634

blitss commented 2 weeks ago

Ok it seems like I ran into some nested virtualization issues here and the problem is actually on my side performance-wise. Because I ran the same container on ARM Mac and even with Rosetta intel code it runs faster lol.

Sorry about that.

blitss commented 2 weeks ago

hm no actually I think I was right the first time the s3 loader time is higher than http

Compared using imagor@s3, imagor@http and just ffmpeg with the same input using cloudflare r2 storage here

Method Time (seconds)
FFmpeg 1.654
Imagor via HTTP loader 0.981
Imagor via S3 loader 20.310

Using ffmpeg

root@ffmpeg-pod:/# time ffmpeg -y -i https://r2v.**.app/obj_01j6m0ncdpe35bhyybgzzv259x.mp4 -ss 00:00:01 -frames:v 1 -vf scale=1920:1080 -update 1 -f image2 output_thumbnail.jpg ffmpeg version n7.0.2 Copyright (c) 2000-2024 the FFmpeg developers built with gcc 13 (Ubuntu 13.2.0-23ubuntu4) configuration: --prefix=/root/ffmpeg-build --cc=gcc --ld=g++ --cxx=g++ --pkg-config-flags=--static --extra-cflags=-I/root/ffmpeg-build/include --extra-ldflags='-L/root/ffmpeg-build/lib -L/root/ffmpeg-build/lib64' --extra-libs='-lpthread -lm -lz' --extra-ldexeflags=-static --bindir=/root/bin --enable-gpl --disable-shared --enable-static --enable-nonfree --enable-openssl --disable-libfreetype --enable-libfdk-aac --enable-libmp3lame --enable-libx264 --enable-libx265 --enable-libaom --enable-libsvtav1 --enable-libvmaf --enable-version3 --enable-libopus --disable-ffplay --disable-doc --disable-podpages --disable-debug libavutil 59. 8.100 / 59. 8.100 libavcodec 61. 3.100 / 61. 3.100 libavformat 61. 1.100 / 61. 1.100 libavdevice 61. 1.100 / 61. 1.100 libavfilter 10. 1.100 / 10. 1.100 libswscale 8. 1.100 / 8. 1.100 libswresample 5. 1.100 / 5. 1.100 libpostproc 58. 1.100 / 58. 1.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'https://r2v.**.app/obj_01j6m0ncdpe35bhyybgzzv259x.mp4': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: mp42mp41isomavc1 creation_time : 2021-06-11T18:48:27.000000Z Duration: 00:00:15.96, start: 0.000000, bitrate: 22420 kb/s Stream #0:00x1: Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 4096x2160, 22417 kb/s, 25 fps, 25 tbr, 25 tbn (default) Metadata: creation_time : 2021-06-11T18:48:27.000000Z handler_name : L-SMASH Video Handler vendor_id : [0][0][0][0] encoder : AVC Coding Stream mapping: Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (native)) Press [q] to stop, [?] for help [swscaler @ 0x7ff774012080] deprecated pixel format used, make sure you did set range correctly Output #0, image2, to 'output_thumbnail.jpg': Metadata: major_brand : mp42 minor_version : 0 compatible_brands: mp42mp41isomavc1 encoder : Lavf61.1.100 Stream #0:0(und): Video: mjpeg, yuvj420p(pc, unknown/bt709/bt709, progressive), 1920x1080, q=2-31, 200 kb/s, 25 fps, 25 tbn (default) Metadata: creation_time : 2021-06-11T18:48:27.000000Z handler_name : L-SMASH Video Handler vendor_id : [0][0][0][0] encoder : Lavc61.3.100 mjpeg Side data: cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A [out#0/image2 @ 0x65482c0] video:81KiB audio:0KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown frame= 1 fps=0.8 q=5.3 Lsize=N/A time=00:00:00.04 bitrate=N/A speed=0.0315x

real 0m1.654s user 0m2.428s sys 0m0.177s

Using imagor via HTTP loader

$ time curl --output thumbnail.png "https://imagor.**.app/unsafe/1920x1080/filters:frame(2)/https://r2v.**.app/obj_01j6m0ncdpe35bhyybgzzv259x. mp4" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 138k 100 138k 0 0 143k 0 --:--:-- --:--:-- --:--:-- 143k

real 0m0.981s user 0m0.013s sys 0m0.012s

Using imagor via S3 loader

$ time curl --output thumbnail.png "https://imagor.**.app/unsafe/1920x1080/filters:frame(1s)/sl/obj_01j6m0ncdpe35bhyybgzzv259x.mp4" % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 136k 100 136k 0 0 6885 0 0:00:20 0:00:20 --:--:-- 34300

real 0m20.310s user 0m0.016s sys 0m0.014s

cshum commented 2 weeks ago

Can you share any of the mp4 files to help reproduce the issue?

blitss commented 2 weeks ago

Can you share any of the mp4 files to help reproduce the issue?

Sure https://r2v.streamloop.app/obj_01j6m0ncdpe35bhyybgzzv259x.mp4

It does seem tho that problem is only reproducible by loading from S3 storage (I'm using CloudFlare, but also reproducible with others)