Skip to content

Instantly share code, notes, and snippets.

@SheldonWangRJT
Last active April 15, 2024 20:14
Show Gist options
  • Save SheldonWangRJT/8d3f44a35c8d1386a396b9b49b43c385 to your computer and use it in GitHub Desktop.
Save SheldonWangRJT/8d3f44a35c8d1386a396b9b49b43c385 to your computer and use it in GitHub Desktop.
Convert Movie(.mov) file to Gif(.gif) file in one command line in Mac Terminal

This notes is written by Sheldon. You can find me with #iOSBySheldon in Github, Youtube, Facebook, etc.

Need

Convert .mov/.MP4 to .gif

Reason

As a developer, I feel better to upload a short video when I create the pull request to show other viewers what I did in this PR. I tried .mov format directly got after finishing recording screen using Quicktime, however, gif offers preview in most web pages, and has smaller file size.

This is not limited to developer, anyone has this need can use this method to convert the files.

Thoughts

I tried to use some software to do the job, but my hands are tied since I don't have admin in my office comupter, but I do have brew installed. And I think using command line tool will be a good choice. So I will use HomeBrew, ffmpeg, gifsicle to do the job.

Solution

  1. download HomeBrew
  2. $brew install ffmpeg
  3. $brew install gifsicle
  4. $ffmpeg -i in.mov -pix_fmt rgb8 -r 10 output.gif && gifsicle -O3 output.gif -o output.gif

Explanation

  1. Convert the file to gif using ffmpeg
- input path argument `-i`
- pixel format argument `-pix_fmt`
- removing some frames using framerate argument `-r`
- end `ffmpeg` with new path/to/filename
  1. Optimize the same output file with third option -O3 and rewrite the generated gif file from last step
  2. Notes: using && to make sure the conversion sucess before optimizing

References

  1. https://brew.sh
  2. https://www.ffmpeg.org
  3. https://www.lcdf.org/gifsicle/
  4. full video tutorial with explanation https://www.youtube.com/watch?v=QKtRMFvvDL0
@SheldonWangRJT
Copy link
Author

Updated the format of the doc to be mark down for easier reading. thanks for the support guys.

@RoySegall
Copy link

RoySegall commented Sep 2, 2020

And with alias:

alias video_to_gif='function video_to_gif(){ ffmpeg -i $1 output.gif && gifsicle -O3 output.gif -o output.gif && say "Video is ready!"};video_to_gif'

And just type video_to_gif cat.mov

@SheldonWangRJT
Copy link
Author

And with alias:

alias video_to_gif='function video_to_gif(){ ffmpeg -i $1 output.gif && gifsicle -O3 output.gif -o output.gif && say "Video is ready!"};video_to_gif'

And just type video_to_gif cat.mov

👍

@artemartemov
Copy link

Updated the alias a bit instead of using the speakers, it displays a native macOS notification:

alias video_to_gif='function video_to_gif(){ ffmpeg -i "$1" "${1%.*}.gif" && gifsicle -O3 "${1%.*}.gif" -o "${1%.*}.gif" && osascript -e "display notification \"${1%.*}.gif successfully converted and saved\" with title \"MOV2GIF SUCCESS!\""};video_to_gif'

Also another example where you can specify the input and output in case you want to rename the file:

alias rename_video_to_gif='function rename_video_to_gif(){ ffmpeg -i $1 $2.gif && gifsicle -O3 $2.gif -o $2.gif && osascript -e "display notification \"$2.gif successfully converted and saved\" with title \"MOV2GIF SUCCESS!\""};rename_video_to_gif'

and you can use that with: rename_video_to_gif cat.mov my-new-file-name

@arikanev
Copy link

Any idea why this alias does not work for me?

alias v2g='function v2g(){ ffmpeg -i $1 -pix_fmt rgb8 -r 10 -s 640x360 $2 && gifsicle -O3 $2 -o $2};v2g'

ran by

v2g tr.mov tr.gif

@RoySegall
Copy link

RoySegall commented Jun 15, 2021

@arikanev Try this one:

alias video_to_gif='function video_to_gif(){ ffmpeg -i $1 $2 && gifsicle -O3 $2 -o $2 && say "Video is ready!"};video_to_gif'

# And now you can do this:
video_to_gif video.mov output2.gif

@bahamas10
Copy link

  1. thank you so much for this, this is super useful.
  2. You don't need to define a function inside an alias... you can simply just define the function once in bash.
function video_to_gif() {
  ffmpeg -i "$1" "$2" ... etc
}

