ConditionalReader

From Avisynth wiki
(Difference between revisions)
Jump to: navigation, search
(formatting, links, phrasing)
m (one more touch-up)
Line 35: Line 35:
 
</div>
 
</div>
  
*The first non-{{BoldColor|blue|100|''comment''}} line must be a {{BoldColor|blue|100|''type''}} line, being one of the following:
+
*The first non-{{BoldColor|blue|100|''comment''}} line should be a {{BoldColor|blue|100|''type''}} line, which sets the ''value'' type for all following lines. There are four valid {{BoldColor|blue|100|''type''}} lines:
 
:: <code>TYPE int</code>
 
:: <code>TYPE int</code>
::: (''ints'' are the digits 0-9, optionally preceded with a '+' or '-' sign)
+
::: Tells '''ConditionalReader''' to expect decimal integer ''values''.
 +
::: (digits <code>0-9</code>, optionally preceded with a '<code>+</code>' or '<code>-</code>' sign)
 
:: <code>TYPE float</code>
 
:: <code>TYPE float</code>
::: (like ''int'' but containing a '.' decimal separator, and optionally followed by an 'e' or 'E' character plus an ''int'' exponent)
+
::: Tells '''ConditionalReader''' to expect floating-point ''values''.
 +
::: (decimal number with '<code>.</code>' decimal point, and optionally followed by an '<code>E</code>' character and decimal exponent)
 
:: <code>TYPE bool</code>
 
:: <code>TYPE bool</code>
::: ('true' or 'false')
+
::: Tells '''ConditionalReader''' to expect boolean ''values''.
 +
::: ('<code>true</code>' or '<code>false</code>', '<code>T</code>' or '<code>F</code>', '<code>yes</code>' or '<code>no</code>', '<code>1</code>' or '<code>0</code>')
 
:: <code>TYPE string</code> (from v2.60)
 
:: <code>TYPE string</code> (from v2.60)
::: (any sequence of characters representing text)
+
::: (any sequence of characters, including quote, backslash etc; a line break ends the string)
 
:The {{BoldColor|blue|100|''type''}} line defines the {{BoldColor|blue|100|''data''}} type to be parsed from this file and assigned to the variable {{FuncArg|variablename}}. You must have one, and only one, {{BoldColor|blue|100|''type''}} line per file, and it must come before any other lines, except for optional comments.
 
:The {{BoldColor|blue|100|''type''}} line defines the {{BoldColor|blue|100|''data''}} type to be parsed from this file and assigned to the variable {{FuncArg|variablename}}. You must have one, and only one, {{BoldColor|blue|100|''type''}} line per file, and it must come before any other lines, except for optional comments.
  
*The {{BoldColor|blue|100|''header''}} comes next, and consists of the following lines in any order:
+
*A {{BoldColor|blue|100|''default''}} line should come next. It is optional but strongly suggested:
 
+
::Optional {{BoldColor|blue|100|''default''}} line:
+
 
:::<code>DEFAULT <value></code>
 
:::<code>DEFAULT <value></code>
:::This specifies the default value to be assigned to the script variable if there is no {{BoldColor|blue|100|''data''}} line defining a value for a given frame. If you do not define a default, you must be sure to specify a setting for all frames; or you will get unexpected results.
+
:::This specifies the value to be used if there is no applicable {{BoldColor|blue|100|''data''}} line for a given frame.  
 +
:::If you do not define a default, be sure to specify a value for all frames; otherwise your script variable could be be [[Internal functions/Defined|undefined]] or take a random value.
  
::Optional {{BoldColor|blue|100|''offset''}} line:
+
*An optional {{BoldColor|blue|100|''offset''}} line may appear:
:::<code>OFFSET <value></code> (from v2.60)
+
:::<code>OFFSET <integer-value></code> (from v2.60)
:::When specified, this will add an offset to all frame numbers in the {{BoldColor|blue|100|''data''}} lines below.  
+
:::When specified, this will add an offset adjustment to all frame numbers in the {{BoldColor|blue|100|''data''}} lines below.  
 
