ApplyEvery
Raffriff42 (Talk | contribs) m (added category) |
(add x64 version and archived downloads section) |
||
(2 intermediate revisions by one user not shown) | |||
Line 1: | Line 1: | ||
− | # | + | {{FilterCat5|External_filters|Plugins|Plugins_x64|Adjustment_filters|Range_Processing}} |
− | {{ | + | {{Filter3 |
+ | | James D. Lin ([http://www.avisynth.nl/users/stickboy/ stickboy]) | ||
+ | | v0.3.1 | ||
+ | |[https://web.archive.org/web/20191106173119if_/http://www.iol.ie/%7Eschubert/gas/ApplyEvery031_32_64.7z ApplyEvery031_32_64.7z] | ||
+ | | Frame Replacement / Range Processing | ||
+ | | [https://www.gnu.org/licenses/gpl-2.0.txt GPLv2] | ||
+ | | 6=[http://forum.doom9.org/showthread.php?p=461878#post461878 Doom9 Thread] | ||
+ | }} | ||
+ | |||
+ | == Description == | ||
+ | A collection of AviSynth functions that operate at regular intervals in a clip. | ||
+ | <br> | ||
+ | <br> | ||
+ | == Requirements == | ||
+ | * [x86] [[AviSynth+]] or [https://sourceforge.net/projects/avisynth2/ AviSynth 2.6.0] | ||
+ | * [x64] [[AviSynth+]] | ||
+ | <br> | ||
+ | |||
+ | == Overview == | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <code>ApplyEvery</code> is a general function to apply a filter at regular intervals in a clip. | ||
+ | |||
+ | <code>DeleteEvery</code> deletes frames from a clip at regular intervals. It complements to the built-in <code>SelectEvery</code> function. | ||
+ | |||
+ | <code>DeleteFrames</code> is a supplement to the built-in <code>DeleteFrame</code> function. <code>DeleteFrames</code> provides a reasonably efficient means to delete multiple frames from a clip. | ||
+ | |||
+ | <code>InterleaveEvery</code> allows two clips to be mixed together in a specified pattern. It can undo the work of <code>SelectEvery</code> and <code>DeleteEvery</code>. | ||
+ | |||
+ | <code>RepeatEveryFrame</code> repeats every frame in a clip a specified number of times. | ||
+ | |||
+ | <code>LengthenClip</code> pads frames to the end of a clip to give it a minimum number of frames. | ||
+ | |||
+ | <code>WhileEval</code> provides a crude looping construct. | ||
+ | |||
+ | |||
+ | </div> | ||
+ | == Syntax == | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <pre>ApplyEvery(clip c, int period, string thunk) | ||
+ | |||
+ | DeleteEvery(clip c, int period [, int offset1 [, int offset2 [, ...]]]) | ||
+ | DeleteFrames(clip c, int frame1 [, int frame2 [, ...]]) | ||
+ | |||
+ | InterleaveEvery(clip baseClip, clip shimClip, | ||
+ | int period [, int offset1 [, int offset2 [, ...]]]) | ||
+ | |||
+ | RepeatEveryFrame(clip c, int count) | ||
+ | |||
+ | LengthenClip(clip c, int minLength, bool "copy", int "color") | ||
+ | |||
+ | WhileEval(string condition, string loopBody)</pre> | ||
+ | |||
+ | </div> | ||
+ | <div id="ApplyEvery"> | ||
+ | |||
+ | == ApplyEvery == | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | === Syntax === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <pre>ApplyEvery(clip c, int period, string thunk)</pre> | ||
+ | |||
+ | </div> | ||
+ | === Parameters === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | {| | ||
+ | | <code>period</code> | ||
+ | | The interval length, in frames. Must be > 0. | ||
+ | |- | ||
+ | | <code>thunk</code> | ||
+ | | The action to perform on the frames in the interval. | ||
+ | |} | ||
+ | |||
+ | |||
+ | </div> | ||
+ | === Usage === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | A general function to apply a filter at regular intervals in a clip. This function is not very efficient, so it's recommended that this function be used only if a combination of <code>SelectEvery</code>, <code>DeleteEvery</code>, and <code>InterleaveEvery</code> cannot suit your needs. | ||
+ | |||
+ | If the total number of frames is not a multiple of period, then silent, blank frames will be appended to the end of the output clip. It is the caller's responsibility to remove these afterward as necessary. (One of the examples below demonstrates how to remove these extra frames.) | ||
+ | |||
+ | Examples: | ||
+ | |||
+ | <pre class="example"># deletes the 0th frame of every 100 | ||
+ | # | ||
+ | # (NOTE: if you want to do this, DeleteEvery is better) | ||
+ | # | ||
+ | ApplyEvery(clip, 100, "DeleteFrame(0)")</pre> | ||
+ | <pre class="example"># inverts the first two frames of every 5 | ||
+ | # | ||
+ | # (NOTE: if you want to do this, a combination of SelectEvery, DeleteEvery, | ||
+ | # and InterleaveEvery is better) | ||
+ | # | ||
+ | ApplyEvery(clip, 5, """ApplyRange(0, 1, "Levels", 0, 1.0, 255, 255, 0)""")</pre> | ||
+ | <pre class="example"># reverses every group of 4 frames | ||
+ | ApplyEvery(clip, 4, "Reverse()")</pre> | ||
+ | <pre class="example"># how to correct the frame-length | ||
+ | # (assumes that thunk does not itself modify the frame-count) | ||
+ | # | ||
+ | n = clip.FrameCount() | ||
+ | ApplyEvery(clip, period, thunk) | ||
+ | Trim(0, -n)</pre> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | <div id="DeleteEvery"> | ||
+ | |||
+ | == DeleteEvery == | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | === Syntax === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <pre>DeleteEvery(clip c, int period [, int offset1 [, int offset2 [, ...]]])</pre> | ||
+ | |||
+ | </div> | ||
+ | === Parameters === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | {| | ||
+ | | <code>period</code> | ||
+ | | The interval length, in frames. Must be > 0. | ||
+ | |- | ||
+ | | <code>offset1 [, ...]</code> | ||
+ | | The offsets of each frame to delete, measured from the beginning of the interval. (See [[#DeleteEvery_usage|Usage]] for examples.) Each offset must be in the range [0, period). Order of the offsets does not matter. | ||
+ | |} | ||
+ | |||
+ | |||
+ | </div> | ||
+ | === Usage === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <code>DeleteEvery</code> reduces the frame-rate proportionately. For example, <code>DeleteEvery(clip, 3, 0, 1)</code> will reduce the frame-rate to one-third of its original value. '''<code>DeleteEvery</code> does not affect the audio track.''' | ||
+ | |||
+ | <code>DeleteEvery(clip, 9, 0)</code> will delete frames 0, 9, 18, 27, … from clip. | ||
+ | |||
+ | <code>DeleteEvery(clip, 9)</code> is equivalent to <code>DeleteEvery(clip, 9, 0)</code>. | ||
+ | |||
+ | <code>DeleteEvery(clip, 10, 0, 3)</code> will delete frames 0, 3, 10, 13, 20, 23, … from clip. | ||
+ | |||
+ | <code>DeleteEvery</code> complements the built-in <code>SelectEvery</code> function; <code>SelectEvery(4, 0, 1, 2)</code> is equivalent to <code>DeleteEvery(4, 3)</code>. | ||
+ | |||
+ | <code>DeleteEvery(clip, period, 0)</code> is conceptually equivalent to <code>ApplyEvery(clip, period, "DeleteFrame(0)")</code>. In practice, <code>DeleteEvery</code> is ''much'' more efficient than <code>ApplyEvery</code>. (Another difference is that <code>DeleteEvery</code> adjusts the frame-rate.) | ||
+ | |||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | <div id="DeleteFrames"> | ||
+ | |||
+ | == DeleteFrames == | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | === Syntax === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <pre>DeleteFrames(clip c, int frame1, [, int frame2 [, ...]])</pre> | ||
+ | |||
+ | </div> | ||
+ | === Parameters === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | {| | ||
+ | | <code>frame1 [, ...]</code> | ||
+ | | The frames to delete. | ||
+ | |} | ||
+ | |||
+ | |||
+ | </div> | ||
+ | === Usage === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | Like the built-in <code>DeleteFrame</code> function, '''<code>DeleteFrames</code> does not affect the audio track nor the frame-rate'''. Therefore, if enough frames are deleted, it may cause significant audio/video desynchronization. | ||
+ | |||
+ | Advantages of <code>DeleteFrames</code> over the built-in <code>DeleteFrame</code> function: | ||
+ | |||
+ | * Repeatedly calling the built-in <code>DeleteFrame</code> function is tedious. | ||
+ | * Repeatedly calling the built-in <code>DeleteFrame</code> function is inefficient; each call generates a new clip, wasting resources. | ||
+ | * Repeated calls to the built-in <code>DeleteFrame</code> function must be performed in reverse order to prevent each call from affecting the frame numbers in subsequent calls. In contrast, the frame numbers passed to <code>DeleteFrames</code> may be in any order. | ||
+ | |||
+ | <code>DeleteFrames(clip, ...)</code> essentially is shorthand for <code>DeleteEvery(clip, clip.FrameCount(), ...)</code>. (They are not exactly the same, however; <code>DeleteFrames</code> does not affect the frame-rate.) | ||
+ | |||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | <div id="InterleaveEvery"> | ||
+ | |||
+ | == InterleaveEvery == | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | === Syntax === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <pre>InterleaveEvery(clip baseClip, clip shimClip, | ||
+ | int period [, int offset1 [, int offset2 [, ...]]])</pre> | ||
+ | |||
+ | </div> | ||
+ | === Parameters === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | {| | ||
+ | | <code>baseClip</code><br /> | ||
+ | <code>shimClip</code> | ||
+ | | Frames from shimClip are inserted into baseClip. Both clips must have the same width, height, and colorspace properties. | ||
+ | |- | ||
+ | | <code>period</code> | ||
+ | | The ''output'' interval length, in frames. Must be > 0. | ||
+ | |- | ||
+ | | <code>offset1 [, ...]</code> | ||
+ | | The ''destination'' offsets to place frames from shimClip. (See [[#InterleaveEvery_usage|Usage]].) Each offset must be in the range [0, period). | ||
+ | |} | ||
+ | |||
+ | |||
+ | </div> | ||
+ | === Usage === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <code>InterleaveEvery</code> inserts frames at regular intervals from shimClip into baseClip at the specified offsets. For example: | ||
+ | |||
+ | {| | ||
+ | ! clip | ||
+ | ! frames | ||
+ | |- | ||
+ | | baseClip | ||
+ | | 0 1 2 3 … | ||
+ | |- | ||
+ | | shimClip | ||
+ | | '''a b c d''' … | ||
+ | |- | ||
+ | | <code>InterleaveEvery(baseClip, shimClip, 5, 0)</code> | ||
+ | | '''a''' 0 1 2 3 '''b''' 4 5 6 7 '''c''' 8 9 10 11 '''d''' … | ||
+ | |- | ||
+ | | <code>InterleaveEvery(baseClip, shimClip, 5, 0, 1)</code> | ||
+ | | '''a b''' 0 1 2 '''c d''' 3 4 5 '''e f''' 6 7 8 '''g h''' … | ||
+ | |} | ||
+ | |||
+ | <code>InterleaveEvery</code> continues until there are no more frames in baseClip: | ||
+ | |||
+ | {| | ||
+ | ! clip | ||
+ | ! frames | ||
+ | |- | ||
+ | | baseClip | ||
+ | | 0 1 2 3 4 5 6 | ||
+ | |- | ||
+ | | shimClip | ||
+ | | '''a b c d''' … | ||
+ | |- | ||
+ | | <code>InterleaveEvery(baseClip, shimClip, 5, 0)</code> | ||
+ | | '''a''' 0 1 2 3 '''b''' 4 5 6 | ||
+ | |} | ||
+ | |||
+ | If shimClip does not have enough frames to insert into baseClip, the last frame of shimClip will be repeated: | ||
+ | |||
+ | {| | ||
+ | ! clip | ||
+ | ! frames | ||
+ | |- | ||
+ | | baseClip | ||
+ | | 0 1 2 3 … | ||
+ | |- | ||
+ | | shimClip | ||
+ | | '''a b''' | ||
+ | |- | ||
+ | | <code>InterleaveEvery(baseClip, shimClip, 5, 0)</code> | ||
+ | | '''a''' 0 1 2 3 '''b''' 4 5 6 7 '''b''' 8 9 10 11 '''b''' … | ||
+ | |} | ||
+ | |||
+ | Offset order determines where particular frames from shimClip are inserted: | ||
+ | |||
+ | {| | ||
+ | ! clip | ||
+ | ! frames | ||
+ | |- | ||
+ | | baseClip | ||
+ | | 0 1 2 3 … | ||
+ | |- | ||
+ | | shimClip | ||
+ | | '''a b c d''' … | ||
+ | |- | ||
+ | | <code>InterleaveEvery(baseClip, shimClip, 5, 1, 0)</code> | ||
+ | | '''b a''' 0 1 2 '''d c''' 3 4 5 '''f e''' 6 7 8 '''h g''' … | ||
+ | |} | ||
+ | |||
+ | <code>InterleaveEvery</code> increases the frame-rate proportionately to preserve the total duration of baseClip. For example, <code>InterleaveEvery(baseClip, shimClip, 5, 0, 1)</code> will return a clip with a frame-rate that is five-thirds of baseClip's. | ||
+ | |||
+ | '''The output clip uses the unaltered audio track of baseClip.''' | ||
+ | |||
+ | Note that the period and offset parameters specify the desired periodicity of the ''output'' clip, not of the base clip. This syntax is designed to ease interoperability with <code>SelectEvery</code> and <code>DeleteEvery</code>. The same arguments used to extract frames with <code>SelectEvery</code>/<code>DeleteEvery</code> can be used to put them back with <code>InterleaveEvery</code>. | ||
+ | |||
+ | For example, to invert the first two frames of every group of five, we could use: | ||
+ | |||
+ | <pre class="example">src = AVISource( ... ) | ||
+ | |||
+ | # pull out the frames we want | ||
+ | subClip = src.SelectEvery(5, 0, 1) | ||
+ | src = src.DeleteEvery(5, 0, 1) | ||
+ | |||
+ | # invert subClip | ||
+ | subClip = subClip.Levels(0, 1.0, 255, 255, 0) | ||
+ | |||
+ | # inject the frames back in | ||
+ | src.InterleaveEvery(subClip, 5, 0, 1)</pre> | ||
+ | My <code>JDL_SimpleApplyEvery</code> function (part of [http://www.avisynth.org/stickboy/jdl-range.avsi jdl-range.avsi]) automates the above. | ||
+ | |||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | <div id="RepeatEveryFrame"> | ||
+ | |||
+ | == RepeatEveryFrame == | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | === Syntax === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <pre>RepeatEveryFrame(clip c, int count)</pre> | ||
+ | |||
+ | </div> | ||
+ | === Parameters === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | {| | ||
+ | | <code>count</code> | ||
+ | | The number of times to repeat each frame. | ||
+ | |} | ||
+ | |||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | <div id="LengthenClip"> | ||
+ | |||
+ | == LengthenClip == | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | === Syntax === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <pre>LengthenClip(clip c, int minLength, bool "copy", int "color")</pre> | ||
+ | |||
+ | </div> | ||
+ | === Parameters === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | {| | ||
+ | | <code>minLength</code> | ||
+ | | The minimum length desired for the clip. | ||
+ | |- | ||
+ | | <code>"copy"</code> | ||
+ | | Pass true to lengthen the clip by duplicating its last frame.<br /> | ||
+ | Pass false to lengthen the clip by appending blank frames to the end.<br /> | ||
+ | (Default: false) | ||
+ | |- | ||
+ | | <code>"color"</code> | ||
+ | | The RGB color to use for appended, blank frames.<br /> | ||
+ | (Default: $000000 (black)) | ||
+ | |} | ||
+ | |||
+ | |||
+ | </div> | ||
+ | === Usage === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | If the input clip already meets the minimum length, <code>LengthenClip</code> has no effect. | ||
+ | |||
+ | (This function doesn't belong with the rest, but it's provided because it's used by <code>ApplyEvery</code>.) | ||
+ | |||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | <div id="WhileEval"> | ||
+ | |||
+ | == WhileEval == | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | === Syntax === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <pre>WhileEval(string condition, string loopBody)</pre> | ||
+ | |||
+ | </div> | ||
+ | === Parameters === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | {| | ||
+ | | <code>condition</code> | ||
+ | | A string representing the looping condition. The loop continues as long as the string evaluates to true. | ||
+ | |- | ||
+ | | <code>loopBody</code> | ||
+ | | The body of the loop. May consist of multiple lines. (See [[#WhileEval_usage|Usage]].) | ||
+ | |} | ||
+ | |||
+ | |||
+ | </div> | ||
+ | === Usage === | ||
+ | |||
+ | <div class="subBody"> | ||
+ | |||
+ | <code>WhileEval</code> provides a very crude, ''static'' looping construct. That is, the loop is processed when the script is initially loaded. | ||
+ | |||
+ | <code>WhileEval</code> is not very efficient. A large number of iterations may cause a script to be slow to load; too many iterations may prevent AviSynth from loading the script at all. Although <code>WhileEval</code> should consume fewer resources than recursive looping constructs (AviSynth currently does not optimize tail-recursive calls), <code>ApplyEvery</code>, <code>SelectEvery</code>/<code>DeleteEvery</code>/<code>InterleaveEvery</code>, <code>Animate</code>, or <code>ScriptClip</code>/<code>FrameEvaluate</code> should be considered first when possible. | ||
+ | |||
+ | The example below is yet another way to delete the 0th frame of every 100. (Again, for this specific task, using <code>DeleteEvery</code> would be better.) | ||
+ | |||
+ | <pre class="example">c = AVISource( ... ) | ||
+ | |||
+ | i = c.FrameCount() - 1 | ||
+ | |||
+ | # this is NOT a no-op; this rounds i down to the next highest multiple | ||
+ | # of 100 | ||
+ | i = i / 100 * 100 | ||
+ | WhileEval("i >= 0", | ||
+ | \ "c = c.DeleteFrame(i) | ||
+ | i = i - 100") | ||
+ | c</pre> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | </div> | ||
+ | |||
+ | |||
+ | == Revision History == | ||
+ | |||
+ | <div id="historylist"> | ||
+ | |||
+ | * 0.3.1 | ||
+ | ** Fixed(?) some off-by-one errors in InterleaveEvery. | ||
+ | * 0.3.0 | ||
+ | ** Added <code>RepeatEveryFrame</code>. | ||
+ | ** Fixed some integer overflow cases. | ||
+ | * 0.2.3 | ||
+ | ** Oops, 0.2.2 accidentally undid the changes from 0.2.1. Fixed. | ||
+ | * 0.2.2 | ||
+ | ** Added <code>WhileEval</code>. | ||
+ | * 0.2.1 | ||
+ | ** Minor adjustments to handling of 0-frame clip inputs. | ||
+ | * 0.2.0 | ||
+ | ** Merged with my DeleteEvery/DeleteFrames plug-in. | ||
+ | ** Added <code>InterleaveEvery</code>. | ||
+ | ** Added documentation for <code>LengthenClip</code>. | ||
+ | * 0.1.0 | ||
+ | ** Initial release. | ||
+ | |||
+ | |||
+ | == Archived Downloads == | ||
+ | {| class="wikitable" border="1"; width="600px" | ||
+ | |- | ||
+ | !!width="100px"| Version | ||
+ | !!width="150px"| Download | ||
+ | !!width="150px"| Mirror | ||
+ | |- | ||
+ | !v0.3.1 (x86/x64) | ||
+ | |[https://web.archive.org/web/20191106173119if_/http://www.iol.ie/%7Eschubert/gas/ApplyEvery031_32_64.7z ApplyEvery031_32_64.7z] | ||
+ | |[https://web.archive.org/web/20200526194735if_/https://files.videohelp.com/u/223002/ApplyEvery031_32_64.7z ApplyEvery031_32_64.7z] /// [https://www.mediafire.com/file/hjr34mrq9n04enw/ApplyEvery031_32_64.7z/file MediaFire] | ||
+ | |- | ||
+ | !v0.3.1 | ||
+ | |[http://www.avisynth.nl/users/stickboy/ApplyEvery.zip ApplyEvery.zip] | ||
+ | |[https://web.archive.org/web/20170616055827/http://www.avisynth.nl/users/stickboy/ApplyEvery.zip ApplyEvery.zip] | ||
+ | |} | ||
+ | * x86/x64 version compiled by [https://forum.doom9.org/showthread.php?t=173259 Groucho2004]. | ||
+ | <br> | ||
+ | </div> | ||
+ | |||
+ | <div id="footer"> | ||
+ | |||
+ | Copyright © 2004 James D. Lin | ||
+ | </div> | ||
+ | <br> | ||
+ | <br> | ||
+ | ----------------------------------------------- | ||
+ | '''Back to [[External_filters#Frame_Replacement/Range_Processing|External Filters]] ←''' | ||
+ | ----------------------------------------------- |
Latest revision as of 20:52, 26 May 2020
Abstract | |
---|---|
Author | James D. Lin (stickboy) |
Version | v0.3.1 |
Download | ApplyEvery031_32_64.7z |
Category | Frame Replacement / Range Processing |
License | GPLv2 |
Discussion | Doom9 Thread |
Contents |
[edit] Description
A collection of AviSynth functions that operate at regular intervals in a clip.
[edit] Requirements
- [x86] AviSynth+ or AviSynth 2.6.0
- [x64] AviSynth+
[edit] Overview
ApplyEvery
is a general function to apply a filter at regular intervals in a clip.
DeleteEvery
deletes frames from a clip at regular intervals. It complements to the built-in SelectEvery
function.
DeleteFrames
is a supplement to the built-in DeleteFrame
function. DeleteFrames
provides a reasonably efficient means to delete multiple frames from a clip.
InterleaveEvery
allows two clips to be mixed together in a specified pattern. It can undo the work of SelectEvery
and DeleteEvery
.
RepeatEveryFrame
repeats every frame in a clip a specified number of times.
LengthenClip
pads frames to the end of a clip to give it a minimum number of frames.
WhileEval
provides a crude looping construct.
[edit] Syntax
ApplyEvery(clip c, int period, string thunk) DeleteEvery(clip c, int period [, int offset1 [, int offset2 [, ...]]]) DeleteFrames(clip c, int frame1 [, int frame2 [, ...]]) InterleaveEvery(clip baseClip, clip shimClip, int period [, int offset1 [, int offset2 [, ...]]]) RepeatEveryFrame(clip c, int count) LengthenClip(clip c, int minLength, bool "copy", int "color") WhileEval(string condition, string loopBody)
[edit] ApplyEvery
[edit] Syntax
ApplyEvery(clip c, int period, string thunk)
[edit] Parameters
period
|
The interval length, in frames. Must be > 0. |
thunk
|
The action to perform on the frames in the interval. |
[edit] Usage
A general function to apply a filter at regular intervals in a clip. This function is not very efficient, so it's recommended that this function be used only if a combination of SelectEvery
, DeleteEvery
, and InterleaveEvery
cannot suit your needs.
If the total number of frames is not a multiple of period, then silent, blank frames will be appended to the end of the output clip. It is the caller's responsibility to remove these afterward as necessary. (One of the examples below demonstrates how to remove these extra frames.)
Examples:
# deletes the 0th frame of every 100 # # (NOTE: if you want to do this, DeleteEvery is better) # ApplyEvery(clip, 100, "DeleteFrame(0)")
# inverts the first two frames of every 5 # # (NOTE: if you want to do this, a combination of SelectEvery, DeleteEvery, # and InterleaveEvery is better) # ApplyEvery(clip, 5, """ApplyRange(0, 1, "Levels", 0, 1.0, 255, 255, 0)""")
# reverses every group of 4 frames ApplyEvery(clip, 4, "Reverse()")
# how to correct the frame-length # (assumes that thunk does not itself modify the frame-count) # n = clip.FrameCount() ApplyEvery(clip, period, thunk) Trim(0, -n)
[edit] DeleteEvery
[edit] Syntax
DeleteEvery(clip c, int period [, int offset1 [, int offset2 [, ...]]])
[edit] Parameters
period
|
The interval length, in frames. Must be > 0. |
offset1 [, ...]
|
The offsets of each frame to delete, measured from the beginning of the interval. (See Usage for examples.) Each offset must be in the range [0, period). Order of the offsets does not matter. |
[edit] Usage
DeleteEvery
reduces the frame-rate proportionately. For example, DeleteEvery(clip, 3, 0, 1)
will reduce the frame-rate to one-third of its original value. DeleteEvery
does not affect the audio track.
DeleteEvery(clip, 9, 0)
will delete frames 0, 9, 18, 27, … from clip.
DeleteEvery(clip, 9)
is equivalent to DeleteEvery(clip, 9, 0)
.
DeleteEvery(clip, 10, 0, 3)
will delete frames 0, 3, 10, 13, 20, 23, … from clip.
DeleteEvery
complements the built-in SelectEvery
function; SelectEvery(4, 0, 1, 2)
is equivalent to DeleteEvery(4, 3)
.
DeleteEvery(clip, period, 0)
is conceptually equivalent to ApplyEvery(clip, period, "DeleteFrame(0)")
. In practice, DeleteEvery
is much more efficient than ApplyEvery
. (Another difference is that DeleteEvery
adjusts the frame-rate.)
[edit] DeleteFrames
[edit] Syntax
DeleteFrames(clip c, int frame1, [, int frame2 [, ...]])
[edit] Parameters
frame1 [, ...]
|
The frames to delete. |
[edit] Usage
Like the built-in DeleteFrame
function, DeleteFrames
does not affect the audio track nor the frame-rate. Therefore, if enough frames are deleted, it may cause significant audio/video desynchronization.
Advantages of DeleteFrames
over the built-in DeleteFrame
function:
- Repeatedly calling the built-in
DeleteFrame
function is tedious. - Repeatedly calling the built-in
DeleteFrame
function is inefficient; each call generates a new clip, wasting resources. - Repeated calls to the built-in
DeleteFrame
function must be performed in reverse order to prevent each call from affecting the frame numbers in subsequent calls. In contrast, the frame numbers passed toDeleteFrames
may be in any order.
DeleteFrames(clip, ...)
essentially is shorthand for DeleteEvery(clip, clip.FrameCount(), ...)
. (They are not exactly the same, however; DeleteFrames
does not affect the frame-rate.)
[edit] InterleaveEvery
[edit] Syntax
InterleaveEvery(clip baseClip, clip shimClip, int period [, int offset1 [, int offset2 [, ...]]])
[edit] Parameters
baseClip
|
Frames from shimClip are inserted into baseClip. Both clips must have the same width, height, and colorspace properties. |
period
|
The output interval length, in frames. Must be > 0. |
offset1 [, ...]
|
The destination offsets to place frames from shimClip. (See Usage.) Each offset must be in the range [0, period). |
[edit] Usage
InterleaveEvery
inserts frames at regular intervals from shimClip into baseClip at the specified offsets. For example:
clip | frames |
---|---|
baseClip | 0 1 2 3 … |
shimClip | a b c d … |
InterleaveEvery(baseClip, shimClip, 5, 0)
|
a 0 1 2 3 b 4 5 6 7 c 8 9 10 11 d … |
InterleaveEvery(baseClip, shimClip, 5, 0, 1)
|
a b 0 1 2 c d 3 4 5 e f 6 7 8 g h … |
InterleaveEvery
continues until there are no more frames in baseClip:
clip | frames |
---|---|
baseClip | 0 1 2 3 4 5 6 |
shimClip | a b c d … |
InterleaveEvery(baseClip, shimClip, 5, 0)
|
a 0 1 2 3 b 4 5 6 |
If shimClip does not have enough frames to insert into baseClip, the last frame of shimClip will be repeated:
clip | frames |
---|---|
baseClip | 0 1 2 3 … |
shimClip | a b |
InterleaveEvery(baseClip, shimClip, 5, 0)
|
a 0 1 2 3 b 4 5 6 7 b 8 9 10 11 b … |
Offset order determines where particular frames from shimClip are inserted:
clip | frames |
---|---|
baseClip | 0 1 2 3 … |
shimClip | a b c d … |
InterleaveEvery(baseClip, shimClip, 5, 1, 0)
|
b a 0 1 2 d c 3 4 5 f e 6 7 8 h g … |
InterleaveEvery
increases the frame-rate proportionately to preserve the total duration of baseClip. For example, InterleaveEvery(baseClip, shimClip, 5, 0, 1)
will return a clip with a frame-rate that is five-thirds of baseClip's.
The output clip uses the unaltered audio track of baseClip.
Note that the period and offset parameters specify the desired periodicity of the output clip, not of the base clip. This syntax is designed to ease interoperability with SelectEvery
and DeleteEvery
. The same arguments used to extract frames with SelectEvery
/DeleteEvery
can be used to put them back with InterleaveEvery
.
For example, to invert the first two frames of every group of five, we could use:
src = AVISource( ... ) # pull out the frames we want subClip = src.SelectEvery(5, 0, 1) src = src.DeleteEvery(5, 0, 1) # invert subClip subClip = subClip.Levels(0, 1.0, 255, 255, 0) # inject the frames back in src.InterleaveEvery(subClip, 5, 0, 1)
My JDL_SimpleApplyEvery
function (part of jdl-range.avsi) automates the above.
[edit] RepeatEveryFrame
[edit] LengthenClip
[edit] Syntax
LengthenClip(clip c, int minLength, bool "copy", int "color")
[edit] Parameters
minLength
|
The minimum length desired for the clip. |
"copy"
|
Pass true to lengthen the clip by duplicating its last frame. Pass false to lengthen the clip by appending blank frames to the end. |
"color"
|
The RGB color to use for appended, blank frames. (Default: $000000 (black)) |
[edit] Usage
If the input clip already meets the minimum length, LengthenClip
has no effect.
(This function doesn't belong with the rest, but it's provided because it's used by ApplyEvery
.)
[edit] WhileEval
[edit] Syntax
WhileEval(string condition, string loopBody)
[edit] Parameters
condition
|
A string representing the looping condition. The loop continues as long as the string evaluates to true. |
loopBody
|
The body of the loop. May consist of multiple lines. (See Usage.) |
[edit] Usage
WhileEval
provides a very crude, static looping construct. That is, the loop is processed when the script is initially loaded.
WhileEval
is not very efficient. A large number of iterations may cause a script to be slow to load; too many iterations may prevent AviSynth from loading the script at all. Although WhileEval
should consume fewer resources than recursive looping constructs (AviSynth currently does not optimize tail-recursive calls), ApplyEvery
, SelectEvery
/DeleteEvery
/InterleaveEvery
, Animate
, or ScriptClip
/FrameEvaluate
should be considered first when possible.
The example below is yet another way to delete the 0th frame of every 100. (Again, for this specific task, using DeleteEvery
would be better.)
c = AVISource( ... ) i = c.FrameCount() - 1 # this is NOT a no-op; this rounds i down to the next highest multiple # of 100 i = i / 100 * 100 WhileEval("i >= 0", \ "c = c.DeleteFrame(i) i = i - 100") c
[edit] Revision History
- 0.3.1
- Fixed(?) some off-by-one errors in InterleaveEvery.
- 0.3.0
- Added
RepeatEveryFrame
. - Fixed some integer overflow cases.
- Added
- 0.2.3
- Oops, 0.2.2 accidentally undid the changes from 0.2.1. Fixed.
- 0.2.2
- Added
WhileEval
.
- Added
- 0.2.1
- Minor adjustments to handling of 0-frame clip inputs.
- 0.2.0
- Merged with my DeleteEvery/DeleteFrames plug-in.
- Added
InterleaveEvery
. - Added documentation for
LengthenClip
.
- 0.1.0
- Initial release.
[edit] Archived Downloads
Version | Download | Mirror |
---|---|---|
v0.3.1 (x86/x64) | ApplyEvery031_32_64.7z | ApplyEvery031_32_64.7z /// MediaFire |
v0.3.1 | ApplyEvery.zip | ApplyEvery.zip |
- x86/x64 version compiled by Groucho2004.
Back to External Filters ←