• Home
  • Guides
    • All
    • Linux
    • Programming
    • Tools
    How to Loop and Resize MP4 Videos with Python and FFmpeg on Linux

    How to Loop and Resize MP4 Videos with Python and FFmpeg on Linux

    Understanding Linux File Permissions

    Understanding Linux File Permissions

    Building a Python Broken Link Checker

    Building a Python Broken Link Checker

    Working With Webhooks in PHP

    Working With Webhooks in PHP

    My Backup Setup for Linux PCs

    My Backup Setup for Linux PCs

    Detecting Hidden WordPress Malware Disguised as Images

    Detecting Hidden WordPress Malware Disguised as Images

    Server-Side Image Conversion with Apache

    Server-Side Image Conversion with Apache

    Fastest Way to Extract a Massive .tar.gz File on Linux

    Fastest Way to Extract a Massive .tar.gz File on Linux

    Monitor SSL Expiration with Python

    Monitor SSL Expiration with Python

  • Blog
    • All
    • Artificial Intelligence
    • Developer Life
    • Privacy
    • Reviews
    • Security
    • Tutorials
    What Drawing and Animating in BASIC Taught Me About Programming

    What Drawing and Animating in BASIC Taught Me About Programming

    Why I Stopped Treating SMS As Good Enough

    Why I Stopped Treating SMS As Good Enough

    Why I Built My Own Ad Server Instead of Relying on Outdated Platforms

    Why I Built My Own Ad Server Instead of Relying on Outdated Platforms

    How I Stay Focused When Working on Long Term Projects

    How I Stay Focused When Working on Long Term Projects

    Imposter Syndrome as a Self-Taught Developer

    Imposter Syndrome as a Self-Taught Developer

    Why Stable Websites Outperform Flashy Redesigns

    Why Stable Websites Outperform Flashy Redesigns

    AdGuard Ad Blocker Review

    AdGuard Ad Blocker Review

    Surfshark VPN Review

    Surfshark VPN Review

    Nmap Unleash the Power of Cybersecurity Scanning

    Nmap: Unleash the Power of Cybersecurity Scanning

  • Apps
    • Bible App
    • Bible Verse Screensaver
    • Blue AI Chatbot
    • Early Spring Predictor
    • FIGlet Generator
    • Password Generator
    • StegX
    • The Matrix
    • WeatherX
    • Website Risk Level Tool
  • About
    • About JMooreWV
    • Live Cyber Attack Stats
  • Contact
    • General Contact
    • Website Administration & Cybersecurity
No Result
View All Result
  • Home
  • Guides
    • All
    • Linux
    • Programming
    • Tools
    How to Loop and Resize MP4 Videos with Python and FFmpeg on Linux

    How to Loop and Resize MP4 Videos with Python and FFmpeg on Linux

    Understanding Linux File Permissions

    Understanding Linux File Permissions

    Building a Python Broken Link Checker

    Building a Python Broken Link Checker

    Working With Webhooks in PHP

    Working With Webhooks in PHP

    My Backup Setup for Linux PCs

    My Backup Setup for Linux PCs

    Detecting Hidden WordPress Malware Disguised as Images

    Detecting Hidden WordPress Malware Disguised as Images

    Server-Side Image Conversion with Apache

    Server-Side Image Conversion with Apache

    Fastest Way to Extract a Massive .tar.gz File on Linux

    Fastest Way to Extract a Massive .tar.gz File on Linux

    Monitor SSL Expiration with Python

    Monitor SSL Expiration with Python

  • Blog
    • All
    • Artificial Intelligence
    • Developer Life
    • Privacy
    • Reviews
    • Security
    • Tutorials
    What Drawing and Animating in BASIC Taught Me About Programming

    What Drawing and Animating in BASIC Taught Me About Programming

    Why I Stopped Treating SMS As Good Enough

    Why I Stopped Treating SMS As Good Enough

    Why I Built My Own Ad Server Instead of Relying on Outdated Platforms

    Why I Built My Own Ad Server Instead of Relying on Outdated Platforms

    How I Stay Focused When Working on Long Term Projects

    How I Stay Focused When Working on Long Term Projects

    Imposter Syndrome as a Self-Taught Developer

    Imposter Syndrome as a Self-Taught Developer

    Why Stable Websites Outperform Flashy Redesigns

    Why Stable Websites Outperform Flashy Redesigns

    AdGuard Ad Blocker Review

    AdGuard Ad Blocker Review

    Surfshark VPN Review

    Surfshark VPN Review

    Nmap Unleash the Power of Cybersecurity Scanning

    Nmap: Unleash the Power of Cybersecurity Scanning

  • Apps
    • Bible App
    • Bible Verse Screensaver
    • Blue AI Chatbot
    • Early Spring Predictor
    • FIGlet Generator
    • Password Generator
    • StegX
    • The Matrix
    • WeatherX
    • Website Risk Level Tool
  • About
    • About JMooreWV
    • Live Cyber Attack Stats
  • Contact
    • General Contact
    • Website Administration & Cybersecurity
