https://github.com/cshum/imagorvideo Skip to content Toggle navigation Sign up * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code + Explore + All features + Documentation + GitHub Skills + Blog * Solutions + By Plan + Enterprise + Teams + Compare all + By Solution + CI/CD & Automation + DevOps + DevSecOps + Case Studies + Customer Stories + Resources * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles + Repositories + Topics + Trending + Collections * Pricing [ ] * # In this repository All GitHub | Jump to | * No suggested jump to results * # In this repository All GitHub | Jump to | * # In this user All GitHub | Jump to | * # In this repository All GitHub | Jump to | Sign in Sign up {{ message }} cshum / imagorvideo Public * * Notifications * Fork 6 * Star 74 imagor thumbnail server in Go and ffmpeg C bindings License Apache-2.0 license 74 stars 6 forks Star Notifications * Code * Issues 1 * Pull requests 1 * Actions * Projects 0 * Security * Insights More * Code * Issues * Pull requests * Actions * Projects * Security * Insights cshum/imagorvideo This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. master Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags Name already in use A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? Cancel Create 2 branches 19 tags Code * Clone HTTPS GitHub CLI [https://github.com/c] Use Git or checkout with SVN using the web URL. [gh repo clone cshum/] Work fast with our official CLI. Learn more. * Open with GitHub Desktop * Download ZIP Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching Xcode If nothing happens, download Xcode and try again. Launching Visual Studio Code Your codespace will open once ready. There was a problem preparing your codespace, please try again. Latest commit @cshum cshum fix(ffmpeg): 0s frame handling ... 9ccfbe5 Oct 24, 2022 fix(ffmpeg): 0s frame handling 9ccfbe5 Git stats * 99 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .github chore: update sponsor button Oct 4, 2022 cmd/imagorvideo feat: imagorvideo init Sep 8, 2022 ffmpeg fix(ffmpeg): 0s frame handling Oct 24, 2022 testdata fix(ffmpeg): 0s frame handling Oct 24, 2022 .dockerignore feat: imagorvideo init Sep 8, 2022 .gitignore feat: imagorvideo init Sep 8, 2022 Dockerfile build: go 1.19.2 Oct 6, 2022 LICENSE feat: imagorvideo init Sep 8, 2022 Makefile feat: imagorvideo init Sep 8, 2022 README.md chore: update description Oct 23, 2022 config.go feat: imagorvideo init Sep 8, 2022 config_test.go test: ffmpeg processor tests Sep 16, 2022 go.mod build: imagor 1.2.2 Oct 18, 2022 go.sum build: imagor 1.2.2 Oct 18, 2022 option.go feat: imagorvideo init Sep 8, 2022 processor.go feat: seek() filter and ffmpeg.SeekPosition, ffmpeg.SeekDuration Oct 23, 2022 processor_test.go feat: seek() filter and ffmpeg.SeekPosition, ffmpeg.SeekDuration Oct 23, 2022 View code imagorvideo Quick Start Filters frame(n) vs seek(n) Metadata Configuration README.md imagorvideo Test Status Coverage Status Docker Hub GitHub Container Registry imagorvideo is a new initiative that brings video thumbnail capability through ffmpeg, built on the foundations of imagor - a fast, Docker-ready image processing server written in Go with libvips. imagorvideo uses ffmpeg C bindings that extracts image thumbnail from video, by attempting to select the best frame. It then forwards to libvips to perform all the image cropping, resizing and filters provided by imagor. imagorvideo integrates ffmpeg AVIOContext read and seek callbacks with imagor loader, storage and result storage, which supports HTTP (s), File System, AWS S3 and Google Cloud Storage out of box. For non seek-able source such as HTTP and S3, imagor simulates seek using memory or temp file buffer. This also aims to be a reference project demonstrating imagor extension. Quick Start docker run -p 8000:8000 shumc/imagorvideo -imagor-unsafe Original: http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 Result: http://localhost:8000/unsafe/300x0/7x7/filters:label(imagorvideo,-10,-7,15,yellow):fill(yellow)/http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 http://localhost:8000/unsafe/300x0/0x0:0x14/filters:frame(1m59s):fill(yellow):label(imagorvideo,center,bottom,12,black,20)/http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 http://localhost:8000/unsafe/300x0/7x7/filters:frame(0.6):label(imagorvideo,10,-7,15,yellow):fill(yellow)/http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 [demo] [demo2] [demo3] imagorvideo works by streaming out a limited number of frame data, looping through and calculating the histogram of each frame. It then choose the best frame for imaging, based on root-mean-square error (RMSE). This allow skipping the black frames that usually occur at the beginning of videos. imagorvideo then converts the selected frame to RGB image data, forwards to the imagor libvips processor, which has always been best at image processing with tons of features. Check out imagor documentations for all the image options supported. Filters imagorvideo supports the following filters, which can be used in conjunction with imagor filters: * frame(n) specify the position or time duration for imaging, which skips the automatic best frame selection: + Float between 0.0 and 1.0 indices position of the video. Example frame(0.5), frame(1.0) + Time duration indices the elasped time since the start of video. Example frame(5m1s), frame(200s) * seek(n) seeks to the approximate position or time duration, then perform automatic best frame selection around that point: + Float between 0.0 and 1.0 indices position of the video. Example seek(0.5) + Time duration indices the elasped time since the start of video. Example seek(5m1s), seek(200s) * max_frames(n) restrict the maximum number of frames allocated for image selection. The smaller the number, the faster the processing time. frame(n) vs seek(n) There are differences you may want to choose one over the other. frame(n) gives you the precise time frame specified. However, precise may not be the best in some circumstances: http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 Retrieving the frame at 5 minutes elapsed time of this video: http://localhost:8000/unsafe/filters:frame(5m)/http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 It results a complete black frame. black This is where seek(n) comes handy. It seeks to the key frame before the 5 minutes elapsed time, then perform best frame selection starting from that point using root-mean-square error (RMSE). The result is a reasonable image that sits close to the specified time: http://localhost:8000/unsafe/filters:seek(5m)/http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4 seek 5m Metadata imagorvideo provides metadata endpoint that extracts video metadata, including dimension, duration and FPS data. It processes header only, without extracting the frame data for better processing speed. To use the metadata endpoint, add /meta right after the URL signature hash before the image operations: http://localhost:8000/unsafe/meta/https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/1080/Big_Buck_Bunny_1080_10s_30MB.mp4 { "format": "mp4", "content_type": "video/mp4", "orientation": 1, "duration": 10000, "width": 1920, "height": 1080, "title": "Big Buck Bunny, Sunflower version", "artist": "Blender Foundation 2008, Janus Bager Kristensen 2013", "fps": 30, "has_video": true, "has_audio": false } Configuration Configuration options specific to imagorvideo. Please see imagor configuration for all existing options available. -ffmpeg-fallback-image string FFmpeg fallback image on processing error. Supports image path enabled by loaders or storages About imagor thumbnail server in Go and ffmpeg C bindings Topics docker ffmpeg mp4 webm flv ogg mkv cover-art thumbnail Resources Readme License Apache-2.0 license Stars 74 stars Watchers 3 watching Forks 6 forks Releases 9 v0.3.3 Latest Oct 23, 2022 + 8 releases Sponsor this project Sponsor Learn more about GitHub Sponsors Packages 1 Languages * Go 59.0% * C 31.0% * Dockerfile 9.0% * Makefile 1.0% Footer (c) 2022 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.