Skip to main content

A fast, flexible Python wrapper for FFmpeg, FFprobe, and FFplay — fetch metadata, encode, split, play and run custom commands easily with real-time progress tracking.

Project description

ffwrapy

ffwrapy is a fast, flexible Python wrapper for FFmpeg, FFprobe, and FFplay — fetch metadata, encode, split, play and run custom commands easily with real-time progress tracking.


Features

  • Fetch media info (duration, size, streams) via FFprobe
  • Encode with custom codecs, presets, and metadata via FFmpeg
  • Split files or split into parts (with/without re-encoding)
  • Generate thumbnails from videos
  • Custom command execution for ffmpeg, ffprobe, ffplay
  • Track naming and title setting
  • Progress callback support for long operations (encoding, splitting, etc)
  • Pure subprocess (no dependencies except Python & FFmpeg)

Requirements

  • Python 3.x
  • FFmpeg, FFprobe, and FFplay installed and available in the system PATH

NOTE: Only FFprobe required at initialisation; FFmpeg required only during associated tasks like encoding, splitting, etc; FFplay required only during associated tasks like playback, etc;

ffmpeg -version
ffprobe -version
ffplay -version

Installation

pip install ffwrapy

Usage

Initialization

from ffwrapy import FFMedia as FFM
media = FFM(
    file="input.mp4",   # Input file
    verbose=True        # To trigger any print statements in the script; Default: False
    )

Fetching Media Info

print(media.size_mb)      # File size in MB
print(media.duration)     # Duration in seconds
print(media.audiodata)    # Audio tracks info
print(media.videodata)    # Video tracks info
print(media.subtitles)    # Subtitle tracks info

Preparing to Encode

# Naming Tracks and Title
media.name(
    aud_name="ffwrapy_aud",    # Name for all audio tracks 
    vid_name="ffwrapy_vid",    # Name for all video tracks 
    sub_name="ffwrapy_sub",    # Name for all subtitle tracks 
    title="ffwrapy title"      # Name for the output video title 
    )   # Default : <the name as defined in input file ie media>

# Defining Preset and Codecs
media.codec_vid = "libx264"     	# Name for video codec;     Default : "libx264"
media.codec_aud = "aac"         	# Name for audio codec;     Default : "aac"
media.codec_sub = "mov_text"   		# Name for subtitle codec;  Default : "mov_text"
media.crf = "23"                	# Value for crf (0-51);     Default : "23"
media.preset = "faster"         	# Preset to be used;        Default : "faster"
media.movflags = "+faststart"   	# Value for moov atom;      Default : "+faststart"
media.max_muxing_queue_size = "99"	# Max size for mux queue;   Default : "9999"

Encoding

media.encode(
    output="output.mp4",    # Name for output encoded file
    thumb="00:00:05",       # Timestamp in "HH:MM:SS" format to generate output.jpg from the processed video at the given time
    replace=True,           # Overwrite output if exists
    )
  • output Name for output encoded file
  • ss: Start time (string or seconds); Default : None (ie from beginning)
  • to: End time (string or seconds); Default : None (ie till ending)
  • thumb: Timestamp in "HH:MM:SS" format to generate output.jpg from the processed video at the given time; Default : None (ie no thumbnail generated)
  • replace: Overwrite output if exists; Default : False
  • progress_callback: Callback function to track progress; Args : (progress as a dict), (process object); Default : None
  • callback_interval: The interval (in seconds) between each callback; Default : 1

Splitting

media.split(
    output="output_clip.mp4",   # Name for output splitted file
    ss="00:01:00",              # Start time (string or seconds)
    to="00:02:00",              # End time (string or seconds)
    replace=True,               # Overwrite output if exists
    )
  • output Name for output splitted file
  • ss: Start time (string or seconds); Default : None (ie from beginning)
  • to: End time (string or seconds); Default : None (ie till ending)
  • thumb: Timestamp in "HH:MM:SS" format to generate output.jpg from the processed video at the given time; Default : None (ie no thumbnail generated)
  • replace: Overwrite output if exists; Default : False
  • progress_callback: Callback function to track progress; Args : (progress as a dict), (process object); Default : None
  • callback_interval: The interval (in seconds) between each callback; Default : 1

Splitting into Parts

media.split_parts(
    output = "part.mp4",    # Base name for the output
    parts=3,                # Number of parts to split into
    safe_time=5,            # Repetion duration (in seconds) between each part to conserve any diversion
    reencode=False,         # Whether to reencode the file
    )
  • output Base name for the output; if a string is provided, forms an array with each element as 'i_out' where i is the part name and out is the provided string; if an array is provided, the elements of array are used as the part name
  • parts Number of parts to split into; Default : 2
  • safe_time Repetion duration (in seconds) between each part to conserve any diversion; Default : 5
  • reencode=True Whether to reencode the file (accurate but takes time), reencode uses .encode() otherwise .split() is used which is quick but may not be accurate; Default : False
  • thumb: Timestamp in "HH:MM:SS" format to generate output.jpg from the processed video at the given time; Default : None (ie no thumbnail generated)
  • replace: Overwrite output if exists; Default : False
  • progress_callback: Callback function to track progress; Args : (progress as dict), (process object), (serial number of part as int); Default : None
  • callback_interval: The interval (in seconds) between each callback; Default : 1

