libdv,
ffmpeg (and to a lesser extent) mplayer could
prove tricky; if you have any trouble building this framework on Windows,
then give some consideration to building it in a
MinGW and/or
Cygwin environment.
setup.py:
$ python setup.py build
$ sudo python setup.py install
Password:
$
One common cause of build failure is an out-of-date or otherwise incompatible
version of Cython. One thing you can try is to remove Cython from your system, and install the one enclosed with this package:
$ cd 3rdparty/cython/cython-package
$ python setup.py build
$ sudo python setup.py install
Password:
$ cd ../../..
$
then try the DVEdit build again.
dvedit.Clip
frame = myclip[12]for frame in myclipnframes = len(myclip)myclip.append(newframe)
or myclip[400] = newframe
bigclip = clip1 + clip2excerpt = clip1[100:325]Clip and its subclasses
has a method .render(), which will render the video out
to file of any chosen format (within the limitations of ffmpeg).
Clip.
Clip:
BlankClip - a clip of arbitrary length which contains
only blank framesFile - gives read/write access to video filesSlice - an excerpt of another clip, the result of taking
a slice of the clipSum - two clips spliced together, the result of adding
two clips together with the '+' operatorTransition - one clip fading to another; by implementing
subclasses of Transition, different transition effects
can be createdSequence - zero or more clips arranged in a timeline,
analogous to a 'track' in conventional video editorsStack - zero or more clips arranged as layers in a
vertical stack;
when rendering, frames will be taken from the first layer which gives
a non-blank frameClip (or subclass) objects represent a set of audio/video
frames. Indexing a clip will return a Frame object, which
contains either the raw audio/video data, or the encoded DV data for this,
or both.
Filter extension type.
Slice,
Sum, Transition, Sequence and
Stack are all based on containing other Clip
objects, so it's quite OK for example to have a Stack containing
a Sequence which contains a Stack which contains
a Sequence which contains a Slice which contains
a Stack which contains a File and a Sum and so on. Any class which honours the basic Clip interface
may be used as a component of these containing classes.
Clip objects, as a rule, do not actually contain Frame objects. Instead, Frame objects are created
on demand and returned whenever such Clip objects are indexed.
File object possesses only the ability to open
a video file, seek to a given position, and read or write a block of encoded
DV data.
frame.ensureDecodedAsYuv() - causes the frame to, if
necessary, convert its internal video representation to a YCbCr 4:2:2
called YUY2,
in which case the video buffer contains a sequence of pixel pairs,
where each pixel pair comprises the four-byte sequence:
| Y0 | Cb | Y1 | Cr |
(Y0,Cb,Cr), and the second pixel is defined by
(Y1,Cb,Cr)
frame.ensureDecodedAsRgb() - causes the frame to, if
necessary, convert its internal video representation to RGB,
in which case the video buffer contains a sequence of single pixels,
where each pixel consists of the three-byte sequence:
| R | G | B |
raw.vob and renders it out as a medium-quality
Quicktime4Linux video myvid.mov:
#!/usr/bin/env python
from dvedit.core import *
# open the input video
clip = File("raw.vob")
# 125 frames @ 25fps = 5 secs
excerpt = clip[:125]
# now render it out as an AVI with MPEG4 video, MP3 audio
excerpt.render("myvid.avi",
"-f avi -vcodec mpeg4 -acodec libmp3lame -b 5000000")
No processing has been done on the video, apart from cutting a 5 second excerpt and saving it out as an excerpt.
dvedit.core.Clip. This class allows video files
to be accessed in a manner similar to Python lists.
.numFrames - integer - declares the length of the clip
in frames. In your subclass, you must keep this attribute up to date.
getFrame(frameno) - C method - takes an integer argument
frameno and returns a Frame object. In your
subclass, you will typically override this method.
dvedit.transitions.transition.Transition and provide
the methods init() and blendFrames().
Study the source files dvedit/transitions/transition.pyx
and dvedit/transitions/crossfade.pyx.
transition.pyx contains the Transition
base class, whose docstring describes the requirements for subclassing.
crossfade.pyx contains an implementation for a simple
cross-dissolve transition. You can use this as a model for creating
your own transitions.
.pyx file
in dvedit/filters, and in that file, create a subclass of
Filter.
from dvedit.core cimport Filter, Frame, COLOR_RGB
cdef class InverseFilter(Filter):
cdef Frame getFrame(self, int idx):
cdef int i, nbytes
cdef Frame frame
# we just fetch from the sequence (or further up the filter stack)
# a frame at the same point in time
frame = self.getSourceFrame(idx)
# make sure the frame is decoded, and set it so it needs re-encoding
frame.ensureDecoded(COLOR_RGB)
frame.hasEncoded = 0
# ohh, hardwired assumption of PAL in RGB :(
nbytes = 720 * 576 * 3
for i from 0 <= i < nbytes:
frame.videoBuf[i] = 255 - frame.videoBuf[i]
# all done
return frame
A couple of notes here:
getFrame()
getSourceFrame(). This method takes
care of figuring out whether there are any filters that are active
at the same point in time, and pulling the needed frames from those
filters (or if no other filters, from the Sequence itself).
from dvedit.core import *
from dvedit.filters.inverse import InverseFilter
from dvedit.filters.flip import FlipFilter
from dvedit.filters.reverse import ReverseFilter
clip1 = File("clip1.mpg")
# create sequence, add clip
seq = Sequence()
seq.add(clip1)
# add some filters
seq.filter(ReverseFilter) # this will apply for the full duration of the sequence
seq.filter(InverseFilter, 50, 100) # applies at frame 50 for 100 frames
seq.filter(FlipFilter, 100, 100) # applies at frame 100 for 100 frames
seq.render("filtertest.dv")