I'm here because TASing combines three big facets of my life: video games, computer science, and obsessive compulsive behavior. Sometimes I encode videos.
SetFilterMTMode("DEFAULT_MT_MODE", MT_MULTI_INSTANCE)
# The downloadable/HD encoding script
# http://tasvideos.org/EncodingGuide/PublicationManual.html
AviSource("")
# Dolphin (with FFMPEG). Use FFV1 patch for dumping:
# https://github.com/vadosnaprimer/dolphin/releases
# AviSource("movie.avi", pixel_type="RGB24")
# AudioDub(last, wavsource("dspdump.wav"))
preview = false # Set true for 1080p
downscale = false # Set to downscale high res source for SD encodes (set extra hq w/h)
trimFrame = 654321 # manual, discards logo lengh automatically
handHeld = false # auto, but set it for preview
hd = false # auto, but set it for preview
halfFPS = false # for games that "lag" every other frame
stackNDS = false # stack one of NDS screens near both of them for HD
global vb = false # for Virtual Boy encodes
# Resizer (for hd upscaling and multisegment import)
resizer = hd ? "Point" : "Lanczos"
# force Lanczos for 3D footage with increased internal resolution
# resizer = "Lanczos"
# Subtitles contents
game = "gamename"
branch = "'branch'" # lowercase for usual words, capital for in-game capital words. when blank, leave "''"
author = "author"
time = "00:00.00"
rerecords = "0"
# Subtitles timing and placement
subFF = 600 # first subtitles frame, set manually!
subAlign = 8 # subtitles horizontal alignment (7/8/9)
subEntry = 2 # sets the number of sub entries (2/3/4)
subYpos = 0 # subtitles vertical position
subXoffs = 0 # subtitles horizontal offset (can be negative)
subLengthMul = 5.00 # entry length in seconds (fractions work)
subFF2delay = 0 # extra delay in frames between subtitle entries 1 and 2
subFF2delay2 = 0 # extra delay in frames between subtitle entries 2 and 3
subFF2delay3 = 0 # extra delay in frames between subtitle entries 3 and 4
subFont = "helv" # see "fonts" folder for available types
bighaloCutoff = 384 # width and height above this will use bighalo instead of freesub
# Subtitle fades
fadeIn1 = 0 # number of frames to fade in subtitle entry 1 from black (set to 0 to disable fade)
fadeIn2 = 0 # number of frames to fade in subtitle entry 2 from black
fadeIn3 = 0 # number of frames to fade in subtitle entry 3 from black
fadeIn4 = 0 # number of frames to fade in subtitle entry 4 from black
fadeOut1 = 0 # number of frames to fade out subtitle entry 1 to black (set to 0 to disable fade)
fadeOut2 = 0 # number of frames to fade out subtitle entry 2 to black
fadeOut3 = 0 # number of frames to fade out subtitle entry 3 to black
fadeOut4 = 0 # number of frames to fade out subtitle entry 4 to black
# Multisegment import (upscales hires segments straight to HD when needed)
# requires normally importing a sample whose attributes it will use for all segments
ms = true # enable multisegment import
ms_base = "" # common string for all segment names
ms_start = 0 # number of the first segment
ms_end = 15 # number of the last segment
ms_format = "%1.0f" # string format: http://avisynth.nl/index.php/Internal_functions#String
# Extra HQ (upscaled downloadable encodes)
hq = false # auto
hq_scale = 2 # manual for now
hq_hiResSrc = false # we downscale hires 3D source, and upscale lowres pixelated source
hq_baseWidth = 320 # aspect-corrected 1x width (only for hires source)
hq_baseHeight = 240 # aspect-corrected 1x height (only for hires source)
# Aspect ratio correction
wAspect = 4
hAspect = 3
# Subtitles text
subString1 = game + "\n" \
+ (branch == "''" ? "" : branch + "\n") \
+ "Played by " + author
subString2 = "Playing time: " + time \
+ "\nRerecord count: " + rerecords
subString3 = "This is a tool-assisted recording." \
subString4 = "For details, visit http://TASVideos.org/"
################
# LEGACY STUFF #
################
# Famtasia
# ConvertAudioTo16bit()
# Mupen64
# ResampleAudio(last, 44100)
# Crop(0,0,-0,-20) # when old Glide64 is used
# PSXjin
# audio = WavSource("movie_000.wav")
# AudioDub(audio, last)
# Old Dolphin (remove /* and */ to uncomment)
# get values at http://tasvideos.org/forum/viewtopic.php?p=373299#373299
/*
M = 486000000
F = 60
k = 1
N = 525
b = 0
D = (k * N + b) * floor(floor(M / F) / N) # don't edit this formula
LoadCPlugin("./programs/timecodefps.dll")
video = last.TimecodeFPS("timecodes.txt", fpsnum=M, fpsden=D)
audio = \
WavSource("dspdump0.wav") + \
WavSource("dspdump1.wav").ResampleAudio(32000) + \
WavSource("dspdump.wav")
*/
# Fix progressing (not floating) desync
# AssumeFPS(last.FrameCount / last.AudioLengthF * last.AudioRate)
######################
# AUTOMATED SETTINGS #
######################
ConvertToRGB32()
# Add 1 scanline if height is uneven (ntsc sms, pal c64)
last.height % 2 > 0 ? StackVertical(last, Crop(0, Height-1, 0, 0)) : 0
pass = 0
i444 = false
originalWidth = last.width
originalHeight = last.height
hdvb = hd && vb
root = ScriptDir()
Import (root + "\programs\functions.avsi")
#LoadPlugin (root + "programs\ExactDedup.dll")
#LoadPlugin (root + "programs\mvtools2.dll")
#LoadPlugin (root + "programs\mt_masktools-26.dll")
#LoadPlugin (root + "programs\autolevels_0.6_20110109.dll")
#LoadCPlugin(root + "programs\freesub.dll")
#LoadCPlugin(root + "programs\assrender.dll" )
# Make too dark scenes brighter
# AutoLevels(filterRadius=1000, sceneChgThresh=200, gamma=1.1)
# VirtualBoy (bizhawk only!)
# http://tasvideos.org/forum/viewtopic.php?p=435440#435440
left = vb ? Crop( 0, 0, 384, 224).Levels(0, 1, 255, 0, 157) : 0
right = vb ? Crop(384, 0, 384, 224).Levels(0, 1, 255, 0, 157) : 0
vb ? hd ? 0 : Anaglyph(left, right, "grey").AudioDub(left) : 0
# Pick logo file
file = hd || hq \
? vb \
? "logoGrey.png" \
: stackNDS \
? "logohdnds.png" \
: last.height == 384 \
? "logonds.png" \
: "hdlogo.gif" \
: last.height == 384 \
? "logonds.png" \
: "sdlogo.gif"
# file = !hd ? "logo34.png" : "hdlogo34.png"
# Stack 3 NDS screens
upperScreen = last.Crop(0, 0, -0, last.height/2)
lowerScreen = last.Crop(0, last.height/2, -0, -0)
halfScreen = upperScreen # set which NDS screen to put as main
stackNDS && hd ? StackHorizontal(halfScreen.PointResize(last.width*2, last.height), last) : 0
# Aspect ratio correction for SD encodes
height = handHeld \
? last.height \
: last.width > last.height * wAspect / hAspect \
? last.width * hAspect / wAspect \
: last.height
width = handHeld \
? last.width \
: height * wAspect / hAspect
width = width % 4 == 1 ? width + 3 \
: width % 4 == 2 ? width + 2 \
: width % 4 == 3 ? width + 1 : width
height = height % 4 == 1 ? height + 3 \
: height % 4 == 2 ? height + 2 \
: height % 4 == 3 ? height + 1 : height
# Remember SD frame size for subYpos HD tweaks
wARC = width
hARC = height
# Actually go HD if we need
height = hd ? (preview ? 1080 : 2160) : height
width = handHeld \
? height * last.width / last.height \
: height * wAspect / hAspect
width = width % 4 == 1 ? width + 3 : \
width % 4 == 2 ? width + 2 : \
width % 4 == 3 ? width + 1 : width
# Rescaling
# extra HQ:
# hires source: downscale straight to aspect-corrected res with lanczos
# lowres source: upscalse by our factor with point, then do ARC with lanczos for 512kb
# hd:
# resize to 4K, then just subsample with lanczos in the end
# for hires 3D footage, upscaled with lanczos
# handheld and primary (dedupped): do nothing
# 512kb: do ARC with lanczos
resized = hq && !hd \
? hq_hiResSrc \
? Lanczos4Resize(hq_baseWidth * hq_scale, hq_baseHeight * hq_scale) \
: handHeld || pass != 0 \
? PointResize(last.width * hq_scale, last.height * hq_scale) \
: PointResize(last.width * hq_scale, last.height * hq_scale) \
.Lanczos4Resize(width * hq_scale, height * hq_scale) \
: hd \
? eval(resizer+"Resize(width, height)") \
: handHeld || pass != 0 \
? last \
: Lanczos4Resize(width, height)
# If ms enabled, we use parameters of "resized" to apply to all segments
resized = ms ? resized.AppendSegment(ms_base, ms_start, ms_end, ms_format, resizer).ConvertToRGB32() : resized
# Downscale for high res source and SD encodes
resized = downscale ? hd ? resized : AreaResize(resized, hq_baseWidth, hq_baseHeight) : resized
# Logo
logoVideo = ImageSourceAnim(file=file, fps=60.0).ConvertToRGB32().ChangeFPS(resized)
logoAudio = BlankClip(logoVideo, audio_rate=resized.AudioRate, channels=resized.AudioChannels)
logo = AudioDub(logoVideo, logoAudio).Lanczos4Resize(resized.width, resized.height)
last = hdvb ? logo.PointResize(resized.width / 2, resized.height) : logo ++ resized
# Virtual Boy
left = hdvb ? last ++ left.PointResize(last.width, last.height) : 0
right = hdvb ? last ++ right.PointResize(last.width, last.height) : 0
# Additional subtitle magic
# figure out how much our font will be changed after x264 ARC and for HD
wFactor = hd || hq ? float(last.width) / wARC : 1
hFactor = hd || hq ? float(last.height) / hARC : 1
wStretch = (handHeld || pass == 0) && !hdvb ? 1 \
: (float(last.width) / last.height) / (float(wAspect) / hAspect)
smallerSide = last.height < last.width ? last.height : last.width
biggerSide = last.height > last.width ? last.height : last.width
# use bighalo if we're relatively hires
# or if font stretch on some side is too heavy (ARCed primary)
global useBighalo = biggerSide > bighaloCutoff \
|| ((wStretch < 0.8 || wStretch > 1.3) \
&& !handHeld && pass != 0 \
&& smallerSide >= 224)
# Subtitles variables
subXoffs = int(subXoffs * wStretch)
subRatio = float(last.height) / 21
#subRatio = float(smallerSide) / 21
subXpos = subAlign == 7 || subAlign == 4 || subAlign == 1 \
? (2 + subXoffs) * wFactor \
: subAlign == 8 || subAlign == 5 || subAlign == 2 \
? last.width / 2 + subXoffs * wFactor \
: last.width - (2 + subXoffs) * wFactor
subXpos = hdvb ? subXpos / 2 : subXpos
subYpos = int(float(subYpos) / (wStretch > 1 ? wStretch : 1) * hFactor)
subYpos = hdvb ? subYpos * hFactor : subYpos
global subSize = useBighalo ? subRatio \
: subRatio < 10 ? 8 \
: subRatio < 12 ? 10 \
: subRatio < 14 ? 12 \
: subRatio < 18 ? 14 \
: subRatio < 24 ? 18 : 24
global subWidth = useBighalo && !hd ? float(subSize) / 2.323 * wStretch : 0
subHaloSize = useBighalo ? floor(subSize / 7) : floor(subSize / 4.5)
global subHaloSize = subHaloSize < 3 ? 3 : subHaloSize
subFontName = subFont + (smallerSide < 224 ? "R" : "B")
global subFontFile = "./fonts/" + subFontName + string(subSize) + ".bdf"
subLength = int(last.FrameRate * subLengthMul)
subFF2 = SubFF + subLength + 1 + subFF2delay
subFF3 = SubFF2 + subLength + 1 + subFF2delay2
subFF4 = SubFF3 + subLength + 1 + subFF2delay3
global subColor = vb ? $009D9D9D : $00FFFFFF
global subRadius = hd ? subHaloSize : 0
subFadeIn1 = subFF + fadeIn1
subFadeIn2 = subFF2 + fadeIn2
subFadeIn3 = subFF3 + fadeIn3
subFadeIn4 = subFF4 + fadeIn4
subFadeOut1 = subFF + subLength - fadeOut1
subFadeOut2 = subFF2 + subLength - fadeOut2
subFadeOut3 = subFF3 + subLength - fadeOut3
subFadeOut4 = subFF4 + subLength - fadeOut4
# Subtitles functions
function subs(clip c, string text, float x, float y, int align, int first_frame, int last_frame, int fade, int fade2)
{
useBighalo \
? vb \
? 0 \
: ng_bighalo(c, text, x=x, y=y, align=align, first_frame=first_frame, \
last_frame=last_frame, size=subSize, font_width=subWidth, text_color=subColor, \
halo_color=$00000000, lsp=2, halo_radius=subRadius, fade=fade, fade2=fade2) \
: FreeSub2(c, text, x=int(x), y=int(y+subHaloSize), align=align, first_frame=first_frame, last_frame=last_frame, \
font=subFontFile, halo_width=subHaloSize, halo_height=subHaloSize, \
text_color=subColor, halo_color=$00000000, lsp=2, fade=fade, fade2=fade2) \
}
subEntry == 2 ? subs(subString1 + "\n" + subString2, subXpos, subYpos, subAlign, subFF, subFF+subLength, subFadeIn1, subFadeOut1) : 0
subEntry == 2 ? subs(subString3 + "\n" + subString4, subXpos, subYpos : subYPos, subAlign, subFF2, subFF2+subLength, subFadeIn2, subFadeOut2) : 0
subEntry == 3 || subEntry == 4 ? subs(subString1, subXpos, subYpos, subAlign, subFF, subFF+subLength, subFadeIn1, subFadeOut1) : 0
subEntry == 3 || subEntry == 4 ? subs(subString2, subXpos, subYpos, subAlign, subFF2, subFF2+subLength, subFadeIn2, subFadeOut2) : 0
subEntry == 3 ? subs(subString3 + "\n" + subString4, subXpos, subYpos, subAlign, subFF3, subFF3+subLength, subFadeIn3, subFadeOut3) : 0
subEntry == 4 ? subs(subString3, subXpos, subYpos, subAlign, subFF3, subFF3+subLength, subFadeIn3, subFadeOut3) : 0
subEntry == 4 ? subs(subString4, subXpos, subYpos, subAlign, subFF4, subFF4+subLength, subFadeIn4, subFadeOut4) : 0
# Virtual Boy hacks
left = hdvb ? left \
.ng_bighalo(subString1, x=subXpos, y=subYpos, \
align=subAlign, first_frame=subFF, last_frame=subFF+subLength, \
size=subSize, text_color=subColor, halo_color=$00000000, lsp=2) \
.ng_bighalo(subString2, x=subXpos, y=subYpos, \
align=subAlign, first_frame=subFF2, last_frame=subFF2+subLength, \
size=subSize, text_color=subColor, halo_color=$00000000, lsp=2) \
.ng_bighalo(subString3 + "\n" + subString4, x=subXpos, y=subYpos, \
align=subAlign, first_frame=subFF3, last_frame=(subFF3+SubLength), \
size=subSize, text_color=subColor, halo_color=$00000000, lsp=2) : 0
right = hdvb ? right \
.ng_bighalo(subString1, x=subXpos, y=subYpos, \
align=subAlign, first_frame=subFF, last_frame=subFF+subLength, \
size=subSize, text_color=subColor, halo_color=$00000000, lsp=2) \
.ng_bighalo(subString2, x=subXpos, y=subYpos, \
align=subAlign, first_frame=subFF2, last_frame=subFF2+subLength, \
size=subSize, text_color=subColor, halo_color=$00000000, lsp=2) \
.ng_bighalo(subString3 + "\n" + subString4, x=subXpos, y=subYpos, \
align=subAlign, first_frame=subFF3, last_frame=subFF3+SubLength, \
size=subSize, text_color=subColor, halo_color=$00000000, lsp=2) : 0
hdvb ? yt3d(left, right).AudioDub(left) : 0
Trim(0, trimFrame)
# Youtube can't hanble fps above 60
hd && last.FrameRate > 60 ? ChangeFPS(60) : 0
halfFPS ? SelectOdd : 0
# YV24 conversion doesn't reduce chroma, so "point" is fine
ConvertToYV24(chromaresample="point", matrix=(hd \
? "Rec709" \
: (pass == 0 \
? "Rec601" \
: "PC.601")))
# pass == 1 ? assrender("subtitles.ass") : 0
# Remove duplicate frames for primary
pass == 1 ? ExactDedup(firstpass=true, dupinfo="./temp/dup.txt",times="./temp/times.txt") : 0
pass == 2 ? ExactDedup(firstpass=false,dupinfo="./temp/dup.txt" ) : 0
# YV12 reduces chroma, so we use "lanczos" even for HD
# http://tasvideos.org/forum/viewtopic.php?t=19426
i444 ? last : ConvertToYV12(chromaresample="lanczos", matrix=(hd \
? "Rec709" \
: (pass == 0 \
? "Rec601" \
: "PC.601")))
pass != 1 ? Prefetch(7) : last
# Multisegment AVI import
function AppendSegment(
\ clip sample,
\ string base,
\ int first_val,
\ int last_val,
\ string format,
\ string resizer
\){
filename = base + string(first_val, format) + ".avi"
result = AviSource(filename).Eval(resizer + """Resize(sample.width, sample.height)""")
return (first_val < last_val) \
? result ++ sample.AppendSegment(base, first_val+1, last_val, format, resizer) \
: result
}
# Multisegment FFMPEG AVI import
function FFAppendSegment(
\ clip sample,
\ string base,
\ int first_val,
\ int last_val,
\ string format,
\ string resizer,
\ string csp,
\ int fps
\){
filename = base + string(first_val, format) + ".avi"
result = Exist(filename) \
? FFVideoSource(filename, colorspace=csp, fpsnum=fps, fpsden=1).Eval(resizer + """Resize(sample.width, sample.height)""") \
: BlankClip(length=0, width=sample.width, height=sample.height, fps=fps, pixel_type="RGB24").KillAudio()
return Exist(filename) \
? (first_val < last_val) \
? result + sample.FFAppendSegment(base, first_val+1, last_val, format, resizer, csp, fps) \
: result \
: (first_val < last_val) \
? sample.FFAppendSegment(base, first_val+1, last_val, format, resizer, csp, fps) \
: BlankClip(length=0, width=sample.width, height=sample.height, fps=fps, pixel_type="RGB24").KillAudio()
}
function Remove(
\ clip c,
\ int start,
\ int end
\){
c
Trim(0, -start) + Trim(end, 0)
}
function Replace(
\ clip dest,
\ int start,
\ int end,
\ clip src
\){
Assert(start >= 0, "Replace: parameter 'start' is negative")
Assert( end >= 0, "Replace: parameter 'end' is negative")
p1 = dest.Trim(0, -start)
p2 = src.Trim(start, end)
p3 = dest.Trim(end + 1, 0)
p1 = (start == 0) ? dest.Trim(0, -1).DeleteFrame(0) : p1
p3 = ( end == 0) ? dest.Trim(0, -1).DeleteFrame(0) : p3
p1 + p2 + p3
return (dest.HasAudio) ? last.AudioDub(dest) : last
}
# HD encodes need big subtitle fonts, but AviSynth can't enlarge the halo.
# Here's the custom subtitle function by nanogyth
# It's slow, but we have subtitles for a limited time only
function ng_bighalo(
\ clip clp,
\ string text,
\ float "x",
\ float "y",
\ int "first_frame",
\ int "last_frame",
\ string "font",
\ float "size",
\ int "text_color",
\ int "halo_color",
\ int "align",
\ int "spc",
\ int "lsp",
\ float "font_width",
\ float "font_angle",
\ int "halo_radius",
\ string "mode",
\ string "halo",
\ string "shadow",
\ int "fade",
\ int "fade2"
\){
#Version 16-17 2012/12/1
# - added circle_12 as default
# - reworked math to avoid bitwise functions that are only
# availible in experimental builds
#Version 15 2012/12/1
# - drop shadow added
# - halo_radius still works, but calculating the points of
# a hollow circle for halo is much faster
# - mode is depricated since memo-ing isn't as needed
first_frame = default(first_frame, 0)
last_frame = default( last_frame, first_frame + 299)
font = default( font, "Arial")
size = default( size, 112)
x = default( x, -1)
y = default( y, -1)
text_color = default( text_color, $00DDDDDD)
halo_color = default( halo_color, $80000000)
align = default( align, 5)
spc = default( spc, 0)
lsp = default( lsp, 0)
font_width = default( font_width, 0)
font_angle = default( font_angle, 0)
shadow = default( shadow, "")
w = clp.width
h = clp.height
fade = default(fade, first_frame)
fade2 = default(fade2, last_frame)
###
###
##
#
#
#
#
#
#
#
#
#
# #
circle_12="0 0 "+\
"12 0 0 12 -12 0 0 -12 "+\
"1 12 2 12 3 11 4 11 5 11 6 10 7 10 8 9 "+\
"12 1 12 2 11 3 11 4 11 5 10 6 10 7 9 8 "+\
"-1 12 -2 12 -3 11 -4 11 -5 11 -6 10 -7 10 -8 9 "+\
"-12 1 -12 2 -11 3 -11 4 -11 5 -10 6 -10 7 -9 8 "+\
"-1 -12 -2 -12 -3 -11 -4 -11 -5 -11 -6 -10 -7 -10 -8 -9 "+\
"-12 -1 -12 -2 -11 -3 -11 -4 -11 -5 -10 -6 -10 -7 -9 -8 "+\
"1 -12 2 -12 3 -11 4 -11 5 -11 6 -10 7 -10 8 -9 "+\
"12 -1 12 -2 11 -3 11 -4 11 -5 10 -6 10 -7 9 -8 "
halo = (defined(halo_radius) && halo_radius != 0) ? mt_circle(halo_radius) : circle_12
invis = BlankClip(1, w, h, pixel_type="YV12")
tm = Subtitle(invis, text, x, y, 0, 0, font, size, $00FFFFFF,\
0, align, spc, lsp, font_width, font_angle)
text_mask = tm.mt_expand(mode="0 0 "+shadow, chroma="-128")
halo_mask = text_mask.mt_expand(mode=halo, chroma="-128")
h0 = halo_color%$01000000
h_color = (h0>=0) ? h0 : $01000000+h0
t0 = text_color%$01000000
t_color = (t0>=0) ? t0 : $01000000+t0
h_alpha = (halo_color>=0) ? 255-(halo_color/$01000000) : (-halo_color-1)/$01000000
t_alpha = (text_color>=0) ? 255-(text_color/$01000000) : (-text_color-1)/$01000000
lut_str = string(h_alpha)+ " x * 255 / " +string(t_alpha)+\
" " +string(h_alpha)+ " - y * 255 / +"
alpha_mask = mt_lutxy(halo_mask, text_mask, lut_str)
hc = BlankClip(1, w, h, color=h_color)
tc = Subtitle(hc, text, x, y, 0, 0, font, size, t_color,\
0, align, spc, lsp, font_width, font_angle)
overlay = tc.Mask(alpha_mask.ConvertToRGB32())
(fade == first_frame && fade2 == last_frame )\
? clp.ApplyRange(first_frame, last_frame, "Layer", overlay)\
: clp.Animate(first_frame-1, last_frame+1, "LayerFade", \
overlay, first_frame-1, first_frame, last_frame, fade, fade2,\
overlay, last_frame+1, first_frame, last_frame, fade, fade2)
}
function FreeSub2(clip c, string "text", int "x", int "y", int "align", int "first_frame", int "last_frame", \
string "font", int "halo_width", int "halo_height", \
int "text_color", int "halo_color", int "lsp", int "fade", int "fade2")
{
base = BlankClip(c, 1, pixel_type="RGB32", color=$888888).ResetMask()
subs = base.FreeSub(text, x=x, y=y, align=align, font=font, \
halo_width=halo_width, halo_height=halo_height, text_color=text_color, halo_color=halo_color, lsp=lsp).ColorKeyMask($888888)
(fade == first_frame && fade2 == last_frame )\
? c.ApplyRange(first_frame, last_frame, "Layer", subs) \
: c.Animate(first_frame-1, last_frame+1, "LayerFade", \
subs, first_frame-1, first_frame, last_frame, fade, fade2, \
subs, last_frame+1, first_frame, last_frame, fade, fade2)
}
# Used with Animate, layers a clip and linearly fades from black. Specify 1 frame before desired start and 1 frame after
# desired end for both animation length and the interpolated value to get a fade that starts at 0.0/1.0 and ends at 1.0/0.0.
function LayerFade(clip c, clip overlayClip, float curFrame, int first_frame, int last_frame, int fadeEnd, int fadeBegin)
{
curFrame = Int(curFrame)
y = curFrame <= fadeEnd \
? Max(0, curFrame - first_frame) * (1.0 / (fadeEnd - first_frame)) \
: curFrame >= fadeBegin \
? Max(0,last_frame - curFrame) * (1.0 / (last_frame - fadeBegin)) \
: 1.0
f = BlankClip(overlayClip)
g = Overlay(overlayClip, f, opacity=1.0-y)
return ((curFrame == first_frame-1) || (curFrame == Last_frame+1)) ? c : c.Layer(g)
}