Thumbnail Generation

media.thumbnail(
    replace=True    # Overwrite output if exists
    )
  • timestamp The timestamp in the input file at which thumbnail is to be generated; Default : "00:00:05"
  • file The input filename whose thumbnail is to be generated; Default: None (ie media.file)
  • replace: Overwrite output if exists; Default : False

Playback

media.play(
    volume=50,              # Playback volume (0 to 100)
    audio=1,                # Audio stream index to play
)
  • seek: Start playback after skipping given time (in seconds); Default: 0
  • duration: Stop playback after this duration; Default: None (ie till end)
  • volume: Set audio volume for playback in percentage (0–100); Default: 50
  • audio: Select audio stream index (as per media) to play; Default : None (ie first available audio stream)
  • video: Select video stream index (as per media) to play; Default : None (ie first available video stream)
  • subtitle: Select subtitle stream index (as per media) to play; Default : None (ie first available subtitle stream)
  • width : Resize the playback window width; Default: None (ie original width) height : Resize the playback window height; Default: None (ie original height)
  • disable_audio : Disable the audio stream playback; Default: False
  • disable_video : Disable the video stream playback; Default: False
  • disable_subtitle : Disable the subtitle stream playback; Default: False

Custom FFmpeg/FFprobe/FFplay Command

media.custom_ffmedia(
    customisation=["ffprobe", "-hide_banner", media.file]
    )
media.custom_ffm(
    customisation=["ffprobe", "-hide_banner", media.file]
    )   # Same as .custom_ffmedia()

media.custom_ffmedia(
    customisation=["ffplay", media.file]
    )
media.custom_ffm(
    customisation=["ffplay", media.file]
    )  # Same as .custom_ffmedia()
  • customisation The custom cmd array for FFmpeg/FFprobe/FFplay Command
  • thumb: Timestamp in "HH:MM:SS" format to generate output.jpg from the processed video at the given time; Default : None (ie no thumbnail generated)
  • replace: Overwrite output if exists; Default : False
  • progress_callback: Callback function to track progress; Args : (progress as dict), (process object); Default : None
  • callback_interval: The interval (in seconds) between each callback; Default : 1

Example Workflow

from ffwrapy import FFMedia as FFM

media = FFM("movie.ts", verbose=True)
media.name("HIN", "Main", "HIN Subs", title="Demo Movie")
media.encode("movie.mkv", thumb="00:00:05")

media_encoded = FFM("movie.mkv")
media_encoded.split("movie_clip.mp4", ss="00:10:00", to="00:15:00")
media_encoded.split_parts("movie_part.mp4", parts=4)
media_encoded.thumbnail()

media_encoded.custom_ffmedia(["ffmpeg", "-i", media_encoded.file, "-vn", "-acodec", "copy", "audio.aac"])

media_encoded.play()

Notes

  • All operations use subprocess calls to FFmpeg/FFprobe/FFplay; ensure these are installed and accessible.
  • Error handling is basic; adapt for production use as needed.
  • Extend or modify the class for advanced workflows.

License

Apache License 2.0

This library is open-source and free to use under the Apache 2.0 License.


Contributing

Contributions, suggestions, and feature requests are welcome! Feel free to submit an issue or PR.


Author

Developed by भाग्य ज्योति (Bhagya Jyoti)


Happy media processing!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ffwrapy-1.1.0.tar.gz (13.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ffwrapy-1.1.0-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file ffwrapy-1.1.0.tar.gz.

File metadata

  • Download URL: ffwrapy-1.1.0.tar.gz
  • Upload date:
  • Size: 13.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for ffwrapy-1.1.0.tar.gz
Algorithm Hash digest
SHA256 f0b926519e2981ca954cbd707aa794840704076c87ec58d96beb0b20595a0f4b
MD5 66b6f23710f374e200730c2ef8cea362
BLAKE2b-256 9d564bb67dde45677300b9ad29c7c9b50ac436a67388f2602ed68b372b91ca13

See more details on using hashes here.

Provenance

The following attestation bundles were made for ffwrapy-1.1.0.tar.gz:

Publisher: pypi.yml on BhagyaJyoti22006/ffwrapy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ffwrapy-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: ffwrapy-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for ffwrapy-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 08637080a0f2fd127dd2e78d943675b08b6a83028d2647d9f44c2f696bc46d9a
MD5 d4e6c7d35438e4c8ca32c7f7a30fe290
BLAKE2b-256 9566228d3e75d15561929ba29bdea4cc39f0ff91306f8483ca863085c57b052e

See more details on using hashes here.

Provenance

The following attestation bundles were made for ffwrapy-1.1.0-py3-none-any.whl:

Publisher: pypi.yml on BhagyaJyoti22006/ffwrapy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page