+
::Optional {{BoldColor|blue|100|''comment''}} and empty line(s)
+
  
 
*Next come the {{BoldColor|blue|100|''data''}} line(s), which set the per-frame value(s) to be assigned to the script variable. There are three styles:
 
*Next come the {{BoldColor|blue|100|''data''}} line(s), which set the per-frame value(s) to be assigned to the script variable. There are three styles:
  
::''Single-frame'' data line:  
+
::''Single-frame'' style:  
 
:::<code><framenumber> <value></code>
 
:::<code><framenumber> <value></code>
 
:::Set ''value'' for frame ''framenumber'' only.
 
:::Set ''value'' for frame ''framenumber'' only.
  
::''Range'' data line:  
+
::''Range'' style:  
 
:::<code>R <startframe> <endframe> <value></code>
 
:::<code>R <startframe> <endframe> <value></code>
 
:::Apply ''value'' to a range of frames.  
 
:::Apply ''value'' to a range of frames.  
:::Note that both ''startframe'' and ''endframe'' are included.
+
:::Note that both ''startframe'' and ''endframe'' are included in the range.
  
::''Interpolated'' data line:
+
::''Interpolated'' style:
:::<code>I <startframe> <endframe> <startvalue> <stopvalue></code>
+
:::<code>I <startframe> <endframe> <start-value> <stop-value></code>
:::Interpolate between two ''values'' over a range of frames. This only works on ''int'' and ''float'' types.
+
:::Interpolate between ''start-value'' and ''stop-value'' over a range of frames. This only works on ''int'' and ''float'' types.
:::Note that both ''startframe'' and ''endframe'' are included.
+
:::Note that both ''startframe'' and ''endframe'' are included in the range.
  
:''Values'' must be valid for the defined {{BoldColor|blue|100|''type''}}, as defined above, or file parsing will fail and an error will be raised.
+
:Later data lines in the file overrule earlier ones. Styles may be mixed-and-matched; see the examples below.
 
+
:All {{BoldColor|blue|100|''data''}} and {{BoldColor|blue|100|''default''}} ''values'' must be valid for the defined {{BoldColor|blue|100|''type''}}, as defined above, or an error will be raised.
 
+
To sum up the file format in approximate [[wikipedia:Backus–Naur_Form|BNF]]-style:
+
<div {{BoxWidthIndent|58|1}} >
+
input_file:
+
    comment_line*  /* asterisk means zero or more */
+
    WS* 'TYPE' WS ( 'int' | 'float' | 'bool' | 'string' ) /* choose one */
+
    header
+
    data_line+      /* plus sign means one or more */
+
+
comment_line:
+
    WS* ( '#' | ';' | '%' ) <ignore any characters to end of line>
+
+
WS:
+
    ( ' ' | '\t' )+ /* WS = one or more spaces or tabs */
+
+
header:            /* header = zero or more of the following in any order */
+
(
+
    WS* 'DEFAULT' WS <type value>      /* legal value for TYPE */
+
  | WS* 'OFFSET' WS <int offset_value>
+
  | WS*
+
  | comment_line
+
)*
+
+
data_line:          /* data = one or more of the following in any order */
+
(
+
    WS* <int framenumber> WS <type value>
+
  | WS* 'R' WS <int startframe> WS <int endframe> WS <type value>
+
  | WS* 'I' WS <int startframe> WS <int endframe> WS <type startvalue> WS <type endvalue>
+
)
+
</div>
+
 
</div>
 
</div>
  
Line 112: Line 82:
 
<div style="max-width:62em" >
 
<div style="max-width:62em" >
 
===== ''Basic usage'' =====
 
===== ''Basic usage'' =====
:Example file ''File.txt:''
+
:File ''Basic.txt:''
 
<div {{BoxWidthIndent|24|3}} >
 
<div {{BoxWidthIndent|24|3}} >
 
  Type float
 
  Type float
Line 124: Line 94:
 
:The file above will return values of type ''float''. It will return <tt>3.45567</tt> by default, but at frames 45-300 it will return <tt>76.5654</tt>, and at frames 2 and 72 it will return <tt>-671.454</tt>.  
 
:The file above will return values of type ''float''. It will return <tt>3.45567</tt> by default, but at frames 45-300 it will return <tt>76.5654</tt>, and at frames 2 and 72 it will return <tt>-671.454</tt>.  
  
