{"id":13394657,"url":"https://github.com/vvo/gifify","last_synced_at":"2025-05-14T02:07:50.561Z","repository":{"id":23645651,"uuid":"27015948","full_name":"vvo/gifify","owner":"vvo","description":"😻 Convert any video file to an optimized animated GIF.","archived":false,"fork":false,"pushed_at":"2019-03-18T20:28:01.000Z","size":7833,"stargazers_count":6251,"open_issues_count":27,"forks_count":312,"subscribers_count":93,"default_branch":"master","last_synced_at":"2025-05-11T21:44:02.137Z","etag":null,"topics":["ffmpeg","gif","gifify","gifsicle","imagemagick","mp4","nodejs","screencast","video"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vvo.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-22T23:25:23.000Z","updated_at":"2025-05-10T04:48:48.000Z","dependencies_parsed_at":"2022-08-07T11:00:41.967Z","dependency_job_id":null,"html_url":"https://github.com/vvo/gifify","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvo%2Fgifify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvo%2Fgifify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvo%2Fgifify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvo%2Fgifify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vvo","download_url":"https://codeload.github.com/vvo/gifify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254052911,"owners_count":22006717,"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","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":["ffmpeg","gif","gifify","gifsicle","imagemagick","mp4","nodejs","screencast","video"],"created_at":"2024-07-30T17:01:27.314Z","updated_at":"2025-05-14T02:07:45.551Z","avatar_url":"https://github.com/vvo.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","🔧 Utilities \u0026 Miscellaneous","Media Processing","video","JS/ES6"],"sub_categories":["Rust"],"readme":"**NOTE FROM AUTHOR**\n\nI am no more using this project or providing any support to it, if you want to maintain it, ping me here: vincent.voyer@gmail.com.\n\nThis project was created 4 years ago, there might be better ways to turn a video into a GIF now, use google!\n\n**/NOTE FROM AUTHOR**\n\n# gifify\n\nConvert any video file to an optimized animated GIF. Either in its full length or only a part of it.\n\n## Demo time\n\n![screencast](screencast.gif)\n\nThis screencast was recorded with [lolilolicon/FFcast](https://github.com/lolilolicon/FFcast) then converted to a GIF with:\n\n```shell\ngifify screencast.mkv -o screencast.gif --resize 800:-1\n```\n\n## Features\n\n- command line interface\n- programmatic JavaScript ([Node.JS](http://nodejs.org/)) [stream](http://nodejs.org/api/stream.html) interface\n- unix friendly, supports `stdin` \u0026 `stdout`\n- optimized! uses [pornel/giflossy](https://github.com/pornel/giflossy) to generate light GIFS\n- lots of options: movie speed, fps, colors, compression, resize, reverse, from \u0026 to, subtitles\n- no temp files used, everything happens in memory\n- fast! Extracting a 5-second GIF from the middle of a 2-hour movie takes less than 20 seconds\n\n## Requirements\n\nBefore using gifify, please install:\n\n- [Node.js](https://nodejs.org) (`$ brew install node`)\n- [FFmpeg](http://ffmpeg.org/) [🐓🐓🐓🐓](http://en.wikipedia.org/wiki/FFmpeg#History) (`$ brew install ffmpeg`)\n- [convert](http://www.imagemagick.org/script/convert.php), the famous [ImageMagick](http://www.imagemagick.org/) (`$ brew install imagemagick`)\n- [pornel/giflossy](https://github.com/pornel/giflossy/releases), it's a [gifsicle](http://www.lcdf.org/gifsicle/) fork (waiting for [gifsicle#16](https://github.com/kohler/gifsicle/pull/16) to be merged) (`$ brew install giflossy`)\n\nYou can also use the [gifify Docker image](https://github.com/maxogden/gifify-docker) which comes with everything installed.\n\n## Installation\n\n```shell\nnpm install -g gifify\n```\n\n## Command line usage\n\n```shell\n\u003e gifify -h\n\n  Usage: gifify [options] [file]\n\n  Options:\n\n    -h, --help              output usage information\n    -V, --version           output the version number\n    --colors \u003cn\u003e            Number of colors, up to 255, defaults to 80\n    --compress \u003cn\u003e          Compression (quality) level, from 0 (no compression) to 100, defaults to 40\n    --from \u003cposition\u003e       Start position, hh:mm:ss or seconds, defaults to 0\n    --fps \u003cn\u003e               Frames Per Second, defaults to 10\n    -o, --output \u003cfile\u003e     Output file, defaults to stdout\n    --resize \u003cW:H\u003e          Resize output, use -1 when specifying only width or height. `350:100`, `400:-1`, `-1:200`\n    --reverse               Reverses movie\n    --speed \u003cn\u003e             Movie speed, defaults to 1\n    --subtitles \u003cfilepath\u003e  Subtitle filepath to burn to the GIF\n    --text \u003cstring\u003e         Add some text at the bottom of the movie\n    --to \u003cposition\u003e         End position, hh:mm:ss or seconds, defaults to end of movie\n    --no-loop               Will show every frame once without looping\n```\n\n## Programmatic usage\n\nSee the [example](./example).\n\n```js\nvar fs = require('fs');\nvar gifify = require('gifify');\nvar path = require('path');\n\nvar input = path.join(__dirname, 'movie.mp4');\nvar output = path.join(__dirname, 'movie.gif');\n\nvar gif = fs.createWriteStream(output);\n\nvar options = {\n  resize: '200:-1',\n  from: 30,\n  to: 35\n};\n\ngifify(input, options).pipe(gif);\n```\n\nYou can also pass a [readable stream](http://nodejs.org/api/stream.html#stream_class_stream_readable) to `gifify(stream, opts)`.\n\n## Readable stream input performance\n\nGifify supports streams both on command line (`cat movie.mp4 | gifify -o out.gif`) and in the programmatic API (`gifify(readableStream, opts).pipe(writableStream)`).\n\nWhile it's super useful in some cases, if you have the file on disk already, you better do `gifify movie.mp4 -o out.gif` or `gifify(filePath, opts).pipe(writableStream)`.\n\nWhy? Because piping 3.4GB when you want to cut from 40:20 to 40:22 still takes a loooooot of time and does not give you any performance benefit.\n\nFFmpeg has to read from 0GB -\u003e $START_BYTE_40:20 and discards it. But everything flows in your memory.\n\nWhen using direct file input from command line, we pass the `-i filename` option to FFmpeg and then it's super fast!\n\nBe careful when `|piping`.\n\n## Adding some text\n\nYou can burn some simple text into your GIF:\n\n```shell\ngifify back.mp4 -o back.gif --from 01:48:23.200 --to 01:48:25.300 --text \"What?..What?What?\"\n```\n\nResult:\n\n![back](back.gif)\n\n## Subtitles\n\nYou can burn subtitles into your GIF, it's that easy:\n\n```shell\ngifify 22.mkv -o movie.gif --subtitles 22.ass --from 1995 --to 2002 --resize 600:-1\n```\n\nYou must create new subtitles files, the timecodes for the complete film will not work for a five seconds GIF.\n\nCreate subtitles using [aegisub](http://www.aegisub.org/) and augment the font size for a great effect!\n\nHere's the `22.ass` from the previous command, created with aegisub:\n\n```ass\n[Script Info]\n; Script generated by Aegisub 3.2.1\n; http://www.aegisub.org/\nTitle: Default Aegisub file\nScriptType: v4.00+\nWrapStyle: 0\nScaledBorderAndShadow: yes\nYCbCr Matrix: None\n\n[Aegisub Project Garbage]\n\n[V4+ Styles]\nFormat: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\nStyle: Default,Arial,20,\u0026H00FFFFFF,\u0026H000000FF,\u0026H00000000,\u0026H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1\n\n[Events]\nFormat: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\nDialogue: 0,0:00:02.50,0:00:03.97,Default,,0,0,0,,{\\fnLiberation Sans\\fs40}Okay, okay.\nDialogue: 0,0:00:05.00,0:00:06.90,Default,,0,0,0,,{\\fnLiberation Sans\\fs40}Okay. Okay.\n```\n\nResult extracting a GIF from [22 Jump Street](http://www.imdb.com/title/tt2294449/):\n\n![22](22.gif)\n\n## GIF Performance\n\n```\nOn modern hardware GIF is the slowest and most expensive video codec. Can we please allow it to be obsoleted?\n```\n\nhttps://pornel.net/efficient-gifs#sec44\n\nYOLO!\n\n## Giflossy\n\n[Giflossy](https://github.com/pornel/giflossy) is a fork of [gifsicle](http://www.lcdf.org/gifsicle/), gifsicle author is currently [working on](https://github.com/kohler/gifsicle/tree/lossy) integrating the lossy part in gifsicle.\n\nSo in little time we will be able to directly use gifsicle and gifiscle packages.\n\n## Thanks\n\n[jclem/gifify](https://github.com/jclem/gifify/) was a great source of inspiration.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvvo%2Fgifify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvvo%2Fgifify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvvo%2Fgifify/lists"}