PDA

View Full Version : How can I generate an N-Frame-long Filmstrip?


Karyudo
31st July 2005, 08:25
I can't seem to find anything like what I want, so in the spirit of AviSynth DIY scripting, I'm hoping that if I start with some ideas of what I might try, some gurus might be able to contribute faster, more concise, or more elegant ideas...

I want as output a horizontal or vertical strip of mini-frames of a user-specified size and number, left-, right- or centre- aligned on a given frame.

Maybe a script or function with a call along the lines of:

FilmStrip(string "orientation", int "frames", int "size", string "alignment")

where

orientation: either "h" or "v" for horizontal or vertical
frames: number of frames per filmstrip
size: range 1-100; percentage of input frame size (i.e. keep AR the same)
alignment: one of "l", "c" or "r" for filmstrip alignment to current frame

I imagine StackHorizontal and StackVertical might be useful. Same with LanczosResize. Not at all sure how to grab data from frames before or after the current frame, and no clue how to make the number, orientation or alignment flexible.

The application I'd like to use this for is to clearly show the differences between film reel edit points on different releases of the same film. You'd be able to line up on the last frame of one reel, say, and see the frames just before and just after the edit all in the same image.

Any snippets of code or links to other threads I should know about?

Thanks in advance...

stickboy
31st July 2005, 10:08
Not at all sure how to grab data from frames before or after the current frameYou're thinking about it in the wrong way.

A clip is a stream of frames. Forget about any notion of a "current frame".

Let's say your start out with a clip:clip : 0 1 2 3 4 5 ... nSo now you want to have each frame to have three rows of frames, vertically aligned:0 1 2 3 4 ... n
1 2 3 4 5 ... n + 1
2 3 4 5 6 ... n + 2That should give you a pretty clear idea what you need to do:src = AVISource("someVideo.avi")
StackVertical(src,
\ src.Trim(1, 0),
\ src.Trim(2, 0))But you probably want the center row to start at frame 0 and to stop on the last frame:- 0 1 2 3 ... n - 1
0 1 2 3 4 ... n
1 2 3 4 5 ... -
src = AVISource("someVideo.avi")

# Bookend the clip with dummy frames.
blankFrame = src.BlankClip(length=1)
StackVertical(blankFrame ++ src.Trim(0, -(src.FrameCount() - 1)),
\ src,
\ src.Trim(1, 0) ++ blankFrame)no clue how to make the number, orientation or alignment flexibleThat's harder. If you want to handle an arbitrary number of rows with a script-defined function, you'll have to use recursion:function StackVerticalStaggered(clip c, int n, clip "blankFrame")
{
Assert(n > 0)
blankFrame = Default(blankFrame, c.BlankClip(length=1))
Assert(blankFrame.FrameCount() == 1)
return (n == 1)
\ ? c
\ : StackVertical(c,
\ StackVerticalStaggered(c.Trim(1, 0) ++ blankFrame,
\ n - 1,
\ blankFrame))
}Combining this, you can do:

function FilmStrip(clip c, int "frameRadius")
{
# frameRadius specifies the number of rows above or below
# the center row. The total number of rows will be
# frameRadius * 2 + 1.
frameRadius = Default(frameRadius, 1)
Assert(frameRadius > 0)

blanks = c.BlankClip(length=frameRadius)

firstRow = blanks ++ c
stacked = firstRow.StackVerticalStaggered(frameRadius * 2 + 1)

# Remove any frames added to the end from the staggering.
return stacked.Trim(0, -c.FrameCount())
}As for the orientation/alignment, I'll leave that as an exercise for the reader. You might find my SelectByString plug-in (http://www.avisynth.org/stickboy/) useful.

Karyudo
31st July 2005, 10:18
Holy crap. If I flatter myself a lot, I could see that maybe I'd get to this sort of strategy eventually. But there is no way in hell I'd have been able to figure all this out in any less than, oh, say, a couple of months. Again, being very generous. So to have you get to this point in less than a couple of hours (including typing up a tutorial to go along with) is pretty freakin' amazing. Thanks a lot!

Now that you've solved the problem of leading frames being blank, I'm not so sure my "alignment" parameter is necessary. I was mostly thinking of doing that to allow the user (me?) to pick the very first or very last frames of a clip, without the function puking up an error of some sort.

I think I should be able to handle the "orientation" part, after I try this all out and digest it a bit. I hope so, anyway.

Thanks again, stickboy!