No Result
View All Result
Home Guides Programming Python

How to Loop and Resize MP4 Videos with Python and FFmpeg on Linux

Jonathan Moore by Jonathan Moore
6 seconds ago
Reading Time: 8 mins read
A A
How to Loop and Resize MP4 Videos with Python and FFmpeg on Linux
FacebookTwitter

Sometimes I need a short video to run much longer than the original clip. That might be an animated background, an ambient visual, a music video backdrop, a video overlay, or a simple social media clip that needs to fill a specific length. I do not always want to open a full video editor for that kind of job. If the source clip already looks and sounds right, I usually just want a repeatable way to stretch it into a longer file.

FFmpeg is perfect for that kind of task because it can loop an input video and stop the output after a specific duration. The command line version is already fast, but I also like wrapping common FFmpeg commands in small Python scripts. That gives me something reusable that can later be connected to file manager actions, batch tools, or other automation scripts. The Python code does not process the video itself. It simply builds and runs the FFmpeg command for me.

This article is written with Linux Mint and Ubuntu users in mind, but the same commands should work on most Linux distributions with FFmpeg installed. I am going to keep the examples focused on MP4 files because that is one of the most common formats people deal with. The same ideas can be adjusted for other formats, but MP4 keeps the workflow easy to test.

Installing FFmpeg On Linux Mint Or Ubuntu

Linux Mint and Ubuntu make FFmpeg easy to install through apt. If FFmpeg is already installed, these commands will either confirm that or update it through the normal package process. I usually start here before writing any script because the Python wrapper depends on the ffmpeg command being available in the system path.

sudo apt update
sudo apt install ffmpeg

After installation, check that FFmpeg responds from the terminal. The version output will include build information and enabled libraries. You do not need to understand every line of that output for this article. The important part is that the command runs successfully.

ffmpeg -version

If your distribution uses a different package manager, install FFmpeg through that distribution’s normal software tools. The rest of the examples still use the same ffmpeg command once it is installed. That consistency is one reason FFmpeg is so useful for automation.

Looping An MP4 For 30 Minutes With FFmpeg

The basic FFmpeg command for this job is short. It tells FFmpeg to repeat the input forever, then stops writing the final output after 1800 seconds. Since 1800 seconds is 30 minutes, that gives us a finished 30 minute video from a short source clip.

ffmpeg -stream_loop -1 -i input.mp4 -t 1800 -c copy output_30min.mp4

The -stream_loop -1 option tells FFmpeg to loop the input indefinitely. The -i input.mp4 option points FFmpeg to the source video. The -t 1800 option tells FFmpeg to stop the output at 1800 seconds. The -c copy option copies the existing video and audio streams instead of re-encoding them.

That last option is what makes this command fast. When FFmpeg can stream copy the video and audio, it does not have to decode and encode every frame again. That preserves the original quality and avoids wasting time on a conversion that is not needed. For a simple loop from a clean source file, this is usually the first version I try.

There is one catch worth knowing. Some MP4 files can have timestamp or playback issues when stream-copying repeated content. If the loop boundary behaves oddly, the output has audio drift, or a media player reports strange duration information, re-encoding may be the safer option. Stream copying is fast, but re-encoding gives FFmpeg more control over the final timeline.

A Reusable Python Wrapper For Looping Video

The command line version is fine when I only need to do the job once. If I expect to repeat the task, I prefer a small Python script. The script below accepts an input filename, an optional output filename, and an optional duration in minutes. If I do not specify a duration, it creates a 30 minute loop by default.

This script uses Python’s standard library, so there are no extra Python packages to install. The only external requirement is FFmpeg itself. It checks whether the input file exists, builds a sensible output filename when one is not provided, converts minutes to seconds, and then runs FFmpeg through subprocess.run. I like wrappers like this because they keep the workflow readable without hiding what FFmpeg is doing.

#!/usr/bin/env python3

import argparse
import subprocess
import sys
from pathlib import Path