# call it like normal
video_to_gif video.mov output.gif

@mcmoe
Copy link

mcmoe commented Jan 7, 2022

Lovely gist, very helpful. I've taken your ideas and wrapped them into a function for me to use as such:

function v2g() {
    src="" # required
    target="" # optional (defaults to source file name)
    resolution="" # optional (defaults to source video resolution)
    fps=10 # optional (defaults to 10 fps -- helps drop frames)

    while [ $# -gt 0 ]; do
        if [[ $1 == *"--"* ]]; then
                param="${1/--/}"
                declare $param="$2"
        fi
        shift
    done

    if [[ -z $src ]]; then
        echo -e "\nPlease call 'v2g --src <source video file>' to run this command\n"
        return 1
    fi

    if [[ -z $target ]]; then
        target=$src
    fi

    basename=${target%.*}
    [[ ${#basename} = 0 ]] && basename=$target
    target="$basename.gif"

    if [[ -n $fps ]]; then
        fps="-r $fps"
    fi

    if [[ -n $resolution ]]; then
        resolution="-s $resolution"
    fi

    echo "ffmpeg -i "$src" -pix_fmt rgb8 $fps $resolution "$target" && gifsicle -O3 "$target" -o "$target""
    ffmpeg -i "$src" -pix_fmt rgb8 $fps $resolution "$target" && gifsicle -O3 "$target" -o "$target"
    osascript -e "display notification \"$target successfully converted and saved\" with title \"v2g complete\""
}

# call it as such
# v2g --src orig.mp4 --target newname --resolution 800x400 --fps 30

@seanf
Copy link

seanf commented Jan 17, 2022

Thanks for the function @mcmoe! But maybe return 1 would be safer than exit 1 in a function. My whole shell exited the first time I ran v2g without arguments.

@mcmoe
Copy link

mcmoe commented Jan 18, 2022

Ah, a return would be much better indeed @seanf 👍
I've updated that in my fork: https://gist.github.com/mcmoe/c76895ee86bd5293d58aca7a75afb6b2 and in my comment above

@Vages
Copy link

Vages commented Aug 16, 2022

Here is a simple shell function I wrote encapsulating this:

,to-gif() {
    # Based on https://gist.github.com/SheldonWangRJT/8d3f44a35c8d1386a396b9b49b43c385
    output_file="$1.gif"

    ffmpeg -i $1 -pix_fmt rgb8 -r 10 $output_file && gifsicle -O3 $output_file -o $output_file
}

@mcmoe's function has way more options, and is probably better if you care more about your results than I 😅

@toridoriv
Copy link

Thanks! To be honest, I'm way more comfortable with the terminal than with GUIs, so this is greatly appreciated 😊

@BinaryShrub
Copy link

BinaryShrub commented Feb 7, 2023

Update on @Vages to mute console and downscale by 50% for propersize with retina on macOS

gif() {
    # Based on https://gist.github.com/SheldonWangRJT/8d3f44a35c8d1386a396b9b49b43c385
    output_file="$1.gif"
    ffmpeg -y -i $1 -v quiet -vf scale=iw/2:ih/2 -pix_fmt rgb8 -r 10 $output_file && gifsicle -O3 $output_file -o $output_file
}

@pdegnan
Copy link

pdegnan commented Sep 22, 2023

very handy, thanks!

@iBanJavascript
Copy link

Glad I came across this via ddg search. Thanks for sharing. Worked for me perfectly.

@tommydangerous
Copy link

Yea this is awesome, thank you.

@adamamyl
Copy link

adamamyl commented Feb 5, 2024

Update on @Vages to mute console and downscale by 50% for propersize with retina on macOS

gif() {
    # Based on https://gist.github.com/SheldonWangRJT/8d3f44a35c8d1386a396b9b49b43c385
    output_file="$1.gif"
    ffmpeg -y -i $1 -v quiet -vf scale=iw/2:ih/2 -pix_fmt rgb8 -r 10 $output_file && gifsicle -O3 $output_file -o $output_file
}

I got a bit annoyed by Screen Recording YYYY-MM-DD… and superflous extensions, so I've added some extension stripping (far from perfect, but YOLO) and some quoting

v2gif() {
    # Based on https://gist.github.com/SheldonWangRJT/8d3f44a35c8d1386a396b9b49b43c385
    output_file="${1%.*}.gif"
    ffmpeg -y -i "$1" -v quiet -vf scale=iw/2:ih/2 -pix_fmt rgb8 -r 10 "$output_file" && gifsicle -O3 "$output_file" -o "$output_file"
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment