This is a simple FFmpeg-based animated GIF generator application built using Iced.
NOTE: Please take the time to read the potential issue section before running this application.
- To start converting a video into an animated GIF, simply drag-and-drop a video file on the application window or click on the
open button
to trigger your system's native file picker dialog. - The GIF's width defaults to 480 pixels, but you can use the
width input
to change that value.- NOTE: The GIF's frame rate is fixed at 10 FPS.
- When the job completes, the animated GIF automatically gets previewed by the application.
- To save the generated GIF, simply click on the
save button
to trigger your system's native file picker (i.e. saver) dialog. - The
cancel button
, when visible, may be used to cancel an ongoing job and clear the UI. - The
clear button
, when visible, may be used to clear the UI for a completed job.
Video to animated GIF conversion is achieved using FFmpeg
. The application uses the rust-ffmpeg-gif-maker wrapper library to communicate with FFmpeg
by making a system call to it and capturing and interpreting its stdout
and stderr
. In turn, the Iced
application communicates with the library using an asynchronous worker, similar to the one described in the official documentation for iced::subscription::channel.
This project is mainly targeted at Rust programmers who are in the process of learning Iced
. It makes use of concepts such as:
- using an asynchronous worker based on iced::subscription::channel to allow communicating between an
Iced
application and something else (in this case a child process), - implementing
Iced
's subscription method, - using the rfd library to trigger native file picker dialogs,
- importing and configuring custom fonts,
- creating and using a component,
- performing custom styling,
- and other stuff.
This project uses the rfd library to display native file picker dialogs. I noticed, on my development system (i.e. macOS
), that running the application with cargo run
or by simply executing the binary in a terminal (e.g. ./target/release/iced_gif_maker
) will cause rfd
to crash the application when trying to trigger a dialog. On the other hand, no problem arises, for instance, when starting the application using the following syntaxes: /bin/bash -c "cargo run --release"
or env cargo run --release
. Launching the application from a shell script will also work fine. At this point, I have reasons to believe that this is a permission issue, but I need to research the problem further. So, in the meantime, I recommend trying these workarounds if you face a similar issue when triggering dialogs. If none of these workarounds work, please let me know by opening an issue and we'll try to figure this out together.
- The
ffmpeg
binary must be available on your system's path.- Note that it is possible to use the
ICED_GIF_MAKER_FFMPEG_PATH
environment variable to specify the absolute location of the binary on the system if the binary is not on the path. See Build and running - More options for an example. - If you need to download
FFmpeg
, please visit the official FFmpeg download page. - NOTE: At the moment, the rust-ffmpeg-gif-maker library has successfully been tested with
ffmpeg version 5.0-tessus
andffmpeg version 6.0-tessus
onmacOS
, as well as with versionffmpeg version N-112483-gd799ad2404-20231020
onWindows 11
. So please feel free to let me know by opening an issue if you encounter any problems when trying run the application on your system.
- Note that it is possible to use the
- Clone the Git repository from GifHub:
git clone https://github.com/BB-301/rust-iced-gif-maker.git
- Move into the cloned repository:
cd rust-iced-gif-maker
- Run in release mode
cargo run --release
- Use the
ICED_GIF_MAKER_FFMPEG_PATH
environment variable to specify the path of theffmpeg
binary on your system. E.g.:
ICED_GIF_MAKER_FFMPEG_PATH=/absolute/path/to/ffmpeg cargo run --release
- Enable logging. E.g.:
# If `RUST_LOG` is not provided, the application will set it
# to `iced_gif_maker=debug,ffmpeg_gif_maker=info`.
cargo run --release --features logging
# Or, to specify `RUST_LOG` yourself, you can do something like this:
RUST_LOG="iced_gif_maker=debug" cargo run --release --features logging
- The application was tested on
macOS
andWindows 11
, but I would also like to test it onRaspberry Pi OS
. - I need to fix the bug described in How to build - Potential issue, about rfd making the application crash on
macOS
(and maybe elsewhere). - Ideally, the application would warn the user when (if) a save operation fails. But currently the application only prints whether the save operation was successful or not to
stdout
. - This project currently relies on a forked version of the iced_gif widget repository. In this application, the
iced_gif::gif::Frames::from_bytes
(from thetokio
feature flag) is used to decode the animated GIF into frames that are required by the widget. But when starting a decoding job, that job cannot be cancelled. This is generally not a problem for small to mid sized GIFs, but it could be wasteful for bigger ones. A simple solution around this problem would be to modifyiced_gif::gif::Frames::from_bytes
with an optional argument for the receiver part of a channel that would allow cancelling a job, and then use that channel's sender part to signal cancellation from the application, when required.
If you have any questions, if you find bugs, or if you have suggestions for this project, please feel free to contact me by opening an issue on the repository.
This project is released under the MIT License.