def loop_video(input_file, output_file=None, minutes=30):
    input_path = Path(input_file)

    if not input_path.exists():
        print(f"Error: File not found: {input_path}")
        sys.exit(1)

    if output_file:
        output_path = Path(output_file)
    else:
        output_path = input_path.with_name(
            f"{input_path.stem}_{minutes}min{input_path.suffix}"
        )

    duration = minutes * 60

    command = [
        "ffmpeg",
        "-y",
        "-stream_loop", "-1",
        "-i", str(input_path),
        "-t", str(duration),
        "-c", "copy",
        str(output_path),
    ]

    print(f"Creating {minutes}-minute loop...")
    print(f"Input:  {input_path}")
    print(f"Output: {output_path}")

    try:
        subprocess.run(command, check=True)
        print("Done.")
    except FileNotFoundError:
        print("Error: ffmpeg is not installed or is not in PATH.")
        sys.exit(1)
    except subprocess.CalledProcessError:
        print("Error: ffmpeg failed to create the looped video.")
        sys.exit(1)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Loop an MP4 video to a specified duration."
    )

    parser.add_argument(
        "input",
        help="Input MP4 file"
    )

    parser.add_argument(
        "-o", "--output",
        help="Output MP4 file"
    )

    parser.add_argument(
        "-m", "--minutes",
        type=float,
        default=30,
        help="Final video length in minutes (default: 30)"
    )

    args = parser.parse_args()

    loop_video(args.input, args.output, args.minutes)

The -y option in the generated FFmpeg command allows FFmpeg to overwrite an existing output file. That is convenient when I am testing, but it is also something to notice before running the script on important files. If you do not want automatic overwriting, remove "-y" from the command list. I usually keep it in small utility scripts because I know when I am intentionally regenerating the same output.

Saving And Running The Script

Save the script as loop_video.py in the same folder as the video you want to process, or save it somewhere else and pass the full path to the input file. After saving it, make it executable. That lets you run it directly from the terminal like a normal command.

chmod +x loop_video.py
./loop_video.py short-video.mp4

With no output filename specified, the script creates a name based on the original file. For example, short-video.mp4 becomes something like short-video_30min.mp4. That is handy because it keeps the original file untouched. I prefer that behavior for utilities that transform media files.

You can also choose the output filename yourself. This is useful when the finished video has a purpose, such as a background clip or a video overlay. The script passes that filename directly to FFmpeg as the final output path.

./loop_video.py short-video.mp4 -o background.mp4

If you want a different duration, use the -m or --minutes option. This example creates a 60 minute version of the input video. Since the script accepts a floating point value, shorter values like 2.5 also work when you need a quick test file.

./loop_video.py short-video.mp4 -m 60

This is still just a Python wrapper around FFmpeg. That is a good thing. FFmpeg remains responsible for the actual media work, while Python handles argument parsing, filenames, validation, and reuse. That same pattern works well when adding video processing to file manager actions, batch scripts, folder watchers, web tools, or larger Python applications.

Resizing A 1080p Video Down To 720p

Looping a video and resizing a video are different jobs. The loop command can often copy the original streams because it is not changing the picture itself. Resizing changes every video frame. That means FFmpeg has to decode the video, scale the frames, and encode a new video stream.

Here is a practical FFmpeg command for resizing a 1080p MP4 down to 720p. It keeps the original aspect ratio, encodes the new video with H.264, and copies the original audio without re-encoding it. For most normal video files, this is a good starting point.

ffmpeg -i input.mp4 -vf scale=-2:720 -c:v libx264 -crf 20 -preset medium -c:a copy output_720p.mp4

The scale=-2:720 filter tells FFmpeg to set the height to 720 pixels and calculate the width automatically. The -2 value keeps the width divisible by 2, which avoids compatibility problems with common video encoders. A standard 1920×1080 video will become 1280×720. If the source uses a different aspect ratio, FFmpeg will calculate the matching width for that shape.

The -c:v libx264 option encodes the new video stream using H.264. The -crf 20 option controls quality and file size. Lower CRF values mean higher quality and larger files, while higher values create smaller files with more compression. A value around 20 is a good balance for many practical uses.

The -preset medium option controls encoding speed versus compression efficiency. Slower presets usually take longer but may create smaller files at the same CRF value. Faster presets finish sooner but may not compress quite as efficiently. The -c:a copy option keeps the original audio stream as-is, which saves time and avoids unnecessary audio quality loss.

A Faster 720p Resize Command

If I need the resize to finish faster, I use a faster preset. The output quality target is still controlled by -crf 20, but the encoder spends less time trying to compress the file efficiently. This is useful for previews, drafts, quick uploads, or situations where waiting longer is not worth a smaller file.

ffmpeg -i input.mp4 -vf scale=-2:720 -c:v libx264 -crf 20 -preset fast -c:a copy output_720p.mp4

The tradeoff is simple. -preset fast usually completes sooner than -preset medium. The file may be a little larger because the encoder did less compression work. If I am making a final copy that I plan to keep, I usually start with medium. If I am testing or making a quick shareable version, fast is often good enough.

Why -c copy Does Not Work For Resizing

The -c copy option only works when FFmpeg can copy the existing stream without changing it. That is why it can be useful for looping, trimming, remuxing, or combining compatible streams. Resizing is different because the video frames must be changed. Once the frame size changes, the old video stream cannot simply be copied into the new file.