:Later lines in the file overrule earlier ones. This is illustrated by the '72' line: even though frame 72 is inside the range of 45-300, frame 72 will use the value <tt>-671.454</tt>, not <tt>76.5654</tt>. If the 'R' line had been placed ''after'' the '72' line, the range value would have had priority.
+
:Later data lines in the file overrule earlier ones. This is illustrated by the '72' line: even though frame 72 is inside the range of 45-300, frame 72 will use the value <tt>-671.454</tt>, not <tt>76.5654</tt>. If the 'R' line had been placed ''after'' the '72' line, the range value would have had priority.
  
 
:A script to invoke this file could be:
 
:A script to invoke this file could be:
Line 130: Line 100:
 
  [[ColorBars]](512,512)
 
  [[ColorBars]](512,512)
 
  [[Trim]](0,500)
 
  [[Trim]](0,500)
  [[ScriptClip]]("subtitle(string(myvar))")
+
  [[ScriptClip]]("Subtitle(String(myvar))")
  ConditionalReader("file.txt", "myvar", false)
+
  ConditionalReader("Basic.txt", "myvar", false)
 
</div>
 
</div>
  
:This will put the values into the variable called <tt>myvar</tt>, which is displayed with [[Subtitle]]. Subtitle must be invoked by [[ScriptClip]] to display the conditional value.
+
:This will put the values into the variable called <tt>myvar</tt>, which is displayed with [[Subtitle]]. Subtitle must be invoked by [[ScriptClip]] to display the [[Runtime_environment|runtime]] value.
 +
 
 +
:'''Note''' the '''ConditionalReader''' line comes ''after'' any use of <tt>myvar</tt> in the script.
 +
 
 +
===== ''String values'' =====
 +
:File ''Strings.txt:''
 +
<div {{BoxWidthIndent|24|3}} >
 +
Type string
 +
Default
 +
# (default=empty string)
 +
 +
R  45  99 this is a string
 +
R 100 199 "quoted string"
 +
R 200 299 w:\xyz.txt
 +
</div>
 +
:Try the above Subtitle script with ''Strings.txt''. You will see the strings displayed verbatim.
  
 
===== ''Adjusting Overlay'' =====
 
===== ''Adjusting Overlay'' =====
Line 167: Line 152:
 
</div>
 
</div>
  
:Basically this example defines ''keyframes'' for an [[Overlay]] x-offset and opacity. For frames 25-50 the opacity is scaled from 0.0 to 1.0, while the text is moving from left to right. The text is then kept steady from frame 50-250, and thereafter it moves further to the right while fading out. It is easier to watch the clip above than completely describe what it does.
+
:It is easier to watch the clip above than completely describe what it does. Basically, this example defines ''keyframes'' for an [[Overlay]] x-offset and opacity. For frames 25-50 the opacity is scaled from 0.0 to 1.0, while the text is moving from left to right. The text is then kept steady from frame 50-250, and thereafter it moves further to the right, while fading out.  
  
===== ''Complicated ApplyRange'' =====
+
===== ''ApplyRange replacement'' =====
:As you may have noticed, using a large number of [[ApplyRange]] calls in a script can lead to resource issues. Using '''ConditionalReader''' together with [[ConditionalFilter]] can lead to an efficient solution:
+
:Using a large number of [[ApplyRange]] calls in a script can lead to resource issues. '''ConditionalReader''' together with [[ConditionalFilter]] can be used instead, leading to an efficient solution:
  
 
:File ''File.txt:''
 
:File ''File.txt:''
Line 185: Line 170:
 
</div>
 
</div>
  
:The file above will return boolean values. It will by default return False. However frames 2, 45 to 60, 72, 200 to 220 and 315 except for 210 it will return True. As you might notice, later changes overrule settings done earlier in the file. This is illustrated by frame '210' - even though it is inside the range of 200-220, the later value, False, will be returned.
+
:By default, the script value will be False. However for frames 2, 45-60, 72, 200-220 and 315, except for 210, it will be True. Later data lines in the file overrule earlier ones. This is illustrated by frame '210': even though it is inside the range of 200-220, the later value, False, will be used.
  
 
:A script to make use of this file could be:
 
