{"id":13489199,"url":"https://github.com/wandenberg/nginx-video-thumbextractor-module","last_synced_at":"2025-10-06T20:50:56.540Z","repository":{"id":1903446,"uuid":"2830385","full_name":"wandenberg/nginx-video-thumbextractor-module","owner":"wandenberg","description":"Nginx module to extract thumbs from a video file","archived":false,"fork":false,"pushed_at":"2023-05-23T17:41:43.000Z","size":4952,"stargazers_count":205,"open_issues_count":0,"forks_count":38,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-04-03T02:11:17.036Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wandenberg.png","metadata":{"files":{"readme":"README.textile","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2011-11-22T19:38:46.000Z","updated_at":"2025-02-18T18:27:53.000Z","dependencies_parsed_at":"2024-01-19T15:04:25.756Z","dependency_job_id":"e2fa9698-31cd-4001-9271-58cbd7d1c022","html_url":"https://github.com/wandenberg/nginx-video-thumbextractor-module","commit_stats":{"total_commits":84,"total_committers":4,"mean_commits":21.0,"dds":0.0357142857142857,"last_synced_commit":"e81f8501406931719eae8eada94b8603932b6f92"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/wandenberg/nginx-video-thumbextractor-module","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wandenberg%2Fnginx-video-thumbextractor-module","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wandenberg%2Fnginx-video-thumbextractor-module/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wandenberg%2Fnginx-video-thumbextractor-module/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wandenberg%2Fnginx-video-thumbextractor-module/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wandenberg","download_url":"https://codeload.github.com/wandenberg/nginx-video-thumbextractor-module/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wandenberg%2Fnginx-video-thumbextractor-module/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278678697,"owners_count":26027049,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-06T02:00:05.630Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T19:00:19.863Z","updated_at":"2025-10-06T20:50:56.521Z","avatar_url":"https://github.com/wandenberg.png","language":"C","funding_links":[],"categories":["C","Third Modules","Third Party Modules","Honourable mentions"],"sub_categories":["C Modules"],"readme":"h1(#nginx_video_thumbextractor_module). Nginx Video Thumb Extractor Module\n\nVideo Thumb Extractor is a module to extract an image from a video frame from a specific second resizing/cropping it to a given size.\nThe smallest generated image is ==16x16== pixels.\n\n_This module is not distributed with the Nginx source. See \"the installation instructions\":installation._\n\nAvailable on github at \"nginx-video-thumbextractor-module\":repository\n\n\nh1(#status). Status\n\nThis module is considered production ready.\n\n\nh1(#requirements). Requirements\n\nThis module depends from some libraries (headers and shared objects) which has to be installed before it:\n\n* avformat \u003e= 57.56.101 (last tested version: 58.12.100) - commonly distributed with \"FFmpeg\":http://ffmpeg.org\n* avcodec \u003e= 57.64.101 (last tested versions: 58.18.100) - commonly distributed with \"FFmpeg\":http://ffmpeg.org\n* avutil \u003e= 55.34.101 (last tested versions: 56.14.100) - commonly distributed with \"FFmpeg\":http://ffmpeg.org\n* avfilter \u003e= 6.65.100 (last tested versions: 7.16.100) - commonly distributed with \"FFmpeg\":http://ffmpeg.org\n* swscale \u003e= 4.2.100 (last tested versions: 5.1.100) - commonly distributed with \"FFmpeg\":http://ffmpeg.org\n* jpeg - \"libjpeg\":http://libjpeg.sourceforge.net\n\n\nh1(#recommendation). Recommendation\n\nWhen installing FFmpeg (last tested versions: 4.0.6) from source do not forget to enable shared libraries using\n\npre. --enable-shared\n\nIf you don't install FFmpeg from source you need to be sure that you have headers files for the libs.\n\n\nh1(#supported_video_formats). Supported Video Formats\n\nThis module uses the libraries avcodec and avformat to read the video files. Any supported video format for these libraries will work.\nTested formats was _mp4_, _mov_ and _flv_.\n\n\nh1(#installation). Installation\n\nInstall the above requirements and follow the steps bellow.\n\n\u003cpre\u003e\n# clone the project\ngit clone https://github.com/wandenberg/nginx-video-thumbextractor-module.git\nNGINX_VIDEO_THUMBEXTRACTOR_MODULE_PATH=$PWD/nginx-video-thumbextractor-module\n\n# get desired nginx version (tested with 1.18.x series)\nwget http://nginx.org/download/nginx-1.18.0.tar.gz\n\n# unpack, configure and build\ntar xzvf nginx-1.18.0.tar.gz\ncd nginx-1.18.0\n# configure nginx\n./configure --add-module=$NGINX_VIDEO_THUMBEXTRACTOR_MODULE_PATH\nmake\n\n# install and finish\nsudo make install\n\n# check\nsudo /usr/local/nginx/sbin/nginx -v\n  nginx version: nginx/1.18.0\n\n# test configuration\nsudo /usr/local/nginx/sbin/nginx -c $NGINX_VIDEO_THUMBEXTRACTOR_MODULE_PATH/nginx.conf -t\n  the configuration file $NGINX_VIDEO_THUMBEXTRACTOR_MODULE_PATH/nginx.conf syntax is ok\n  configuration file $NGINX_VIDEO_THUMBEXTRACTOR_MODULE_PATH/nginx.conf test is successful\n\n# run\nsudo /usr/local/nginx/sbin/nginx -c $NGINX_VIDEO_THUMBEXTRACTOR_MODULE_PATH/nginx.conf\n\u003c/pre\u003e\n\n\nh1(#basic-configuration). Basic Configuration\n\n\u003cpre\u003e\nlocation ~ /thumbs(.*) {\n  video_thumbextractor;\n  video_thumbextractor_video_filename    $1;\n  video_thumbextractor_video_second      $arg_second;\n  video_thumbextractor_image_width       $arg_width;\n  video_thumbextractor_image_height      $arg_height;\n}\n\u003c/pre\u003e\n\n\nh1(#basic-usage). Basic Usage\n\nAssuming that you have a file called _video.mp4_ on your root folder use a browser to test the following urls:\n\n\u003cpre\u003e\n# get an image from second 10 with the original size\nhttp://localhost/thumbs/video.mp4?second=10\n\n# get an image from second 20 with a 50px of height and proportional width keeping video scale\nhttp://localhost/thumbs/video.mp4?second=10\u0026height=50\n\n# get an image from second 30 with a 50px of height and 100px of width, the image will be cropped to keep video scale\nhttp://localhost/thumbs/video.mp4?second=20\u0026height=50\u0026width=100\n\u003c/pre\u003e\n\n\nh1(#directives). Directives\n\n\nh2(#video_thumbextractor). video_thumbextractor\n\n*syntax:* _video_thumbextractor_\n*context:* _location_\n*release version:* _0.1.0_\n\nSet Video Thumb Extractor as the request handler for the location.\n\n\nh2(#video_thumbextractor_video_filename). video_thumbextractor_video_filename\n\n*syntax:* _video_thumbextractor_video_filename filename_\n*default:* _none_\n*context:* _http_\n*release version:* _0.1.0_\n\nThe video filename relative to root folder.\nThis directive is required.\nReturn a 404 if the video is not found.\n\n\nh2(#video_thumbextractor_video_second). video_thumbextractor_video_second\n\n*syntax:* _video_thumbextractor_video_second second_\n*default:* _none_\n*context:* _http_\n*release version:* _0.1.0_\n\nThe time in seconds where the image should be extracted. The nearest key frame will be used to get the image.\nThis directive is required.\nReturn a 400 if the value is not specified.\nReturn a 404 if the second is not found (the video is shorter than the time specified).\n\n\nh2(#video_thumbextractor_image_width). video_thumbextractor_image_width\n\n*syntax:* _video_thumbextractor_image_width width_\n*default:* _0_\n*context:* _http_\n*release version:* _0.1.0_\n\nThe width used to generate the image.\nThis directive is optional.\nIf only the width is specified the video size will be used as image size.\n\n\nh2(#video_thumbextractor_image_height). video_thumbextractor_image_height\n\n*syntax:* _video_thumbextractor_image_height height_\n*default:* _0_\n*context:* _http_\n*release version:* _0.1.0_\n\nThe height used to generate the image.\nThis directive is optional.\nIf only the height is specified the width will be determined using video scale to keep the aspect.\nIf both, width and height, are specified the image will suffers a resize and an eventual crop to keep the aspect.\n\n\nh2(#video_thumbextractor_only_keyframe). video_thumbextractor_only_keyframe\n\n*syntax:* _video_thumbextractor_only_keyframe on|off_\n*default:* _on_\n*context:* _http_\n*release version:* _0.3.0_\n\nSet if only the keyframes should be used to create the image.\nWhen set to off, the process will be a bit slower because the video will be decoded from the nearest keyframe up to the exact requested time.\n\n\nh2(#video_thumbextractor_next_time). video_thumbextractor_next_time\n\n*syntax:* _video_thumbextractor_next_time on|off_\n*default:* _on_\n*context:* _http_\n*release version:* _0.3.0_\n\nSet if will use the previous or the next keyframe considering the requested time when configured to use only the keyframes.\n\n\nh2(#video_thumbextractor_tile_rows). video_thumbextractor_tile_rows\n\n*syntax:* _video_thumbextractor_tile_rows number_\n*default:* _none_\n*context:* _http_\n*release version:* _0.6.0_\n\nSet the number of rows to be used on tile filter. The number of cols will be calculated using the sample interval, the video duration and the start time used on 'video_second' directive, if not set.\n\n!test/test_video_1_rows.jpg(using only 1 row)!\n\n\nh2(#video_thumbextractor_tile_cols). video_thumbextractor_tile_cols\n\n*syntax:* _video_thumbextractor_tile_cols number_\n*default:* _none_\n*context:* _http_\n*release version:* _0.6.0_\n\nSet the number of cols to be used on tile filter. The number of rows will be calculated using the sample interval, the video duration and the start time used on 'video_second' directive, if not set.\n\n!test/test_video_2_cols.jpg(using 2 cols)!\n\n\nh2(#video_thumbextractor_tile_max_rows). video_thumbextractor_tile_max_rows\n\n*syntax:* _video_thumbextractor_tile_max_rows number_\n*default:* _none_\n*context:* _http_\n*release version:* _0.6.0_\n\nSet the max number of rows to be used on tile filter when only the number of cols was set. After calculate the number of necessary rows it can be limited by the configured max number of rows.\n\n!test/test_video_2_cols_2s_interval_2_max_rows.jpg(using 2 cols limited on up to 2 rows)!\n\n\nh2(#video_thumbextractor_tile_max_cols). video_thumbextractor_tile_max_cols\n\n*syntax:* _video_thumbextractor_tile_max_cols number_\n*default:* _none_\n*context:* _http_\n*release version:* _0.6.0_\n\nSet the max number of cols to be used on tile filter when only the number of rows was set. After calculate the number of necessary cols it can be limited by the configured max number of cols.\n\n!test/test_video_1_rows_2s_interval_5_max_cols.jpg(using only 1 row limited on up to 5 cols)!\n\n\nh2(#video_thumbextractor_tile_sample_interval). video_thumbextractor_tile_sample_interval\n\n*syntax:* _video_thumbextractor_tile_sample_interval number_\n*default:* _none_\n*context:* _http_\n*release version:* _0.6.0_\n\nSet the sample interval to get the frames for tile. When it was not set and the number of cols and rows were, the sample interval will be calculated to the video can fit on the tile layout.\nWhen only the number of rows or the number of cols was set and sample interval was not, the module will use the default value of 5 seconds.\nTo the interval be respected you should set video_thumbextractor_only_keyframe directive to off.\n\n!test/test_video_2_cols_2s_interval.jpg(using 2 cols and 2 seconds of interval)!\n\n!test/test_video_1_rows_2s_interval.jpg(using 1 row and 2 seconds of interval)!\n\n!test/test_video_4_cols_4_rows.jpg(using 4 rows, 4 cols and calculated sample interval)!\n\n!test/test_video_4_cols_4_rows_3s_interval.jpg(using  4 rows, 4 cols and 3 seconds of interval)!\n\n\nh2(#video_thumbextractor_tile_color). video_thumbextractor_tile_color\n\n*syntax:* _video_thumbextractor_tile_color string_\n*default:* _none_\n*context:* _http_\n*release version:* _0.6.0_\n\nSet the color to be used on the background. Valid values are defined \"here\":https://ffmpeg.org/ffmpeg-utils.html#Color\n\n!test/test_video_2_cols_bg_color.jpg(using #EEAA33 as background color)!\n\n\nh2(#video_thumbextractor_tile_margin). video_thumbextractor_tile_margin\n\n*syntax:* _video_thumbextractor_tile_margin number_\n*default:* _none_\n*context:* _http_\n*release version:* _0.6.0_\n\nSet the size of the margin to be used on the final image.\n\n!test/test_video_2_cols_2_rows_5_margin.jpg(using 5px of margin)!\n\n\nh2(#video_thumbextractor_tile_padding). video_thumbextractor_tile_padding\n\n*syntax:* _video_thumbextractor_tile_padding number_\n*default:* _none_\n*context:* _http_\n*release version:* _0.6.0_\n\nSet the size of the padding to be used between the frames.\n\n!test/test_video_2_cols_2_rows_3_padding.jpg(using 3px of padding)!\n\n\nh2(#video_thumbextractor_threads). video_thumbextractor_threads\n\n*syntax:* _video_thumbextractor_threads string_\n*default:* _auto_\n*context:* _http_\n*release version:* _0.6.0_\n\nSet the number of threads used by avcodec.\n\n\nh2(#video_thumbextractor_processes_per_worker). video_thumbextractor_processes_per_worker\n\n*syntax:* _video_thumbextractor_processes_per_worker number_\n*default:* _1_\n*context:* _http_\n*release version:* _0.7.0_\n\nSet the number of process each nginx worker can fork to extract the thumbs. The requests will be queued until there is an available process.\n\n\nh1(#contributors). Contributors\n\n\"People\":contributors\n\n\nh1(#changelog). Changelog\n\nh2(#0_9_0). v0.9.0\n* drop support to versions prior Nginx 1.10.0 and FFmpeg libraries prior to 3.2.4\n\nh2(#0_8_0). v0.8.0\n* add support to use dynamic values on tile configurations\n\nh2(#0_7_0). v0.7.0\n\n* add support to execute the thumb extraction in a different process to not block the nginx worker\n* add video_thumbextractor_processes_per_worker directive\n* try to make the code simpler\n* revert the changes on 0.6.2\n\nh2(#0_6_2). v0.6.2\n\n* trying to improve the performance not reading the raw response (the video)\n\nh2(#0_6_1). v0.6.1\n\n* add support to rotate the image when the video stream has instructions to do it\n* add support to videos with different aspect ratio\n* fix support to files with more than one video stream choosing the best of them\n\nh2(#0_6_0). v0.6.0\n\n* add support to tile filter, used to make story boards or sprites\n* add directive to control the number of threads used by avcodec\n\nh2(#0_5_0). v0.5.0\n\n* fix jpeg dpi configuration usage\n* remove support to old libav* libraries\n* remove MagickWand dependency which cause memory leak\n\nh2(#0_4_0). v0.4.0\n\n* fix to proper read videos with the moov atom is at the end of the file\n* fix to use the nearest decoded frame, in the case of requested time is on the end of the video\n* fix CFLAGS, LDFLAGS and ngx_feature_libs to find the parameters to compile using right MagickWand lib version\n* using av_frame_alloc instead of avcodec_alloc_frame when available\n\nh2(#0_3_0). v0.3.0\n\n* fix frame allocation assert\n* add configuration to choose between only keyframes or not, and if will use the previous or next frame relative to given time\n* make possible read the video from an nginx cache file\n\nh2(#0_2_0). v0.2.0\n\n* fix use of deprecated functions\n\nh2(#0_1_0). v0.1.0\n\n* Initial release\n\n\n[repository]https://github.com/wandenberg/nginx-video-thumbextractor-module\n[installation]#instalation\n[contributors]https://github.com/wandenberg/nginx-video-thumbextractor-module/contributors\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwandenberg%2Fnginx-video-thumbextractor-module","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwandenberg%2Fnginx-video-thumbextractor-module","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwandenberg%2Fnginx-video-thumbextractor-module/lists"}