When you resize from 1080p to 720p, FFmpeg has to create a new video stream. It reads the original frames, scales them to the new resolution, and encodes them again with the selected codec. That is why the resize command uses -c:v libx264 instead of -c copy. The audio can still be copied because the resize does not change the audio stream.

Troubleshooting Common Problems

If the Python script says FFmpeg is not installed or not in the path, run ffmpeg -version directly in the terminal. If that command fails, install FFmpeg with sudo apt install ffmpeg. If FFmpeg is installed but Python still cannot find it, check that you are running the script from the same environment where FFmpeg is available.

If the output file already exists, the script will overwrite it because the FFmpeg command includes -y. That is intentional in the provided script, but it may not be what you want every time. Rename the output file with -o, move the old file, or remove "-y" from the Python command list if you want FFmpeg to ask before replacing files.

If you notice audio pops, timestamp warnings, odd duration reporting, or playback problems at loop boundaries, try re-encoding instead of stream copying. Stream copying is fast, but some MP4 files do not behave perfectly when repeated this way. Re-encoding takes longer, but it can produce a cleaner timeline when the source file has timestamp quirks.

If a resized 720p file is larger than expected, raise the CRF value. A value like -crf 23 will usually create a smaller file than -crf 20, but with more compression. You can also try a slower preset if you have time and want better compression efficiency. The best setting depends on whether you care more about quality, file size, or encoding speed.

Final Thoughts

FFmpeg does the real video processing in this workflow. It can loop a short MP4 into a 30 minute file, copy streams quickly when possible, and resize a 1080p video down to 720p when re-encoding is needed. Once the commands make sense, they become reliable building blocks for everyday video tasks on Linux Mint.

Python makes the workflow easier to reuse. Instead of remembering the full loop command every time, I can run a small script with a filename and optional settings. That is the part I like most about pairing Python with FFmpeg. FFmpeg handles the heavy lifting, and Python turns the command into something easier to automate, repeat, and build into other tools.

Tags: AutomationFFmpegLinuxPythonVideo
ShareTweetSharePinShareShareScan
ADVERTISEMENT
Jonathan Moore

Jonathan Moore

I am a Software Architect and Senior Software Engineer with 30+ years of experience building applications for Linux and Windows systems. I focus on system architecture, custom web platforms, server infrastructure, and security-focused tools, with an emphasis on performance and reliability. Over the years, I have built everything from WordPress plugins and automation systems to full platforms, ad serving systems, monitoring tools, and API-driven applications. I prefer working close to the system, solving real problems, and building tools that are meant to be used.

Related Articles

Understanding Linux File Permissions

Understanding Linux File Permissions

File permissions are one of those Linux topics that look simple until something breaks. A script will not run, a...

Building a Python Broken Link Checker

Building a Python Broken Link Checker

Broken links have a way of hiding until they become somebody else's problem. A page gets renamed, a migration misses...

Working With Webhooks in PHP

Working With Webhooks in PHP

I have used webhooks in a lot of different situations over the years, from payment alerts to form submissions to...

Recommended Services

Latest Articles

How to Loop and Resize MP4 Videos with Python and FFmpeg on Linux

How to Loop and Resize MP4 Videos with Python and FFmpeg on Linux

Sometimes I need a short video to run much longer than the original clip. That might be an animated background,...

Read moreDetails

Understanding Linux File Permissions

Understanding Linux File Permissions

File permissions are one of those Linux topics that look simple until something breaks. A script will not run, a...

Read moreDetails

Building a Python Broken Link Checker

Building a Python Broken Link Checker

Broken links have a way of hiding until they become somebody else's problem. A page gets renamed, a migration misses...

Read moreDetails

What Drawing and Animating in BASIC Taught Me About Programming

What Drawing and Animating in BASIC Taught Me About Programming

My first real introduction to programming came through BASICA and GWBASIC on a Tandy 2000 my father got in 1990...

Read moreDetails
  • Privacy Policy
  • Terms of Service
  • Legal Policies

© 2026 JMooreWV. All rights reserved.

No Result
View All Result
  • Home
  • Guides
    • Linux
    • Programming
      • JavaScript
      • PHP
      • Python
    • Tools
    • WordPress
  • Blog
    • Artificial Intelligence
    • Tutorials
    • Privacy
    • Security
  • Apps
    • Bible App
    • Bible Verse Screensaver
    • Blue AI Chatbot
    • Early Spring Predictor
    • FIGlet Generator
    • Password Generator
    • StegX
    • The Matrix
    • WeatherX
    • Website Risk Level Tool
  • About
    • About JMooreWV
    • Live Cyber Attack Stats
  • Contact
    • General Contact
    • Website Administration & Cybersecurity