:A script to make use of this file could be:
Line 194: Line 179:
 
  [[FlipHorizontal]] # Add a complex filter chain
 
  [[FlipHorizontal]] # Add a complex filter chain
 
  B = Last
 
  B = Last
  ConditionalFilter(A, B, "MyVar", "==", "False", false)
+
  [[ConditionalFilter]](A, B, "myvar", "==", "False", false)
  ConditionalReader("File.txt", "MyVar", false)
+
  ConditionalReader("File.txt", "myvar", false)
 
</div>
 
</div>
  
:This will put the values into the variable called <tt>MyVar</tt>, which is used by [[ConditionalFilter]] to select between the unprocessed and flipped version of the source.
+
:This will read the file values into the variable <tt>myvar</tt>, which is used by [[ConditionalFilter]] to select between the unprocessed and flipped version of the source.
 
+
:'''Note!''' The '''ConditionalReader''' line comes ''after'' any use of <tt>MyVar</tt> in the script.
+
  
===== ''Returning Strings'' =====
+
===== ''Strings values in v2.58'' =====
 
:'''ConditionalReader''' cannot return strings prior to v2.60, but one solution is to create a list of variables with corresponding string assignments, and [[Internal functions/Eval|Eval]] the indexed solution.  For example:
 
:'''ConditionalReader''' cannot return strings prior to v2.60, but one solution is to create a list of variables with corresponding string assignments, and [[Internal functions/Eval|Eval]] the indexed solution.  For example:
 
<div {{BoxWidthIndent|42|3}} >
 
<div {{BoxWidthIndent|42|3}} >

Revision as of 15:03, 25 February 2016

Import information from a text file and assign a per-frame value to a script variable.

Contents

Syntax and Parameters

ConditionalReader(clip clip, string filename, string variablename [, bool show ] )

clip  clip =
Source clip. Not touched, unless you specify show=true.
string  filename =
Path to the file with the per-frame values you want to set. See File format below.
string  variablename =
Name of the variable you want the filename values assigned to.
bool  show = false
If true, show the variablename value at the current frame (as determined by the file values) as a text overlay.


File format

  • The file is plain text. It is not case sensitive. Each line stands alone. There are several different line types, as explained below.
  • The file may begin with one or more optional comment lines:

Any line is ignored if the first non-whitespace character is '#' (hash), ';' (semicolon) or '%' (percent).

#this line is a comment
;so is this line
     %and this one too.
  • The first non-comment line should be a type line, which sets the value type for all following lines. There are four valid type lines:
TYPE int
Tells ConditionalReader to expect decimal integer values.
(digits 0-9, optionally preceded with a '+' or '-' sign)
TYPE float
Tells ConditionalReader to expect floating-point values.
(decimal number with '.' decimal point, and optionally followed by an 'E' character and decimal exponent)
TYPE bool
Tells ConditionalReader to expect boolean values.
('true' or 'false', 'T' or 'F', 'yes' or 'no', '1' or '0')
TYPE string (from v2.60)
(any sequence of characters, including quote, backslash etc; a line break ends the string)
The type line defines the data type to be parsed from this file and assigned to the variable variablename. You must have one, and only one, type line per file, and it must come before any other lines, except for optional comments.
  • A default line should come next. It is optional but strongly suggested:
DEFAULT <value>
This specifies the value to be used if there is no applicable data line for a given frame.
If you do not define a default, be sure to specify a value for all frames; otherwise your script variable could be be undefined or take a random value.
  • An optional offset line may appear:
OFFSET <integer-value> (from v2.60)
When specified, this will add an offset adjustment to all frame numbers in the data lines below.
  • Next come the data line(s), which set the per-frame value(s) to be assigned to the script variable. There are three styles:
Single-frame style:
<framenumber> <value>
Set value for frame framenumber only.
Range style:
R <startframe> <endframe> <value>
Apply value to a range of frames.
Note that both startframe and endframe are included in the range.
Interpolated style:
I <startframe> <endframe> <start-value> <stop-value>
Interpolate between start-value and stop-value over a range of frames. This only works on int and float types.
Note that both startframe and endframe are included in the range.
Later data lines in the file overrule earlier ones. Styles may be mixed-and-matched; see the examples below.
All data and default values must be valid for the defined type, as defined above, or an error will be raised.


