Sitemap

MP4 to GIF converter with Python3 step-by-step. Tutorial.

5 min readNov 20, 2023

--

MP4 to GIF converter. Linux, Python3, FFMPEG

While writing my posts, I need to convert short videos to gifs periodically. So, one day, I decided to make this process easier. Previously, I used free online services to convert mp4 to GIFs because I am too lazy even to figure out if the program I use to capture screens can save videos to GIFs. But I am too lazy even to upload my videos to online converters, wait until everything is done, and then download them back. So, the time to make my own Free MP4 to GIF video converter has come. If you want to know how to do the same, this post is for you.

What we will need

  1. Linux server where we will run our mp4 to gif converter. I will use Ubuntu 22
  2. Python3 is installed on this server.
  3. A public guest SMB share without any authentication exists on this server. Yes, security is not part of this post, and the service will not be available from the internet.

I will run my mp4 to gif converter on Proxmox VE.

Get Artur Sagutdinov’s stories in your inbox

Join Medium for free to get updates from this writer.

mp4 to gif converter will be located in /opt/mp4-to-gif-converter and have a folder structure:

opt
└── mp4-to-gif-converter
├── backups
├── inputs
├── main.py
└── outputs

What we want our service to do

  1. Scan the ‘inputs’ folder for new files to convert.
  2. Convert files in the ‘inputs’ folder and place them in the ‘outputs’ folder.
  3. Move converted files from the ‘inputs’ folder to the ‘backups’ folder.
  4. Delete files older than N days from the ‘backups’ folder.
  5. Write some logs

Configuring SMB share

Install samba

sudo apt install samba -y

Create folders that we will share

We will create all folders with access mode 777. That means everyone can read, write, and execute files in this folder if they can access it.

sudo mkdir -p -m=777 /opt/mp4-to-gif-converter/inputs
sudo mkdir -p -m=777 /opt/mp4-to-gif-converter/outputs
sudo mkdir -p -m=777 /opt/mp4-to-gif-converter/backups

3. Configure smb.conf file

sudo nano /etc/samba/smb.conf

You must find these lines:

;   interfaces = 127.0.0.0/8 eth0
; bind interfaces only = yes

And change them to:

interfaces = 127.0.0.0/8 <your_network_interface_name>
bind interfaces only = yes

my network interface is named eth0, so my lines will look like

interfaces = 127.0.0.0/8 eth0
bind interfaces only = yes

At the bottom of the file, add our shares configuration:

[outputs]
path = /opt/mp4-to-gif-converter/outputs
public = yes
guest only = yes
writable = yes
force create mode = 0666
force directory mode = 0777
browseable = yes

[inputs]
path = /opt/mp4-to-gif-converter/inputs
public = yes
guest only = yes
writable = yes
force create mode = 0666
force directory mode = 0777
browseable = yes

[backups]
path = /opt/mp4-to-gif-converter/backups
public = yes
guest only = yes
writable = yes
force create mode = 0666
force directory mode = 0777
browseable = yes

Restart samba daemon

sudo systemctl restart smbd

As a result of this step, you must be able to open your server share on \\<your_server_ip> and find the folders you created earlier.

Install packages required for our script

sudo apt install python3-pip ffmpeg -y
sudo pip3 install ffmpeg-python

Create file main.py and paste the script there. I added explaining comments to it.

sudo nano /opt/mp4-to-gif-converter/main.py
# https://gitlab.com/adminguide/mp4-to-gif-converter
# Author: Artur Sagutdinov

import os
import time
import logging
import ffmpeg

logging.basicConfig(filename='mp4-to-gif-converter.log', encoding='utf-8', level=logging.DEBUG)
logging.debug('start')

# Path to the current script file
dir_script_path = os.path.dirname(os.path.realpath(__file__))
# Path to the inputs folder
dir_inputs_path = f'{dir_script_path}/inputs/'
# Path to the outputs folder
dir_outputs_path = f'{dir_script_path}/outputs/'
# Path to the backups folder
dir_backups_path = f'{dir_script_path}/backups/'
# Delete every file in the backups folder older than 30 days
# 1 day = 60*60*24 = 86400 seconds
delete_backups_older = 30*86400

def convert_all_once():
# List for .mp4 files found in the inputs folder
files_in_dir = []
current_time = time.time()
# Iterate through files in the inputs folder
for file_name in os.listdir(dir_inputs_path):
# If the current path in file_name is a file
if os.path.isfile(os.path.join(dir_inputs_path, file_name)):
# If this file_name hase .mp4 extension
if file_name.endswith(".mp4"):
# Add this file_name to files_in_dir list
files_in_dir.append(file_name)

# Cycle through all elements in the files_in_dir list
for file_name in files_in_dir:
# Get current file_name without extension
file_name_without_extension = file_name.split(".")[:-1]
# Use ffmpeg-python to convert mp4 to gif
(
# file_name from inputs folder
ffmpeg.input(f'{dir_inputs_path}{file_name}')
# Reduse FPS to 8
.filter('fps', fps=8, round='up')
# Save the result to the outputs folder with the .gif extension
.output(f'{dir_outputs_path}{"".join(file_name_without_extension)}.gif')
.run(overwrite_output=True)
)
# Move converted file_name from the inputs folder to the backups folder
os.rename(f'{dir_inputs_path}{file_name}',f'{dir_backups_path}{file_name}')

# Iterate through all files in a backup folder
for file_name in os.listdir(dir_backups_path):
# Get current file_name creation time
file_time = os.stat(f'{dir_backups_path}{file_name}').st_mtime
# If the file_name creation timestamp is older than the current time - delete_backups_older
if(file_time < current_time - delete_backups_older):
# delete file_name in the backup folder
os.remove(f'{dir_backups_path}{file_name}')

# Run convertation
def convert():
try:
while True:
convert_all_once()
time.sleep(5)
except Exception as err:
logging.debug(err)

convert()

Make this file executable

sudo chmod +x /opt/mp4-to-gif-converter/main.py

Create a systemd service to run our script

Create our service unit file

sudo nano /etc/systemd/system/mp4-to-gif-converter.service

And paste its config:

[Unit]
Description=MP4 to GIF Converter by Artur Sagutdinov# The description of our service
After=multi-user.target # Target after which our service will start

[Service]
Type=simple
Restart=always
RestartSec=15
# Command to run our script
ExecStart=/usr/bin/python3 /opt/mp4-to-gif-converter/main.py

[Install]
# Target where service symlink will be placed after enabling
WantedBy=multi-user.target

Start and enable our script

sudo systemctl enable mp4-to-gif-converter.service
sudo systemctl start mp4-to-gif-converter.service

Now you can just put mp4 file Everything works.

What we have as a result:

  1. Our MP4 to GIF converter service runs at IP 192.168.88.169
  2. SMB share is available on address \\192.168.88.169
  3. If we put an MP4 file into the folder inputs, it will be converted to GIF and stored to outputs. MP4 will be moved to backups
  4. Backup files are deleted after N days; for me, it is 30.
Press enter or click to view image in full size

--

--