fvisagie
4th December 2012, 16:32
Hi All,
This function simplifies the task of creating a long sequence of splices or blends between filtered and original clips by allowing the user to enter splice frame numbers and optional duration of blend (overlap) into a single text list. It's mainly intended to be used with prefiltered or prerendered clips, and/or when splice blending is needed to mask filtering transitions.
Thanks to Gavino for pointing me towards the fix.
Feel free to use it as you see fit. Any comments or suggestions welcome.
Edit: updated for version 1.1.0
Main change: <overlapn> can now optionally be specified as an absolute frame number - AvsP/mod users can now just hit <F11> at all transition boundaries :). Default behaviour treating <overlapn> as relative offset remains unchanged.
#-------------------------------------------
# SpliceFiltered 1.1.0
# Simplifies creating long sequence of splices or blends between filtered and original clips by allowing
# the user to enter splice frame numbers and optional amount of blend (overlap) into a single text list
#
# Useful when
#
# [...]ApplyRange[...]() is not convenient or suitable, or
# filtered clip was prerendered or prepared externally (filtering before splicing), or
# filtering must be blended in/out gradually to mask transitions
#
# SpliceFiltered(clip input, clip filtered, string splicelist, bool "absoverlap")
#
# <input> unfiltered input clip
# <filtered> filtered clip
# <splicelist> specifies where and how filtered version must be applied
# <absoverlap> specifies whether overlap value is relative offset or absolute frame number, default false
#
# <splicelist> is of the form [<splice1>[,<splice2>]] ... [,<splicen>]]] ... [,<splicer>]]]]
# Each <splicen> is of the form [<framen>[:[<overlapn>]]]
# Function output starts with clip <input>, from each <splicen><framen> output alternates to the other clip
# When <overlapn> > 0 : current output clip frames are progressively blended with frames from other clip
# When <absoverlap> = false: from <framen>, blending lasts for <overlapn> frames (i.e. frame <framen>+<overlapn> is unblended)
# When <absoverlap> = true : from <framen>, blending ends on frame <overlapn> (i.e. frame <overlapn>+1 is unblended)
# <splicen+1><framen+1> not advancing past overlap of <splicen> will generate an error
# Empty <framen> or <overlapn> is treated as 0
# When ':' is ommitted whole <splicen> is interpreted as <framen>
#
# Usage
#
# a = BlankClip(length=60, color=$000000).ShowFrameNumber(size=100)
# b = BlankClip(length=60, color=$FFFFFF).ShowFrameNumber(size=100)
# # Blend from frame 0, cut on next allowable frame, various cuts/blends, blend to penultimate frame, replace last frame
# # With default <absoverlap> = false syntax
# splicelist1 = "0:5, 5:10, 20:0, 30:, 40, 50:1 , 56:3 , 59:"
# # With <absoverlap> = true syntax
# splicelist2 = "0:4, 5:14, 20:0, 30:, 40, 50:50, 56:58, 59"
# StackHorizontal(SpliceFiltered(a, b, splicelist1).Subtitle(splicelist1), \
# SpliceFiltered(a, b, splicelist2, absoverlap=true).Subtitle(splicelist2))
#
# Requirements
#
# input and filtered clips must have same clip properties, although equal length is not enforced
# http://avisynth.org/stickboy/jdl-util.avsi
#
# Version history
#
# 1.1.0 Francois Visagie
# * <overlapn> can now optionally be specified as an absolute frame number -
# AvsP/mod users can now just hit <F11> at all transition boundaries :).
# Default behaviour treating <overlapn> as relative offset remains unchanged.
# * When passed an empty splicelist '""' function now returns <input>, as probably expected.
# Previously spliced to <filtered> on frame 0.
#
# 1.0.2 Francois Visagie
# corrected documentation and description
#
# 1.0.1 Francois Visagie
# corrected check for <frame> advancing at least to end of previous <frame>+<overlap>
# corrected <overlap> bounds calculation too strict by 1 frame
# improved description
#
# 1.0.0 Francois Visagie
#
function SpliceFiltered(clip input, clip filtered, string splicelist, bool "absoverlap") {
absoverlap = Default(absoverlap, false)
return((splicelist == "") ? input : SpliceFiltered_int(input, filtered, splicelist, 0, 0, absoverlap))
}
# Internal function - do not call this directly
# Keeps track of splice frame pointer so original splicelist can stay intact for error reporting purposes
# Keeps track of any overlap in progress from previous iteration for next splice bounds checking
function SpliceFiltered_int(clip input, clip filtered, string splicelist, int frames, int prvoverlap, bool absoverlap) {
enumpos = FindStr(splicelist, ",")
enumpos = (enumpos == 0) ? StrLen(splicelist)+1 : enumpos # May go beyond string length
splice = LeftStr(splicelist, enumpos-1)
separatpos = FindStr(splice, ":")
separatpos = (separatpos == 0) ? StrLen(splice)+1 : separatpos # May go beyond string length
frame = Int(Value(LeftStr(splice, separatpos-1)))
Assert(((frame>=0) && (frame>=frames+prvoverlap)), "SpliceFiltered: splice '"+splice+"' frame invalid")
overlap = Int(Value(MidStr(splice, separatpos+1)))
Assert((overlap>=0), "SpliceFiltered: splice '"+splice+"' overlap invalid")
overlap = ((absoverlap == true) && (overlap > 0)) ? overlap-frame+1: overlap
frame = frame-frames # Adjust past processed frames to unprocessed clip length
Assert(((frame<input.Framecount()) && (frame<filtered.Framecount())), "SpliceFiltered: splice '"+splice+"' frame out of bounds")
Assert((((frame+overlap)<=input.Framecount()) && ((frame+overlap)<=filtered.Framecount())), \
"SpliceFiltered: splice '"+splice+"' overlap out of bounds")
headseg = input.Trim2(0, end=frame+overlap)
tailseg = (enumpos>=StrLen(splicelist)+1) ? \
filtered.Trim2(frame) : \
SpliceFiltered_int(filtered.Trim2(frame), input.Trim2(frame), MidStr(splicelist, enumpos+1), frames+frame, overlap, absoverlap)
return((overlap==0) ? headseg+tailseg : headseg.Dissolve(tailseg, overlap))
}
# Test code
a = BlankClip(length=60, color=$000000).ShowFrameNumber(size=100)
b = BlankClip(length=60, color=$FFFFFF).ShowFrameNumber(size=100)
# Blend from frame 0, cut on next allowable frame, various cuts/blends, blend to penultimate frame, replace last frame
# With default <absoverlap> = false syntax
splicelist1 = "0:5, 5:10, 20:0, 30:, 40, 50:1 , 56:3 , 59:"
# With <absoverlap> = true syntax
splicelist2 = "0:4, 5:14, 20:0, 30:, 40, 50:50, 56:58, 59"
StackHorizontal(SpliceFiltered(a, b, splicelist1).Subtitle(splicelist1), \
SpliceFiltered(a, b, splicelist2, absoverlap=true).Subtitle(splicelist2))
Kind regards,
Francois
This function simplifies the task of creating a long sequence of splices or blends between filtered and original clips by allowing the user to enter splice frame numbers and optional duration of blend (overlap) into a single text list. It's mainly intended to be used with prefiltered or prerendered clips, and/or when splice blending is needed to mask filtering transitions.
Thanks to Gavino for pointing me towards the fix.
Feel free to use it as you see fit. Any comments or suggestions welcome.
Edit: updated for version 1.1.0
Main change: <overlapn> can now optionally be specified as an absolute frame number - AvsP/mod users can now just hit <F11> at all transition boundaries :). Default behaviour treating <overlapn> as relative offset remains unchanged.
#-------------------------------------------
# SpliceFiltered 1.1.0
# Simplifies creating long sequence of splices or blends between filtered and original clips by allowing
# the user to enter splice frame numbers and optional amount of blend (overlap) into a single text list
#
# Useful when
#
# [...]ApplyRange[...]() is not convenient or suitable, or
# filtered clip was prerendered or prepared externally (filtering before splicing), or
# filtering must be blended in/out gradually to mask transitions
#
# SpliceFiltered(clip input, clip filtered, string splicelist, bool "absoverlap")
#
# <input> unfiltered input clip
# <filtered> filtered clip
# <splicelist> specifies where and how filtered version must be applied
# <absoverlap> specifies whether overlap value is relative offset or absolute frame number, default false
#
# <splicelist> is of the form [<splice1>[,<splice2>]] ... [,<splicen>]]] ... [,<splicer>]]]]
# Each <splicen> is of the form [<framen>[:[<overlapn>]]]
# Function output starts with clip <input>, from each <splicen><framen> output alternates to the other clip
# When <overlapn> > 0 : current output clip frames are progressively blended with frames from other clip
# When <absoverlap> = false: from <framen>, blending lasts for <overlapn> frames (i.e. frame <framen>+<overlapn> is unblended)
# When <absoverlap> = true : from <framen>, blending ends on frame <overlapn> (i.e. frame <overlapn>+1 is unblended)
# <splicen+1><framen+1> not advancing past overlap of <splicen> will generate an error
# Empty <framen> or <overlapn> is treated as 0
# When ':' is ommitted whole <splicen> is interpreted as <framen>
#
# Usage
#
# a = BlankClip(length=60, color=$000000).ShowFrameNumber(size=100)
# b = BlankClip(length=60, color=$FFFFFF).ShowFrameNumber(size=100)
# # Blend from frame 0, cut on next allowable frame, various cuts/blends, blend to penultimate frame, replace last frame
# # With default <absoverlap> = false syntax
# splicelist1 = "0:5, 5:10, 20:0, 30:, 40, 50:1 , 56:3 , 59:"
# # With <absoverlap> = true syntax
# splicelist2 = "0:4, 5:14, 20:0, 30:, 40, 50:50, 56:58, 59"
# StackHorizontal(SpliceFiltered(a, b, splicelist1).Subtitle(splicelist1), \
# SpliceFiltered(a, b, splicelist2, absoverlap=true).Subtitle(splicelist2))
#
# Requirements
#
# input and filtered clips must have same clip properties, although equal length is not enforced
# http://avisynth.org/stickboy/jdl-util.avsi
#
# Version history
#
# 1.1.0 Francois Visagie
# * <overlapn> can now optionally be specified as an absolute frame number -
# AvsP/mod users can now just hit <F11> at all transition boundaries :).
# Default behaviour treating <overlapn> as relative offset remains unchanged.
# * When passed an empty splicelist '""' function now returns <input>, as probably expected.
# Previously spliced to <filtered> on frame 0.
#
# 1.0.2 Francois Visagie
# corrected documentation and description
#
# 1.0.1 Francois Visagie
# corrected check for <frame> advancing at least to end of previous <frame>+<overlap>
# corrected <overlap> bounds calculation too strict by 1 frame
# improved description
#
# 1.0.0 Francois Visagie
#
function SpliceFiltered(clip input, clip filtered, string splicelist, bool "absoverlap") {
absoverlap = Default(absoverlap, false)
return((splicelist == "") ? input : SpliceFiltered_int(input, filtered, splicelist, 0, 0, absoverlap))
}
# Internal function - do not call this directly
# Keeps track of splice frame pointer so original splicelist can stay intact for error reporting purposes
# Keeps track of any overlap in progress from previous iteration for next splice bounds checking
function SpliceFiltered_int(clip input, clip filtered, string splicelist, int frames, int prvoverlap, bool absoverlap) {
enumpos = FindStr(splicelist, ",")
enumpos = (enumpos == 0) ? StrLen(splicelist)+1 : enumpos # May go beyond string length
splice = LeftStr(splicelist, enumpos-1)
separatpos = FindStr(splice, ":")
separatpos = (separatpos == 0) ? StrLen(splice)+1 : separatpos # May go beyond string length
frame = Int(Value(LeftStr(splice, separatpos-1)))
Assert(((frame>=0) && (frame>=frames+prvoverlap)), "SpliceFiltered: splice '"+splice+"' frame invalid")
overlap = Int(Value(MidStr(splice, separatpos+1)))
Assert((overlap>=0), "SpliceFiltered: splice '"+splice+"' overlap invalid")
overlap = ((absoverlap == true) && (overlap > 0)) ? overlap-frame+1: overlap
frame = frame-frames # Adjust past processed frames to unprocessed clip length
Assert(((frame<input.Framecount()) && (frame<filtered.Framecount())), "SpliceFiltered: splice '"+splice+"' frame out of bounds")
Assert((((frame+overlap)<=input.Framecount()) && ((frame+overlap)<=filtered.Framecount())), \
"SpliceFiltered: splice '"+splice+"' overlap out of bounds")
headseg = input.Trim2(0, end=frame+overlap)
tailseg = (enumpos>=StrLen(splicelist)+1) ? \
filtered.Trim2(frame) : \
SpliceFiltered_int(filtered.Trim2(frame), input.Trim2(frame), MidStr(splicelist, enumpos+1), frames+frame, overlap, absoverlap)
return((overlap==0) ? headseg+tailseg : headseg.Dissolve(tailseg, overlap))
}
# Test code
a = BlankClip(length=60, color=$000000).ShowFrameNumber(size=100)
b = BlankClip(length=60, color=$FFFFFF).ShowFrameNumber(size=100)
# Blend from frame 0, cut on next allowable frame, various cuts/blends, blend to penultimate frame, replace last frame
# With default <absoverlap> = false syntax
splicelist1 = "0:5, 5:10, 20:0, 30:, 40, 50:1 , 56:3 , 59:"
# With <absoverlap> = true syntax
splicelist2 = "0:4, 5:14, 20:0, 30:, 40, 50:50, 56:58, 59"
StackHorizontal(SpliceFiltered(a, b, splicelist1).Subtitle(splicelist1), \
SpliceFiltered(a, b, splicelist2, absoverlap=true).Subtitle(splicelist2))
Kind regards,
Francois