Examples

Basic usage
File Basic.txt:
Type float
Default 3.45567

R 45 300 76.5654
2 -671.454
72 -671.454
The file above will return values of type float. It will return 3.45567 by default, but at frames 45-300 it will return 76.5654, and at frames 2 and 72 it will return -671.454.
Later data lines in the file overrule earlier ones. This is illustrated by the '72' line: even though frame 72 is inside the range of 45-300, frame 72 will use the value -671.454, not 76.5654. If the 'R' line had been placed after the '72' line, the range value would have had priority.
A script to invoke this file could be:
ColorBars(512,512)
Trim(0,500)
ScriptClip("Subtitle(String(myvar))")
ConditionalReader("Basic.txt", "myvar", false)
This will put the values into the variable called myvar, which is displayed with Subtitle. Subtitle must be invoked by ScriptClip to display the runtime value.
Note the ConditionalReader line comes after any use of myvar in the script.
String values
File Strings.txt:
Type string
Default 
# (default=empty string)

R  45  99 this is a string
R 100 199 "quoted string"
R 200 299 w:\xyz.txt
Try the above Subtitle script with Strings.txt. You will see the strings displayed verbatim.
Adjusting Overlay
Script:
ColorBars(512,256)
a1 = Trim(0,600)
a2 = MessageClip("Text clip")
Overlay(a1,a2, y = 100, x = 110, mode="subtract", opacity=0, pc_range=true)
ConditionalReader("opacity.txt", "ol_opacity_offset", false)
ConditionalReader("xoffset.txt", "ol_x_offset", false)
File xoffset.txt:
Type int
Default -50

I 25 50 -50 100
R 50 250 100
I 250 275 100 250
File opacity.txt:
Type float
Default 0.0

I 25 50 0.0 1.0
R 50 250 1.0
I 250 275 1.0 0.0
It is easier to watch the clip above than completely describe what it does. Basically, this example defines keyframes for an Overlay x-offset and opacity. For frames 25-50 the opacity is scaled from 0.0 to 1.0, while the text is moving from left to right. The text is then kept steady from frame 50-250, and thereafter it moves further to the right, while fading out.
ApplyRange replacement
Using a large number of ApplyRange calls in a script can lead to resource issues. ConditionalReader together with ConditionalFilter can be used instead, leading to an efficient solution:
File File.txt:
Type Bool
Default False

2 True
R 45 60 True
72 True
R 200 220 True
210 False
315 True
By default, the script value will be False. However for frames 2, 45-60, 72, 200-220 and 315, except for 210, it will be True. Later data lines in the file overrule earlier ones. This is illustrated by frame '210': even though it is inside the range of 200-220, the later value, False, will be used.
A script to make use of this file could be:
ColorBars(512,512)
Trim(0,500)
A = Last
FlipHorizontal # Add a complex filter chain
B = Last
ConditionalFilter(A, B, "myvar", "==", "False", false)
ConditionalReader("File.txt", "myvar", false)
This will read the file values into the variable myvar, which is used by ConditionalFilter to select between the unprocessed and flipped version of the source.
Strings values in v2.58
ConditionalReader cannot return strings prior to v2.60, but one solution is to create a list of variables with corresponding string assignments, and Eval the indexed solution. For example:
Import("strings.txt")
ScriptClip("""subtitle(Eval("n"+string(mystringindex)))""")
ConditionalReader("range_string.txt", "mystringindex")
File strings.txt
n0=""
n1="Intro"
n2="Main"
n3="Credits"
File range_string.txt
Type int
Default 0

R 10 1000 1
R 1005 3000 2
R 3200 3800 3
Obviously strings.txt does not need to be a separate file, but this solution is sometimes appropriate in e.g., multilingual applications:
language="spanish" 
Import(language + "_strings.txt")


Changelog

v2.60 Added OFFSET, Added Type=string.
Personal tools