Log in

View Full Version : stickboy's craptacular AviSynth plug-ins


stickboy
20th March 2004, 01:43
Okay, I've made some really rudimentary AviSynth plug-ins (http://www.avisynth.org/stickboy/). I've mentioned a couple of them in passing in some other threads, but I haven't said much about them.


SelectByString

A function that's similar to the built-in Select function but that operates on strings. (If you're familiar with other programming languages, it can provide functionality similar to a switch statement or to an associative array.)

Examples:SelectByString("jubjub",
\ "tove", 0,
\ "borogove", 1,
\ "jubjub", 2,
\ "jabberwock", 3)would return 2.

Obviously, it's more useful if the search string is a variable:
function ColorNameToRGB(string colorName)
{
return SelectByString(colorName,
\ "white", $FFFFFF,
\ "black", $000000,
\ "red", $FF0000,
\ "green", $00FF00,
\ "blue", $0000FF)
}A SelectByStringEval function also is included, which is shorthand for Eval(SelectByString(...))

And, of course, these functions can be useful for making wrapper functions (http://www.avisynth.org/index.php?page=Wrapper) with presets.


Min/Max

Basic Min/Max functions that can take a variable number of arguments. Arguments can be integers or floats and even can be mixed, if so desired. Not much to say here.


Threshold/Core [YUY2, RGB24, RGB32]

Basic (and unoptimized) threshold and coring functions. Threshold maps all pixels darker than a specified threshold value to pure black and the rest to pure white.

Core is similar; it maps all pixels darker than a specified threshold value to pure black and leaves the rest untouched.


Shuffle

Randomly shuffles the frames in a clip. Yeah, it's useless, but it can be used to make some mildly interesting effects. (See the included script of examples.)


DeleteEvery/DeleteFrames

Functions that facilitate deletion of multiple frames. DeleteEvery complements SelectEvery; SelectEvery(4, 0, 1, 2) is equivalent to DeleteEvery(4, 3). Again, not too useful, but I remember there have been some cases where people have wanted to delete, say, 1 frame of every 1000, which is impractical for SelectEvery.

DeleteFrames--not surprisingly--is a version of the built-in DeleteFrame function that can handle multiple frames. Calling DeleteFrame multiple times is:
tedious inefficient error-prone, since the order of DeleteFrame calls matters


Source code to everything is included under a BSD-style license.

Mug Funky
20th March 2004, 16:46
bravo!!

deleteevery is just the thing for PAL telecine with duped frames (r4 fight club)

[edit]

and shuffle could be made a _little bit_ more useful if you could select random chunks of several frames rather than just single frames.

i did something like that with a script when i was helping a friend make a grindcore video. lots of gore footage selected randomly in 5 frame chunks (that coincided with the double-kick). huge time-saver to do it that way rather than make a million cuts in premiere, i can tell you :|

scharfis_brain
20th March 2004, 17:22
[quote] PAL telecine with duped frames[/qoute]

Please tell me more!

Sounds interesting.

DDogg
20th March 2004, 18:21
Just a thought, but if each of the advanced script writers would post a similar guide to their work in this thread, then eventually, it could be edited, renamed and potentially made sticky. We do need a way to consolidate all this great work you guys are doing and this may be a simple way to do it.

stickboy
20th March 2004, 21:39
Originally posted by Mug Funky
and shuffle could be made a _little bit_ more useful if you could select random chunks of several frames rather than just single frames.
I'm not quite sure what you mean. Could you provide an example? (i.e., if you have frames 0 1 2 3 4 5 ..., then how do you want them rearranged?) There's a "groupSize" parameter to Shuffle, but I'm not sure if that does what you want.

stickboy
21st March 2004, 01:40
ApplyEvery (http://www.avisynth.org/stickboy/ApplyEvery.zip)

A generalized function that can apply a specified function at regular intervals in a clip. DeleteEvery can be viewed as a specialized version; DeleteEvery(100, 0) is conceptually equivalent to ApplyEvery(100, "DeleteFrame(0)"). (In practice, DeleteEvery is much more efficient, so if you're only deleting frames, use that. Plus, DeleteEvery modifies the frame-rate appropriately.)

This is basically a straight conversion of my JDL_ApplyEvery (http://www.avisynth.org/stickboy/jdl-range.avsi) user-defined function to an AviSynth plug-in.

I tried the following script with my user-defined version:
BlankClip(length=2100, pixel_type="yuy2")
ShowFrameNumber()
JDL_ApplyEvery(4, "Reverse()")On my system, the user-defined version can iterate about 525 times (2100 / 4) without crashing; increasing the source clip's frame count by one causes VirtualDub+AviSynth to crash silently.

If I substitute in the plug-in version, I can increase the clip length to over 80000. (That's 20000+ iterations, a ~40-fold increase.) A script with that many iterations is slow to load, however.

This is an experimental, quick-and-dirty build; source currently isn't included but will be forthcoming eventually, after I ponder some possible improvements.

Didée
21st March 2004, 03:17
ApplyEvery!!!

Now, this is great! ... but a year too late ;)

By that time, I had a clip with a logo consisting of the word "pop" in small letters, that was slowly travelling its way around a big imaginary circle.
I ended up in breaking the circumfang in 10 or 12 pieces, made a "delogo" function for each of these fractions, and then fiddled something together with the "select" function and conditional filtering acc. to framecount.

That would've been a job for ApplyEvery ...

Thanks for "centralizing" your functions, stickboy.

- Didée

Mug Funky
22nd March 2004, 05:56
@scharfis_brain - it's nothing spectacular... just a matter of duping 1 in 25 frames and not touching the audio. sadly i've only seen it used once.

i've noticed sped-up audio discs often transcode the audio from the NTSC version! this completely breaks any transparency the audio once had. (if you can get hold of r4 "being john malkovich" you'll hear the opening applause is riddled with pre-echo and stereo collapse)

stickboy
1st April 2004, 03:37
I merged my ApplyEvery and DeleteEvery plug-ins and added a new function: InterleaveEvery.

InterleaveEvery is yet another almost useless function, but I felt that it was needed for completeness.

InterleaveEvery can undo the work of SelectEvery + DeleteEvery. If you use SelectEvery and DeleteEvery to pull some frames out, InterleaveEvery can put them back in:
src = AVISource( ... )

# pull out some frames
subClip = src.SelectEvery(5, 0, 1)
src = src.DeleteEvery(5, 0, 1)

# inject the frames back in
src.InterleaveEvery(subClip, 5, 0, 1)(The above example is basically a convoluted no-op.)

But, if you wanted to, say, invert the first two frames of every group of five, InterleaveEvery makes it easy to do that. (Not that anyone would want to do that, of course...)

Or maybe it could be used to insert subliminal messages. Or something.

stickboy
24th December 2004, 23:19
I neglected to announce this here before, but I made another plug-in: RemapFrames (http://www.avisynth.org/stickboy/).

RemapFrames provides general control over manipulation of frame indices in a clip.

It doesn't affect the audio track. I still haven't figured out a good way to deal with audio, but it's intended to be an alternative to long chains of FreezeFrame and DeleteFrame calls, which touch up individual frames and which also don't affect the audio.

Anyhow, today I hacked in a new function to RemapFrames: ReplaceFramesSimple.

On a number of occasions I've done things like:
c = src.Telecide(...).Decimate(...)

# Oops. Some frames are still combed, and I don't want to
# post-process the entire clip.
ApplyRange(100, 110, "SomeDeinterlacer")
ApplyRange(200, 200, "SomeDeinterlacer")
ApplyRange(250, 250, "SomeDeinterlacer")
ApplyRange(300, 310, "SomeDeinterlacer")With ReplaceFramesSimple, this can be done more efficiently and more cleanly:
c = src.Telecide(...).Decimate(...)
deinterlaced = c.SomeDeinterlacer()

ReplaceFramesSimple(c, deinterlaced,
\ mappings="[100 110] 200 250 [300 310]")The syntax probably could use a little bit more work, and the right now documentation has a lot to be desired. Oh well.

chipzoller
13th January 2007, 22:55
stickboy, I'd like to use applyrange to isolate 2 sections in my clip, but I also need to IVTC the clip (VHS capture). Your warning in the script says I shouldn't use applyrange along with anything that alters frame count, so then what should I use? Trim isn't very reliable from what I've read although I'm no expert.

How should I proceed? Can I just find the decimated frame range and use those numbers, calling jdl_applyrange after IVTC?

stickboy
14th January 2007, 11:38
I don't understand what you want to do. What do you want to use JDL_ApplyRange (or the internal ApplyRange) for? What are you doing that with it that will affect the frame count?

The filter you apply with JDL_ApplyRange shouldn't affect the frame count. You can do whatever you want to the clip before or after calling JDL_ApplyRange, though.

That said, it's probably a better idea to do IVTC early on so you don't waste time filtering frames that will be removed, and then figure out the appropriate frame numbers to give to ApplyRange/JDL_ApplyRange/whatever in the IVTC'd clip.

BTW, why isn't Trim reliable? If you're referring to my Caveats about using Trim in functions (http://forum.doom9.org/showthread.php?t=58358) thread, then you've misunderstood.

guada2
14th January 2007, 11:59
good job man. ;)

chipzoller
14th January 2007, 14:39
I have a capture that the intro and credits are animated and the middle is live action. I want to use applyrange to filter the intro. and credits separately from the live action section, but at the same time, the capture needs to be IVTCd. This thread (http://forum.doom9.org/showthread.php?t=119985) may better explain.

stickboy
14th January 2007, 20:30
Yeah, just IVTC first and use ApplyRange afterward.

Or actually, in this case, just using Trim directly is probably more straightforward:intro = Trim(0, 1000).IVTC().OtherFilters()
rest = Trim(1001, 0).IVTC()

intro + rest

blausand
10th October 2007, 00:54
Good Morning, Stickboy!

I've been happy for about three days now, that i have found a solution for re-arranging frames algorithmically - with your RemapFrames function.
Unfortunately, the function does not eat the three parameters, as the following script earns a "Invalid arguments to function RemapFrames":
dur=1200
src2 = aviSource("an .AVI")
target = BlankClip(src2)
target.lengthenClip(dur).ShowFrameNumber()
#return src2 will work!
#RemapFrames(target, filename = "D:\Code\Avisynth\gfa.Frames.vsc", src2) #as well as
RemapFrames(src2, filename = "D:\Code\Avisynth\gfa.Frames.vsc", target)
# yield the error "Invalid Arguments"

Apart from this Problem i'm having:
I need to extend these functions you wrote, if you could give me some advise:

Time-stretched portions of the Remap should be blended somehow. Maybe by calling another function for each frame with the two srcFrames and opacity-"weights" for blending?
A function like RemixClips should allow for selecting which clip, that is to be remapped. Example:
[srcRange] clipNameWithoutQuotMarks [destRange]
[0 15] src2fx0 [0 15]
[16 31] src2fx1 [63 32]
[32 48] src2fx2 [0 15]
[49 63] src2fx3 [63 0]

Anyway, great work in that stuff! Hope to meet you in the code one day!
blausand

blausand
10th October 2007, 22:37
(Not that anyone would want to do that, of course...)
Don't say that! It seems that your work is quite valueable to a small community (me, in fact?) of video artists.

Regarding the malfunction mentioned above:
It seems that RemapFrames does not insert last
automatically when the first argument is omitted. To double-check, i use 'optional parameter notation' allover now.
The error changed to "Value out of bounds" when i used "pure argument notation" and that turned out to be an error within LengthenClip(). LengthenClip() does not correct the clip property "framecount", as the following screenshot wants to make me believe:

stickboy
10th October 2007, 23:34
Good Morning, Stickboy!
Unfortunately, the function does not eat the three parameters, as the following script earns a "Invalid arguments to function RemapFrames":Hm, RemapFrames has four parameters...


RemapFrames(src2, filename = "D:\Code\Avisynth\gfa.Frames.vsc", target)
# yield the error "Invalid Arguments" But that's because you tried to pass "target" for the "mappings" string. Try:

RemapFrames(src2, filename="D:\Code\Avisynth\gfa.Frames.vsc", sourceClip=target)When used this way, it should use the "implicit last" clip if the first argument is omitted. Let me know if that works or not.
LengthenClip() does not correct the clip property "framecount"Hm, looking at its source code, it should. It does set vi.num_frames in its constructor. I'll double-check when I get to a computer that has AviSynth installed. Can you post the current version of your script? In the original version of the script you posted, none of the clips you passed in (src2 nor target) were lengthened to 1200 frames; only 'last' was.

blausand
11th October 2007, 17:09
at least [me] thought, the object.function semantic operates destructive per default.
It took me some effort to understand this:
target.LengthenClip(new_duration)
target = target.LengthenClip(new_duration)While the first line does not alter target,
i have to make an explicit assignment, as in the second line.
If you look at my second ScreenShot (http://forum.doom9.org/attachment.php?attachmentid=7665&d=1192052110), you'll see a proof of inconsistency, though.
Anyway, i think that this behaviour should be emphasized in any introductory or tutorial text;

I'd personally prefer to work with last, making one operation per line, but working with several clips and using last complicates commenting in and out single lines of code. How can i finish every clip-editing block with an assignment line? The following ends with "Not a Clip" error:
E.g.:LoadPlugin("C:\Programme\MEDIA\AviSynth 2.5\PlugIns\ApplyEvery.dll")
# (necessary because Avisynth didn't register my custom installation path correctly ;( #

#### CLIP1 ####
aviSource("src0.AVI", pixel_type = "RGB32")
BilinearResize(320,240)
Mask(Levels(last, 126,1.0,128, 0, 255))
ShowFrameNumber()
LengthenClip(1200)
CLIP1 = last
Stickboy, Sorry for the inconvenience! Keep the good work up!
blausand

foxyshadis
11th October 2007, 17:40
You have to use CLIP1 or return CLIP1 as the last line of your script; avisynth doesn't like assignments as the last line for some reason, even when there is a logical last.

And yeah, avisynth is designed so that a source clip is never modified, although it may be lost (and internally, a source may be modified/overwritten if it's never reused in script).

stickboy
11th October 2007, 21:11
at least [me] thought, the If you look at my second ScreenShot (http://forum.doom9.org/attachment.php?attachmentid=7665&d=1192052110), you'll see a proof of inconsistency, though.What your screenshot shows is the correct behavior. src2 is not modified, so when you do:
subtitle(src2.framecount))you're showing the original framecount.

"info" shows your intended framecount because when you run a filter on a function (in this case, "src2.LengthenClip(1200)"), it returns a brand new clip and leaves the source clip unchanged. Remember, AviSynth is a functional-like language. Do not try to use imperative programming idioms where you try to set state.

If you were to do:
src2 = src2.LengthenClip(1200).info
src2.subtitle(string(src2.framecount))you'd see the counts match.

blausand
11th October 2007, 23:23
Thanks, foxyshadis, for bringing some light into Avisynths behaviour here. I admit: I'm a bit of a noob to it.
Still i think, that this structure:
PutResultHere = BlankClip().DoSomethingToIt.AndThis.AndLenghenClip()
should work all through the chain before returning the result to PutResultHere. If it doesn't, however, this is a major difference in notation modes, right?

I'm moving over to a new thread now, stickboy shall not longer be bothered anylonger with my basic questions. Have a nice day!

stickboy
12th October 2007, 03:25
Thanks, foxyshadis, for bringing some light into Avisynths behaviour here. I admit: I'm a bit of a noob to it.
Still i think, that this structure:
PutResultHere = BlankClip().DoSomethingToIt.AndThis.AndLenghenClip()
should work all through the chain before returning the result to PutResultHere.It does work through the chain before assigning to PutResultHere. No clips are modified, however. Filters don't directly modify clips; they return new ones.
If it doesn't, however, this is a major difference in notation modes, right?There is no difference.
PutResultHere = BlankClip().DoSomethingToIt().AndThis().AndLengthenClip()is the same as:
PutResultHere = AndLengthenClip(AndThis(DoSomethingToIt(BlankClip())))and is the same as:
BlankClip()
DoSomethingToIt()
AndThis()
AndLengthenClip()
PutResultHere = last

mikeytown2
27th September 2008, 05:50
stickboy, I've done some basic toying around with RemapFrames after I had a brainstorm over here
http://forum.doom9.org/showthread.php?p=1188174#post1188174

The main problem I see with building a NLE on top of AviSynth is the Splicing. I think RemapFrames can fix the trim headache one would encounter when trying to do a multi track NLE. In essence it makes the trims independent of each other.


Base = ColorBars().BlankClip().ShowFrameNumber(x=10,y=30).ConvertToRGB32()
ClipA = ColorBars().BlankClip(pixel_type="YUY2").ColorYUV(showyuv=true).BilinearResize(640,480).ShowFrameNumber(x=10,y=30).ConvertToRGB32()
ClipB = ColorBars().invert().FlipVertical().Trim(0,999).ShowFrameNumber(x=10,y=30).ConvertToRGB32()

Base = RemapFrames(Base,sourceClip=ClipA,mappings="[20 50] [0 30]")
Base = RemapFrames(Base,sourceClip=ClipB,mappings="[100 150] [0 50]")
Base


Issues I see right now is selective filtering, transitions, audio, and error checking. What are your thoughts?

stickboy
27th September 2008, 10:01
I think selective filtering would be better off done with Trim or ApplyRange (or with ReplaceFrames/RemapFrames).

I agree that transitions and audio would be necessary for what you want, but:
1. Transitions are way outside the scope of RemapFrames. I have no idea how that'd even work.
2. Dealing with audio is more realistic, but it's also hard (which is why I haven't done it).

I think if you want to make a graphical NLE based around AviSynth, it'd probably be better just to stick with Trim and Splice. Independent Trims shouldn't be hard; you just need to make sure you only call Trim() on the source clips instead of chaining them.

Splice would need to be improved so that you can do:

Splice(a, b, c, d) without it internally creating a Splice(a, Splice(b, Splice(c, d))) chain (or maybe it's left-folding; I don't remember offhand).

blausand
29th September 2008, 14:31
I'm glad to see that there's life in the development of AviSynth! Recently, i've come to use Avisynth for what it's name suggests ever since: The synthesis of video, in an artsy context. (see Flash-Clips on silvertree.de !)
I wonder if there is a possibility to write frames of a lower resolved clip into higher resolved clips DIRECTLY as D3D-rectangles ,
instead of instantiating an auxiliary clip by adding borders to the small one to make it match the size of the big one and then layeroing the two? So for extensive scripting synthesis, this is a question of ioptimized code... Any ideas?
greetings from cologne, germany.
blausand

Gavino
29th September 2008, 15:00
I wonder if there is a possibility to write frames of a lower resolved clip into higher resolved clips DIRECTLY as D3D-rectangles ,
instead of instantiating an auxiliary clip by adding borders to the small one to make it match the size of the big one and then layeroing the two? So for extensive scripting synthesis, this is a question of ioptimized code... Any ideas?
You can do this with StackHorizontal/StackVertical to construct the larger clip in sections. If doing it in a generic way you just have to be careful about the special cases (when the smaller clip lies along one or more edges of the larger).

cretindesalpes
22nd September 2013, 19:28
I updated RemapFrames: RemapFrames 0.4.1 (https://ldesoras.fr/src/avs/RemapFrames-0.4.1.zip)

Added remf, remfs, rfs, rfs_merge and rfs_transform:

remf, remfs and rfs are shortcuts for RemapFrames, RemapFramesSimple and ReplaceFramesSimple with slight differences. The mappings parameter comes before filename for a more compact "inline" call. These parameters are completely optional; when none of them is specified, an empty string is assumed. And when an empty string is detected, the filter is completely bypassed (no extra memory use). Also, these versions don't check aggressively the frame ranges. If a referenced frame doesn't exist, it's simply ignored or its index is replaced with the closest valid frame index. This allows working on partial ranges of a clip with a unique set of mappings.
rfs_transform is a helper function transforming a set of mappings for ReplaceFramesSimple using an arithmetic operation. This is useful when one needs to substitute frames after a framerate change or any kind of timeline manipulation.
rfs_merge is a helper function merging several mappings for ReplaceFramesSimple together. It just concatenates these strings and inserts spaces in between, but it is probably more convenient than a simple concatenation because it handles properly the undefined strings. If all strings are undefined, the result is also an undefined string.

Katie Boundary
15th February 2019, 03:44
These filters look interesting but proper documentation is necessary if we're to avoid accidentally erasing our hard drives or nuking Russia or something equally disastrous.

manono
15th February 2019, 07:36
At least some have their own pages on the AviSynth wiki with pretty good explanations and examples for their use. For example, here's the page for RemapFrames:

http://avisynth.nl/index.php/RemapFrames

Which were you thinking of trying out? I've only used a few but use ReplaceFramesSimple about every day of my life.

Katie Boundary
15th February 2019, 17:37
Which were you thinking of trying out? I've only used a few but use ReplaceFramesSimple about every day of my life.

ApplyEvery/DeleteEvery

poisondeathray
15th February 2019, 17:47
The original version has html documentation, usage examples
(v0.3.1)

http://www.avisynth.nl/users/stickboy/ApplyEvery.zip

Groucho2004
15th February 2019, 19:05
I added 32/64 bit builds of ApplyEvery with updated AVS2.6 headers to my collection (https://forum.doom9.org/showthread.php?t=173259).

Floatingshed
28th April 2020, 17:18
Can anyone help with a link to RemapFrames 64 bit please? The wiki link is dead.
Thanks.

StainlessS
28th April 2020, 17:36
Remapframes x86 and x64, just above your post in Groucho's Avisynth Stuff.

Floatingshed
28th April 2020, 18:14
Great, thanks very much.