y4m
A simple, intuitive, powerful and extensible framework for video editing
in Python.
Features:
- Great Python classes for reading, writing and manipulating YUV4MPEG
video streams (or almost any type of video stream, for that matter)
- Pyrex-based Python bindings for
MJPEGtools 'yuv4mpeg' API.
- Easy plugin architecture allows rapid development of plugins in C for
processing speeed
- Many off-the-shelf processing effects, including:
- scale
- zoom
- crop
- transparency
- chroma key
- polygon fill or make transparent (inside or outside)
- flips - vertical and horizontal
- overlays
- arbitrary rotation
- cross-fade
- more effects being developed as you're reading this
- automated keyframe interpolation
- 20+ simple and well-commented example scripts
Download: y4m-0.1.3.tar.gz.
Here's a minimal example of basic yuv4mpeg Python usage:
import sys
import y4m
# create an input yuv4mpeg stream
sIn = y4m.Stream(sys.stdin)
# suck the stream header, so we know the format
sIn.readHeader()
# create output stream, same format as input
# stream, sending its output to a file
sOut = y4m.Stream("foo.yuv", "w", copy=sIn)
# now move all the frames
while True:
try:
frm = sIn.readFrame()
except EOFError:
break
sOut.writeFrame(frm)
Here's a filter in Python that actually has some use:
"""
yuvexcerpt.py - a simple tool for extracting an excerpt of video from
standard input.
"""
import sys, os, traceback, getopt
import y4m
progname = sys.argv[0]
args = sys.argv[1:]
def getarg():
return args.pop(0)
def usage(msg=None):
"""
spit usage info and quit with error
"""
if msg:
sys.stderr.write(msg+"\n")
sys.stderr.write("\n".join([
"Usage: %s [-ss starttime] [-t endtime]" % progname,
"Type '%s -h' for help" % progname,
"",
]))
sys.exit(1)
def help():
"""show help info and quit with no error"""
sys.stderr.write("\n".join([
"%s: Cut an excerpt of a stream, based on time" % progname,
"Options:",
" -ss - set start time in seconds, default 0.0 (from beginning)",
" -t - length of excerpt to pass through - default -1 (to end)",
" -h, --help - display this help",
"Valid time format is [[hh:]mm:]ss[.ss]",
"",
]))
sys.exit(0)
def parsetime(arg):
"""
parse a given time value - refer help()
"""
try:
parts = arg.split(":")
hours = mins = secs = 0.0
secs = float(parts.pop())
if parts:
mins = int(parts.pop())
if parts:
hours = int(parts.pop())
except:
usage("invalid time format" % progname)
return hours * 3600 + mins * 60 + secs
def runPipe(startTime, length):
"""
transfer an excerpt of yuv from stdin to stdout
"""
sys.stderr.write("Creating input stream\n")
sIn = y4m.Stream(sys.stdin)
sys.stderr.write("Reading header\n")
sIn.readHeader()
sys.stderr.write("Creating output stream\n")
sOut = y4m.Stream(sys.stdout, "w", copy=sIn)
sys.stderr.write("Writing header\n")
sOut.writeHeader()
curTime = 0.0
if length > 0:
endTime = startTime + length
else:
endTime = 1000000000
# get framerate, convert from ratio to float
fps = sIn.fps
fps = 1.0 * fps[0] / fps[1]
# and derive seconds per frame
framePeriod = 1.0 / fps
sys.stderr.write("fps=%f period=%f\n" % (fps, framePeriod))
# the big loop
while (curTime < endTime):
try:
frm = sIn.readFrame()
except EOFError:
break
curTime += framePeriod
if curTime >= startTime and curTime < endTime:
sOut.writeFrame(frm)
def main():
"""
the front end
"""
# set default parameters
startTime = 0.0
length = -1
# fetch/validate args
while args:
arg = getarg()
if arg == '-ss':
startTime = parsetime(getarg())
elif arg == '-t':
length = parsetime(getarg())
elif arg in ['-h', '--help']:
help()
else:
usage()
try:
runPipe(startTime, length)
except KeyboardInterrupt:
sys.stderr.write("Terminated by user\n")
return
if __name__ == '__main__':
main()