View Full Version : scene change detection plugins
Hat3L0v3
31st January 2023, 06:58
Is it possible to use scene change detection plugins for searching scene changes and applying filter to them?
For example I want to use depanstabilize for every 5 frames before and 2 frames after the scene changes automatically (to stabilize image shifting before scene change on old anime source)
Their description is too complicated for me, I need some examples if it possible.
appreciated for help
StainlessS
31st January 2023, 11:46
depanstabilize for every 5 frames before and 2 frames after the scene changes
What if scene/cut is ony eg 1 or 2 frames in length ? (perhaps several in succession).
What bit depth you got ?
EDIT: I'm making detector using ScSelect_HBD(), and will make DBase so you can perhaps hack to your needs.
https://forum.doom9.org/showthread.php?t=182392&highlight=SCSelect_HBD
StainlessS
31st January 2023, 11:52
So Far,
Global.Avs
# Global.avs
VideoFileName = "D:\LF.dgi"
SFrames = ".\SFrames.txt".RT_GetFullPathName()
DB = ".\MyDB.DB".RT_GetFullPathName()
#LoadPlugin(".\RT_stats_x64.dll")
######################
DB_TypeString = "ii"
# Example TypeString:- "ifffs1024bn", 1st field Int, 3 Float fields, 1 string field of length=1024, 1 Bool field, 1 BIN field(8 bit int). 7 Fields in all (0->6).
DGSource(VideoFileName)
# My Trim to shorten sample file
Trim(10000,-10000) # 10,000 frame
CROP_X=0 CROP_Y=132 CROP_W=-0 CROP_H=-132 # My Crop Coords, get rid of border
crop(CROP_X,CROP_Y,CROP_W,CROP_H)
SOURCE_CLIP = Last # NOT Converted to 8 bit
bpc = Last.BitsPerComponent
(bpc != 8) ? ConvertBits(8) : NOP
BilinearResize(480,360) # Maybe improve detect with MvTools, maybe another reiszer or size.
Return Last
1_Make_SFrames.avs
# 1_Make_SFrames.avs
Import(".\ScSelect_HBD.avsi")
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
##########################
DFACTOR = 3.5
MINDIF = 1.0
SHOW = True
# Function SCSelect_HBD(clip dClip,clip Start,clip End,clip Motion, float "dfactor",Float "MinDif",bool "show",String "S_Frames",String "E_Frames")
SZ = Max(Round(Height*0.10),24)
Start=Subtitle("START OF SCENE",align=5,size=SZ,Y=Height/2-SZ,Text_Color=$FF4040)
End=Subtitle("END OF SCENE", align=5,size=SZ,Y=Height/2+SZ,Text_Color=$4040FF)
Motion=Subtitle("GLOBAL MOTION",align=5,size=SZ)
RT_FileDelete(SFrames)
SCSelect_HBD(Last,Start,End,Motion,dFactor=DFACTOR,MinDif=MINDIF,show=SHOW,S_Frames=SFrames) # When Happy, Use VDub "Run Video Analysis pass".
return last
Above Make_SFrames.avs will write two frame 0s, due to way VDub 2 works (once for startup, and again when scan).#
2_Make_DBase.avs
# 2_Make_DBase.avs
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
##########################
S = RT_ReadTxtFromFile(SFrames)
LINES = RT_TxtQueryLines(S)
RT_DBaseAlloc(DB,0,DB_TypeString) # Create DBase file, with zero pre-existing records, number and type of fields as described by DB_TypeString.
# Here, We dont know how many records there will be.
Start = 0
Record = 0
For(i=0,LINES-1) {
n = S.RT_TxtGetLine(LINE=i).RT_NumberValue()
if(n > 0) { # Skip both zeros in SFrames
End = n - 1 # End frame is frame before a Start frame.
# Record is the SceneNo (Zero Relative)
RT_DBaseExtend(DB) # Add an empty record, Record = Zero Rel record index # All fields are zeroed (Strings = "", Bool=false).
RT_DBaseSetField(DB,Record,0, Start) # Field 0 = Start of Scene
RT_DBaseSetField(DB,Record,1, End) # Field 1 = End of Scene
# Set any further records [EDIT: Fields] as desired and as described via DB_TypeString.
Start = n # For Next time around
Record = Record + 1 # Number of records in DBase so far (and next time around zero relative record number).
}
}
# REPEAT SETTING OF ALL fields for last record
End = FrameCount - 1
RT_DBaseExtend(DB) # Add final empty record
RT_DBaseSetField(DB,Record,0, Start) # Field 0 = Start of Scene
RT_DBaseSetField(DB,Record,1, End) # Field 1 = End of Scene
# Set any further records [EDIT: Fields] as desired and as described via DB_TypeString.
Record = Record + 1 # Number of records in DBase
return MessageClip(RT_String("Wrote %d Records (trims)",Record))
3_Show_Cuts.avs
# 3_Show_Cuts.avs
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
Records = RT_DbaseRecords(DB)
Src = SOURCE_CLIP
C = Src.BlankClip(length=0,Height=Src.Height*2) # zero len clip (double height)
SZ = Max(Round(Height*0.10),24)
for(rec=0,Records-1) {
Start = RT_DbaseGetField(DB,rec, 0) # Field 0 is Start
End = RT_DbaseGetField(DB,rec, 1) # Field 1 is End
StartC = Src.Trim(Start,-1) # Start frame of SceneCut(rec)
EndC = Src.Trim(End,-1) # End frame of SceneCut(rec)
StartC = StartC.Subtitle(RT_String("S=%d",Start),Size=SZ) # Show Start frame number
endC = EndC.Subtitle(RT_String("E=%d",End),Size=SZ) # Show end frame number
CutC = StackVertical(StartC,EndC)
C = C + CutC # Add to clip so far
}
return C
Hat3L0v3
31st January 2023, 13:18
What if scene/cut is ony eg 1 or 2 frames in length ? (perhaps several in succession).
What bit depth you got ?
EDIT: I'm making detector using ScSelect_HBD(), and will make DBase so you can perhaps hack to your needs.
https://forum.doom9.org/showthread.php?t=182392&highlight=SCSelect_HBD
I guess bit depth not important in my case ( I cant stabilize video from start (when its 8bit) or in the end after I pass all filters through (when it converted to 10bit for 10bit encode)
About 1-2 frames scenes - its a problem, as I see running ScSelect_HBD_Simple_Client.avs (throught my source).
There are solid scenes with movement and it detects scene end/start jumping in a middle of the scene (sometimes with motion inside). I guess the only controllers for detection are DFACTOR_1 and MINDIF_1 ? I expirementally increased them to 20 and 15 and seems flickers gone (but some scene changes not detected) maybe you know good settings?
Now the problem - I need atleast few frames (around 3-5) of end of scene (not 1). How to do it?
btw I have only SOS > pTh , EOS > nTh stats. how to turn dFact and MinD info?
StainlessS
31st January 2023, 13:45
Arh, Anime, I did not see that and would probably have ignored this thread had I noticed it.
Best suggestion for anime is significant increase of MinDif, maybe a bit of an increase of DFactor.
maybe you know good settings?
HeHe, not really.
I'll see if I can mod using MvTools SC detection, but am not really expecting too much from that either.
I have only SOS > pTh , EOS > nTh stats. how to turn dFact and MinD info?
A good question, cant help much Im afraid, was best I could do to explain it in the comments.
I guess if cannot get something exaclty right, then can hand edit SFRames file, and use the edited file to create DBase.
Hopefully you can find settings that mostly work. (wild guess, about DFactor=8.0, MinDif=12.0, but anime is a bitch)
I'll try do alternative MvTools thing, maybe works better, maybe not.
I have only SOS > pTh , EOS > nTh stats. how to turn dFact and MinD info?
If it does not show the "DFact, nor MinD" stuff, then NO VARIATION of DFactor will work with current MinDif,
and also, NO VARIATION of MinDif will work with current DFactor. [which I think means that both are way too high, defaults are 3.5 and 1.0]
Metrics when Show=True (metrics provided as if in 8 bit range):
>>>>>>>>>>>>>>>>>
20531 ] S {SOS: dFact= 19.7365:MinD=54.6495}
SOS: P{ 66.214} > pTh{ 12.565}<==
EOS: N{ 3.304} > nTh{232.750}
<<<<<<<<<<<<<<<<<
20531, Is current Frame Number
S, Is flagging a detected Start-Of-Scene (Also 'E'=End-Of-Scene, and 'G' = Global motion.
SOS: P{ 66.214} > pTh{ 12.565} <== The arrow "<==" at the end denotes a SOS (Start Of Scene) detection.
'P' (short for pDf, screen space saving) is difference to previous frame.
pTh = dFactor * nDf + MinDif
EOS: N{ 3.304} > nTh{232.750} Much as Above, but no EOS (End Of Scene) detection.
'N' (short for nDf), is difference to next frame.
nTh = dFactor * pDf + MinDif
{SOS: dFact= 19.7365:MinD=54.6495}, NOT ALWAYS SHOWN.
The Scene change Arg, matching estimate info, in this case for SOS estimate.
Shown only if pDf, nDF, and arg limits on dFactor and MinDif could
produce either SOS or EOS. This indicator only makes any sense on frames
that YOU have decided should be a scene change frame, otherwise ignore.
dFact is the dFactor that will produce an EXACT match of the threshold
(SOS pTh or EOS nTh) to the higher difference {SOS pDf or EOS nDf), when
MinDif unchanged.
As this example shows SOS, so the threshold is pTh and higher difference is pDf,
so it balances this line,
P{ 66.214} == pTh{66.214}, or
P{ 66.214} == {dfact * nDf + MinDif)
P{ 66.214} == {19.7365 * nDf + MinDif)
So in this particular instance it shows that the maximum value for dFactor arg
that could produce SOS on this frame with current Mindif is LESS THAN 19.7365.
It shows that lowest value of dFactor that would fail to produce a SOS, so the maxium
value of dFactor that would succeed to detect SOS for current frame is just below this
value. (pDf has to be greater than pTh so when equal will fail SOS detect).
Similar can be deduced when EOS estimator is shown.
MinD is similar estimator (in this case again for SOS) which shows where MinDif
will balance (with current dFactor unchanged)
P{ 66.214} == pTh{66.214}, or
P{ 66.214} == {dfactor * nDf + MinD)
P{ 66.214} == {dfactor * nDf + 54.641195)
Similar can be deduced when EOS estimator is shown.
Hope some of that made at least a little sense, is intended to give you some
idea about how much you can raise (or lower) dFactor or Mindif to get
a successful detection on current frame.
Hat3L0v3
31st January 2023, 14:01
I guess if cannot get something exaclty right, then can hand edit SFRames file, and use the edited file to create DBase.
Hopefully you can find settings that mostly work. (wild guess, about DFactor=8.0, MinDif=12.0, but anime is a bitch)
didn't really get how to create SFrames.txt file
SFrames = ".\SFrames.txt".RT_GetFullPathName() -it's not import its export?
StainlessS
31st January 2023, 14:22
Get the Beta (#13 I think) RT_stats at MediaFire in my sig below this post.
I'm wondering if these new AI bot whotsits can give a list of start of scene cuts, anybody tried that ?
Anime and JohnMeyer handheld clips, where camera pans from one end of football field to the other (in a couple of frames),
just dont detect well [every frame seems a scene change] using average pixel difference, or MvTools, or anything else that we have.
StainlessS
31st January 2023, 14:40
1B_Make_SFramesB.avs
# 1B_Make_SFramesB.avs
Import(".\ScSelect_HBD.avsi")
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
##########################
RT_FileDelete(SFrames)
thSCD1 = 400
thSCD2 = 130
SHOW = True
SOS = StartOfSceneClip(thSCD1,thSCD2)
SZ = Max(Last.Height*.1,24)
GLOBAL SOSCNT = 0
SSS="""
Y = SOS.RT_Averageluma(w=1,h=1)
if(Y >= 255) {
RT_WriteFile(SFrames,"%d",current_Frame)
GLOBAL SOSCNT = SOSCNT + 1
}
(SHOW) ? Subtitle(RT_String("SOS=%s : SOSCNT=%d",(Y>=255),SOSCNT),size=SZ,text_color=(Y>=255)?$FF0000:$FFFF00,align=5) : NOP
Return Last
"""
ScriptClip(SSS)
return last
Function StartOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") { # All Luma Samples set 255 at SOS, else 0
thSCD1=Default(thSCD1,400) thSCD2=Default(thSCD2,130)
sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
fv=sup.MAnalyse(isb=false,delta=1,blksize=16)
Return c.MSCDetection(fv,thSCD1=thSCD1,thSCD2=thSCD2)
}
Alternative using MvTools.
EDIT: Switch SHOW OFF when using VDub analysis pass.
UPDATED, Shows SOS Count, must scan forwards only [Else SOSCNT wrong].
Hat3L0v3
31st January 2023, 14:45
I download RT_Stats_25&26_x86_x64_dll_v2.00Beta13_20201229 from your archive, have no idea what to do next . I need somehow run 2_Make_DBase.avs ? with all RT_ commands
I guess I need just load x64.dll ?
StainlessS
31st January 2023, 15:00
As well as converting to 8 bit in the Globals.avs, maybe reduce size to maybe 480x360 or about that,
MvTools only scans so many pixels, and if big jumps in HD then will detect big jumps better on lower rez clip [I think, maybe, perhaps].
EDIT: Just put it [extracted x64 dll] in your plugins or use LoadPlugin(), same as any other dll
EDIT: Avisynth26_x64/RT_Stats_x64.dll, extract and rename to just "RT_Stats.dll" (or leave it as "RT_Stats_x64.dll", your choice).
EDIT: I've added line to Globals.avs,
#LoadPlugin(".\RT_stats_x64.dll")
Hat3L0v3
31st January 2023, 15:03
seems it start writing SFrames to txt file finally. I need to play whole clip length to write all of them?
I've test 1B_Make_SFramesB for a little , seems it's work better as detection (for anime I guess)
StainlessS
31st January 2023, 15:10
VDub2 use "Menu/File/Run Video Analysis pass".
Faster.
EDIT: Added line to Globals.avs,
BilinearResize(480,360) # Maybe improve detect with MvTools, maybe another reiszer or size.
Hat3L0v3
31st January 2023, 15:20
VDub2 use "Menu/File/Run Video Analysis pass".
Faster.
Don't really want install VDub. To skip viewing whole length I need to use Video Analysis pass ?
btw what doing SZ = Max(Round(Height*0.10),24) it's important?
StainlessS
31st January 2023, 15:39
Did you use the globals downsize ?
I need to use Video Analysis pass ?
I'm guessin that you are gonna be needing full scan many times, so is a good idea to install.
(Or, use AvsPMod scan full clip, I think it has that capability)
SZ just adjusts size of subtitles, you dont need worry about it.
Hat3L0v3
31st January 2023, 15:56
Did you use the globals downsize ?
I'm guessin that you are gonna be needing full scan many times, so is a good idea to install.
(Or, use AvsPMod scan full clip, I think it has that capability)
SZ just adjusts size of subtitles, you dont need worry about it.
Well MvTools variation work almost perfect, dont even need to tweak settings. (there is small amount scenes with objects movement that cause SOS detection, but technically it's impossible not to detect them. // so maybe to use something like - if between SOS frames are 1-2 frames -> not to count them when creating DataBase? (or not to count previous SOS) they are actually around 5 frames somewhere )
About 2_Make_DBase.avs. It's creating intervals? like for trim (start and end?) so I can use it to put my filters on?
I'm not a programmer so for me it's quite hard to tell where I need to tweak settings. (for example I need to make 5frames before SOS and add/not add SOS to this interval (maybe SOS +1-2 frames) / Where to look?
I'm using avspmod , it have scan function?
Didn't used downsize yet
StainlessS
31st January 2023, 16:10
I cocked up, the 1B thingy only writes a single number to SFrames file (I forgot to add Append=True).
I'm updating all scripts.
I'm adding Ranges.txt file, where ranges will be written "101 152", style [start end].
I'll add minimum length detector, but we will really not have any idea if first of last frame was wrong [will skip last].
I presumed that you had a bit of Avs experience, now is the perfect time for you to learn :) [you're gonna need it]
I'm using avspmod , it have scan function?
I presume so (I use VDub2)
Hat3L0v3
31st January 2023, 16:21
I cocked up, the 1B thingy only writes a single number to SFrames file (I forgot to add Append=True).
I'm updating all scripts.
I'm adding Ranges.txt file, where ranges will be written "101 152", style [start end].
I'll add minimum length detector, but we will really not have any idea if first of last frame was wrong [will skip last].
I presumed that you had a bit of Avs experience, now is the perfect time for you to learn :) [you're gonna need it]
I presume so (I use VDub2)
just wanted to tell about incorrect frames write :)
btw I finded analysis on avps (it's on video > tools > run analysis pass) thx for advise :rolleyes:
I guess I'll just check frames that are close to each other and manually delete them if they doesn't needed (from SFrames.txt)
StainlessS
31st January 2023, 17:31
Redone.
Global.avs
# Global.avs
VideoFileName = "D:\LF.dgi"
SFrames = ".\SFrames.txt".RT_GetFullPathName()
Ranges = ".\Ranges.txt".RT_GetFullPathName() # Ranges file written during making DBase.
DB = ".\MyDB.DB".RT_GetFullPathName()
#LoadPlugin(".\RT_stats_x64.dll")
######################
DB_TypeString = "ii"
# Example TypeString:- "ifffs1024bn", 1st field Int, 3 Float fields, 1 string field of length=1024, 1 Bool field, 1 BIN field(8 bit int). 7 Fields in all (0->6).
DGSource(VideoFileName)
# My Trim to shorten sample file
Trim(10000,-10000) # 10,000 frame
CROP_X=0 CROP_Y=132 CROP_W=-0 CROP_H=-132 # My Crop Coords, get rid of border
crop(CROP_X,CROP_Y,CROP_W,CROP_H)
SOURCE_CLIP = Last # NOT Converted to 8 bit
bpc = Last.BitsPerComponent
(bpc != 8) ? ConvertBits(8) : NOP
Spline36Resize(480,360) # Maybe improve detect with MvTools, maybe another reiszer or size. Can just comment out.
Return Last
1_Make_SFrames.avs
# 1_Make_SFrames.avs
Import(".\ScSelect_HBD.avsi")
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
##########################
DFACTOR = 8.0 # Way high
MINDIF = 12.0 # Way high
SHOW = True # Turn off during full fast scan (SHOW=False)
# Function SCSelect_HBD(clip dClip,clip Start,clip End,clip Motion, float "dfactor",Float "MinDif",bool "show",String "S_Frames",String "E_Frames")
SZ = Max(Round(Height*0.10),24)
Start=Subtitle("START OF SCENE",align=5,size=SZ,Y=Height/2-SZ,Text_Color=$FF4040)
End=Subtitle("END OF SCENE", align=5,size=SZ,Y=Height/2+SZ,Text_Color=$4040FF)
Motion=Subtitle("GLOBAL MOTION",align=5,size=SZ)
RT_FileDelete(SFrames)
RT_FileDelete(Ranges)
SCSelect_HBD(Last,Start,End,Motion,dFactor=DFACTOR,MinDif=MINDIF,show=SHOW,S_Frames=SFrames) # When Happy, Use VDub "Run Video Analysis pass".
return last
1B_Make_SFramesB.avs
# 1B_Make_SFramesB.avs
Import(".\ScSelect_HBD.avsi")
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
##########################
RT_FileDelete(SFrames)
RT_FileDelete(Ranges)
thSCD1 = 400
thSCD2 = 130
SHOW = True
SOS = StartOfSceneClip(thSCD1,thSCD2)
SZ = Max(Last.Height*.1,24)
GLOBAL SOSCNT = 0
SSS="""
Y = SOS.RT_Averageluma(w=1,h=1)
if(Y >= 255) {
RT_WriteFile(SFrames,"%d",current_Frame,Append=True)
GLOBAL SOSCNT = SOSCNT + 1
}
(SHOW) ? Subtitle(RT_String("SOS=%s : SOSCNT=%d",(Y>=255),SOSCNT),size=SZ,text_color=(Y>=255)?$FF0000:$FFFF00,align=5) : NOP
Return Last
"""
ScriptClip(SSS)
return last
Function StartOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") { # All Luma Samples set 255 at SOS, else 0
thSCD1=Default(thSCD1,400) thSCD2=Default(thSCD2,130)
sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
fv=sup.MAnalyse(isb=false,delta=1,blksize=16)
Return c.MSCDetection(fv,thSCD1=thSCD1,thSCD2=thSCD2)
}
2_Make_DBase.avs
# 2_Make_DBase.avs
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
MIN_SCENE_LEN = 1 # Whatever you choose (1 will switch off limiting)
##########################
RT_FileDelete(Ranges)
S = RT_ReadTxtFromFile(SFrames)
LINES = RT_TxtQueryLines(S)
RT_DBaseAlloc(DB,0,DB_TypeString) # Create DBase file, with zero pre-existing records, number and type of fields as described by DB_TypeString.
# Here, We dont know how many records there will be.
Start = 0
Record = 0
For(i=0,LINES-1) {
n = S.RT_TxtGetLine(LINE=i).RT_NumberValue()
if(n > 0) { # Skip both zeros in SFrames
End = n - 1 # End frame is frame before a Start frame.
Length = End - Start + 1
if(Length >= MIN_SCENE_LEN) {
RT_WriteFile(Ranges,"%d %d",Start,End,Append=true)
# Record is the SceneNo (Zero Relative)
RT_DBaseExtend(DB) # Add an empty record, Record = Zero Rel record index # All fields are zeroed (Strings = "", Bool=false).
RT_DBaseSetField(DB,Record,0, Start) # Field 0 = Start of Scene
RT_DBaseSetField(DB,Record,1, End) # Field 1 = End of Scene
# Set any further Fields as desired and as described via DB_TypeString.
Start = n # For Next time around
Record = Record + 1 # Number of records in DBase so far (and next time around zero relative record number).
}
}
}
# REPEAT SETTING OF ALL fields for last record
End = FrameCount - 1
RT_DBaseExtend(DB) # Add final empty record
RT_DBaseSetField(DB,Record,0, Start) # Field 0 = Start of Scene
RT_DBaseSetField(DB,Record,1, End) # Field 1 = End of Scene
# Set any further Fields as desired and as described via DB_TypeString.
Record = Record + 1 # Number of records in DBase
return MessageClip(RT_String("Wrote %d Records (trims)",Record))
3_Show_Cuts.avs
# 3_Show_Cuts.avs
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
Records = RT_DbaseRecords(DB)
Src = SOURCE_CLIP
C = Src.BlankClip(length=0,Width=Src.Width*2) # zero len clip (double height EDIT: double width)
INVALID_FRAME = Src.BlankClip(length=1,Color=$FF00FF) # Frame before 0 or after last frame.
SZ = Max(Round(Height*0.10),24)
# Scene numbers shown 1 relative.
for(rec=0,Records-1) {
if(rec==0) {
EndC = INVALID_FRAME # Frame before Scene 0 is INVALID
} Else {
EndOfPreviousScene = RT_DbaseGetField(DB,rec-1, 1) # Last frameNo of previous scene (Field 1 is End frame)
EndC = Src.Trim(EndOfPreviousScene,-1) # End frame of SceneCut(rec)
EndC = EndC.Subtitle(RT_String("%d] : Scene %d/%d : EOS",EndOfPreviousScene,rec,Records),Size=SZ)
}
Start = RT_DbaseGetField(DB,rec, 0) # Field 0 is Start (current scene)
StartC = Src.Trim(Start,-1) # Start frame of SceneCut(rec)
StartC = StartC.Subtitle(RT_String("%d] : Scene %d/%d : SOS",Start,rec+1,Records),Size=SZ) # Show Start frame number
CutC = StackHorizontal(EndC,StartC)
C = C + CutC # Add to clip so far
}
# A bit more to show final frame of clip and invalid next start frame
EndOfPreviousScene = RT_DbaseGetField(DB,rec-1, 1) # Final frame in entire clip
EndC = Src.Trim(EndOfPreviousScene,-1) # End frame of SceneCut(rec)
EndC = EndC.Subtitle(RT_String("%d] : Scene %d/%d : EOS",EndOfPreviousScene,rec,Records),Size=SZ)
StartC = INVALID_FRAME
CutC = StackHorizontal(EndC,StartC)
C = C + CutC
return C
EDIT: 3_Show_Cuts.avs Now shows Last frame of previous scene, together with start frame of current scene [for scene change comparison].
https://i.postimg.cc/8JKNy7ZX/3-Show-Cuts-00.jpg (https://postimg.cc/8JKNy7ZX)
EDIT: My sample frames either side of scene change are a bit 'manky'.
Hat3L0v3
31st January 2023, 17:48
thanks.
SHOW = True #Switch OFF when using VDub analysis pass - its for increasing speed?
StainlessS
31st January 2023, 17:53
Yes, subtitles take time to render, and every little helps. [SHOW=False]
EDIT:
Now you've gotta find out how to do the deshake whotsit [I dont do deshake, seems way too tedious and I never had satisfactory results, probably cos I'm doin' it wrong].
Get somebody else to assist with the deshake, and afterwards I'll make script to process in parts, and add back together again.
I'll come back tomorrow to see how you are doing.
EDIT: I see Wonkey_Monkey there, I bet he's good at deshaking it all about.
Hat3L0v3
31st January 2023, 17:59
Yes, subtitles take time to render, and every little helps. [SHOW=False]
MIN_SCENE_LEN = 1
its minimum frames to detect as scene?
btw ranges txt is for what?
StainlessS
31st January 2023, 18:03
An edit from previous post:
EDIT: I see Wonkey_Monkey there, I bet he's good at deshaking it all about.
MIN_SCENE_LEN
You said you wanted minimum length scene, that is to set minimum length, but I reccommend you dont use it and leave at 1.
Ranges.txt is for whatever I/you might want it for, dont know, but its there anyways.
I see JohnMeyer there too, you seem to be in luck. [Call him Sir, he likes that].
EDIT:
You need script to deshake a single section, I'll make scripts to process entire clip using that as example.
EDIT: You'll need to post a sample for the guys.
Hat3L0v3
1st February 2023, 02:24
An edit from previous post:
EDIT: I see Wonkey_Monkey there, I bet he's good at deshaking it all about.
You said you wanted minimum length scene, that is to set minimum length, but I reccommend you dont use it and leave at 1.
Ranges.txt is for whatever I/you might want it for, dont know, but its there anyways.
I see JohnMeyer there too, you seem to be in luck. [Call him Sir, he likes that].
EDIT:
You need script to deshake a single section, I'll make scripts to process entire clip using that as example.
EDIT: You'll need to post a somaple for the guys.
Sorry for not replying immediately, my power goes off. after that I went sleep :)
When I was trying to stabilize big parts of video manually - script was looking like this:
T1=Trim(0, 6738)
b2=Trim(6739, 6999)
d2 = DePanEstimate(b2, range=1, trust=1, dxmax=5, dymax=5)
T2 = DePanStabilize(b2, data=d2, mirror=15)
T3=Trim(7000, 10487)
So basically (for example) with my SFrames.txt that starts with
0
108
202
4_part must looks something like this:
#input part
everything that need to be loaded (like DGSource(VideoFileName), txt, other)
#param inputs part
param1=5 #frames before SOS
param2=0 #frames that count SOS and add some more ahead
settings1= #settings for DePanEstimate (In my case it will be range=1, trust=1, dxmax=5, dymax=5)
settings2= #settings for DePanStabilize (In my case only mirror=15 but there are more)
#part that split intervals into 2parts
(script)
In my case with param1+2 = 5+0 it must create intervals like:
part1A=(0,102)
part1B=(103,107)
part2A=(108,196)
...etc...
With param1+2 = 5+2 it must create intervals like:
part1A=(0,102)
part1B=(103,109)
part2A=(110,196)
...etc...
#part for creating data for depanstab and stabilize
(script that do something like this):
1B=last.Trim(part1B)
data1= DePanEstimate(1B, settings1)
stab1= DePanStabilize(1B, data=data1, settings2)
2B=last.Trim(part2B)
data2= DePanEstimate(2B, settings1)
stab2= DePanStabilize(2B, data=data2, settings2)
...etc...
#part that trims and merge everything together
(something like this):
part1=last.Trim(part1A)
part2=stab1
part3=last.Trim(part2A)
part4=stab2
...etc...
Output=part1+part2+part3+...etc...
Output
Ofcource it's from my noob perspective. Some parts must be written in other (proper) way.
I don't know how to do part with data if I want to use other filter that not require data (like Stab3 for example, it must run only stab1= Stab3(1B, settings3) )
For 3_Show_Cuts script , I would like to see info about how much frames are to closest SOS/EOF (I guess closest previous SOS for left prewiev, and closest next EOF for right prewiev) so I can see where are short parts of scenes.
StainlessS
1st February 2023, 12:57
I would like to see info about how much frames are to closest SOS/EOF (I guess closest previous SOS for left prewiev, and closest next EOF for right prewiev) so I can see where are short parts of scenes.
OK, I added two fields to DBase, Field_3=PrevSceneLen, Field_4=NextSceneLen.
Global.avs
# Global.avs
VideoFileName = "D:\LF.dgi"
SFrames = ".\SFrames.txt".RT_GetFullPathName()
Ranges = ".\Ranges.txt".RT_GetFullPathName() # Ranges file written during making DBase.
DB = ".\MyDB.DB".RT_GetFullPathName()
#LoadPlugin(".\RT_stats_x64.dll")
######################
# Example TypeString:- "ifffs1024bn", 1st field Int, 3 Float fields, 1 string field of length=1024, 1 Bool field, 1 BIN field(8 bit int). 7 Fields in all (0->6).
DB_TypeString = "iiiii" # Field_0=StartFrameNo, Field_1=EndFrameNo, Field_2=SceneLength, Field_3=PrevSceneLength, Field_4=NextSceneLength,
DGSource(VideoFileName)
# My Trim to shorten sample file
Trim(10000,-10000) # 10,000 frame
CROP_X=0 CROP_Y=132 CROP_W=-0 CROP_H=-132 # My Crop Coords, get rid of border
crop(CROP_X,CROP_Y,CROP_W,CROP_H)
SOURCE_CLIP = Last # NOT Converted to 8 bit
bpc = Last.BitsPerComponent
(bpc != 8) ? ConvertBits(8) : NOP
Spline36Resize(480,360) # Maybe improve detect with MvTools, maybe another reiszer or size. Can just comment out.
Return Last
1_Make_SFrames.avs [No Change]
# 1_Make_SFrames.avs
Import(".\ScSelect_HBD.avsi")
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
##########################
DFACTOR = 8.0 # Way high
MINDIF = 12.0 # Way high
SHOW = True # Turn off during full fast scan (SHOW=False)
# Function SCSelect_HBD(clip dClip,clip Start,clip End,clip Motion, float "dfactor",Float "MinDif",bool "show",String "S_Frames",String "E_Frames")
SZ = Max(Round(Height*0.10),24)
Start=Subtitle("START OF SCENE",align=5,size=SZ,Y=Height/2-SZ,Text_Color=$FF4040)
End=Subtitle("END OF SCENE", align=5,size=SZ,Y=Height/2+SZ,Text_Color=$4040FF)
Motion=Subtitle("GLOBAL MOTION",align=5,size=SZ)
RT_FileDelete(SFrames)
RT_FileDelete(Ranges)
SCSelect_HBD(Last,Start,End,Motion,dFactor=DFACTOR,MinDif=MINDIF,show=SHOW,S_Frames=SFrames) # When Happy, Use VDub "Run Video Analysis pass".
return last
1B_Make_SFramesB.avs [No Change]
# 1B_Make_SFramesB.avs
Import(".\ScSelect_HBD.avsi")
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
##########################
RT_FileDelete(SFrames)
RT_FileDelete(Ranges)
thSCD1 = 400
thSCD2 = 130
SHOW = True
SOS = StartOfSceneClip(thSCD1,thSCD2)
SZ = Max(Last.Height*.1,24)
GLOBAL SOSCNT = 0
SSS="""
Y = SOS.RT_Averageluma(w=1,h=1)
if(Y >= 255) {
RT_WriteFile(SFrames,"%d",current_Frame,Append=True)
GLOBAL SOSCNT = SOSCNT + 1
}
(SHOW) ? Subtitle(RT_String("SOS=%s : SOSCNT=%d",(Y>=255),SOSCNT),size=SZ,text_color=(Y>=255)?$FF0000:$FFFF00,align=5) : NOP
Return Last
"""
ScriptClip(SSS)
return last
Function StartOfSceneClip(clip c,Int "thSCD1",Int "thSCD2") { # All Luma Samples set 255 at SOS, else 0
thSCD1=Default(thSCD1,400) thSCD2=Default(thSCD2,130)
sup=c.MSuper(pel=1,sharp=0,rfilter=2,hpad=16, vpad=16)
fv=sup.MAnalyse(isb=false,delta=1,blksize=16)
Return c.MSCDetection(fv,thSCD1=thSCD1,thSCD2=thSCD2)
}
2_Make_DBase.avs [Changes]
# 2_Make_DBase.avs
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
MIN_SCENE_LEN = 1 # Whatever you choose (1 will switch off limiting)
##########################
RT_FileDelete(Ranges)
S = RT_ReadTxtFromFile(SFrames)
LINES = RT_TxtQueryLines(S)
RT_DBaseAlloc(DB,0,DB_TypeString) # Create DBase file, with zero pre-existing records, number and type of fields as described by DB_TypeString.
# Here, We dont know how many records there will be.
Start = 0
Record = 0
For(i=0,LINES-1) {
n = S.RT_TxtGetLine(LINE=i).RT_NumberValue()
if(n > 0) { # Skip both zeros in SFrames
End = n - 1 # End frame is frame before a Start frame.
Length = End - Start + 1
if(Length >= MIN_SCENE_LEN) {
RT_WriteFile(Ranges,"%d %d",Start,End,Append=true)
# Record is the SceneNo (Zero Relative)
RT_DBaseExtend(DB) # Add an empty record, Record = Zero Rel record index # All fields are zeroed (Strings = "", Bool=false).
RT_DBaseSetField(DB,Record,0, Start) # Field 0 = Start of Scene
RT_DBaseSetField(DB,Record,1, End) # Field 1 = End of Scene
RT_DBaseSetField(DB,Record,2, Length) # Field 2 = Length of Scene
# Set Prev Scene Length and Next Scene Length Fields
PrevLen = (Record==0) ? 0 : RT_DBaseGetField(DB,Record-1,2) # Get Length of Previous Scene
RT_DBaseSetField(DB,Record,3, PrevLen) # Set current Record Field 3 with length of Previous Scene.
(Record==0) ? NOP : RT_DBaseSetField(DB,Record-1,4, Length) # Set Prev Record Field 4 (next scene len) with length of current Scene.
# Set any further Fields as desired and as described via DB_TypeString.
Start = n # For Next time around
Record = Record + 1 # Number of records in DBase so far (and next time around zero relative record number).
}
}
}
# REPEAT SETTING OF ALL fields for last record
End = FrameCount - 1
RT_WriteFile(Ranges,"%d %d",Start,End,Append=true)
Length = End - Start + 1
RT_DBaseExtend(DB) # Add final empty record
RT_DBaseSetField(DB,Record,0, Start) # Field 0 = Start of Scene
RT_DBaseSetField(DB,Record,1, End) # Field 1 = End of Scene
RT_DBaseSetField(DB,Record,2, Length) # Field 2 = Length of Scene
# Set Prev Scene Length and Next Scene Length Fields
PrevLen = RT_DBaseGetField(DB,Record-1,2) # Get Length of Previous Scene
RT_DBaseSetField(DB,Record,3, PrevLen) # Set current Record Field 3 with length of Previous Scene.
RT_DBaseSetField(DB,Record-1,4, Length) # Set Prev Record Field 4 (next scene len) with length of current Scene.
# Set any further Fields as desired and as described via DB_TypeString.
Record = Record + 1 # Number of records in DBase
return MessageClip(RT_String("Wrote %d Records (trims)",Record))
3_Show_Cuts.avs [Changes, quite a few, not marked]
# 3_Show_Cuts.avs
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
Records = RT_DBaseRecords(DB)
Src = SOURCE_CLIP
C = Src.BlankClip(length=0,Width=Src.Width*2) # zero len clip (double width)
INVALID_FRAME = Src.BlankClip(length=1,Color=$FF00FF) # Frame before 0 or after last frame.
SZ = Max(Round(Height*0.10),24)
# Subtitled Scene numbers are 1 relative.
for(rec=0,Records) { # *** WARNING ***, rec=Records record dont exist, just for showing FINAL EOS of previous scene.
LenOfCurrScene = (rec!=Records) ? RT_DbaseGetField(DB,rec, 2) : 0 # Length of Current scene from Field 2
LenOfPrevScene = (rec!=Records) ? RT_DbaseGetField(DB,rec, 3) : RT_DbaseGetField(DB,rec-1, 2) # Length of Previous scene (Use current len of previous scene if rec=Records)
LenOfNextScene = (rec!=Records) ? RT_DbaseGetField(DB,rec, 4) : 0 # Length of Next scene from Field 4
if(LenOfPrevScene==0) {
EndC = INVALID_FRAME # Frame before Scene 0 is INVALID
} Else {
EndOfPreviousScene = RT_DbaseGetField(DB,rec-1, 1) # Last frameNo of previous scene (Field 1 is End frame)
EndC = Src.Trim(EndOfPreviousScene,-1) # End frame of SceneCut(rec-1)
EndC = EndC.Subtitle(RT_String("%d] Prev EOS : Scene %d/%d Len=%d",EndOfPreviousScene,rec-1+1,Records,LenOfPrevScene),Size=SZ)
}
if(LenOfCurrScene==0) {
StartC = INVALID_FRAME # Final Frame + 1, Invalid
} Else {
StartOfCurrScene = RT_DbaseGetField(DB,rec, 0) # Field 0 is Start (current scene)
StartC = Src.Trim(StartOfCurrScene,-1) # Start frame of SceneCut(rec)
StartC = StartC.Subtitle(RT_String("%d] Curr SOS : Scene %d/%d : Len=%d\\nPrevLen=%d : NextLen=%d",
\ StartOfCurrScene,rec+1,Records,LenOfCurrScene,LenOfPrevScene,LenOfNextScene),Size=SZ,lsp=0)
}
CutC = StackHorizontal(EndC,StartC)
C = C + CutC # Add to clip so far
}
return C
EDIT: Looks like this, showing Curr, Prev and Next lengths.
https://i.postimg.cc/tsm8dG2P/3-Show-Cuts-01.jpg (https://postimg.cc/tsm8dG2P)
EDIT:
# *** WARNING ***, rec=Records record dont exist, just for showing FINAL EOS of previous scene.
Above, in my sample, we have only 50 scenes, but show 51 frames, last frame shows only final frame in clip as EOS of final scene. [SOS of next scene dont exist]
EDIT I'm off t' pub.
Hat3L0v3
1st February 2023, 17:04
OK, I added two fields to DBase, Field_3=PrevSceneLen, Field_4=NextSceneLen.
Thanks for changes. 4_part it's not your specialization?
Hope someone can write it, using DB that you help to create.
StainlessS
1st February 2023, 17:24
In pub.
You need start and end and eg preframes and postframes in your script.
Edit: variables
Hat3L0v3
2nd February 2023, 03:37
In pub.
You need start and end and eg preframes and postframes in your script.
Edit: variables
I don't understand what it means. start and end of parts that I want to filter? something like:
start = SOS -1 -param1
end = SOS -1 +param2
and what eg preframes/postframes means? frames before start/after end?
StainlessS
2nd February 2023, 11:14
frames before start/after end?
Yes, explicit frame numbers are not of use to me, eg
PreFrames = 5
PostFrames = 5
# both of current trim.
oStart = SOS
oEnd = EOS
# Outer start and end of current trim
oStart = oStart - Min(PreFrames,LengthOfPrevTrim) # I'll do the worrying about actual implementation
oEnd = oEnd + Min(PostFrames,LengthOfNextTrim) # I'll do the worrying about actual implementation
By the way, something I should have asked in my 1st post,
Are you sure that you need to process in separate trims, people usually just process the entire clip.
(I had presumed that you know what you are doing)
(Perhaps JohnMeyer or somebody more familiar with Deshaker stuff could comment on Hat3Ov3's reason when they give it)
Hat3L0v3
2nd February 2023, 12:13
By the way, something I should have asked in my 1st post,
Are you sure that you need to process in separate trims, people usually just process the entire clip.
(I had presumed that you know what you are doing)
Well, I can use deshaked on entire clip, but I can't use all parts and scenes because it make worse some of them (like background start shaking to responds character movement).I tried to find parameters that can work in both ways, but: -or deshaker not working enough to stab frames well but not ruining other parts; -or it's stab scenes/frames and ruining other scenes.
So the only way I see - its use deshaker only for places where it needed : 1 - shifting frames before every scene changes (thay are too many for single episode to do it manually); 2 - scenes where deshaker needed (this part I can do manually because not so many of them)
And the only way I know how to do it - it's trim original part and filtered parts.
If you know how to replace this parts without trimming - go ahead. I'm just too noob in all of this stuff.
StainlessS
2nd February 2023, 12:37
OK, I get it now.
If you can decide upon a number (say half a dozen or so) different groups of settings, and create separate clips for each, and then can use ClipClop function, to
apply those settings to appropriate ranges.
ClipClop:- https://forum.doom9.org/showthread.php?t=162266&highlight=ClipCLop
Example usage script using NickNames (instead of clip index numbers):
###
# ColorBars(Pixel_Type="YV12")
Avisource("D:\avs\test.avi")
ORG=Last
V1 = FFT3DFilter(Plane=0,Sigma=1.6) # Light Luma
V2 = FFT3DFilter(Plane=0,Sigma=2.0) # Med Luma
V3 = FFT3DFilter(Plane=0,Sigma=4.0) # High Luma
V4 = FFT3DFilter(Plane=3,Sigma=1.6) # Light Chroma
V5 = FFT3DFilter(Plane=3,Sigma=2.0) # Med Chroma
V6 = FFT3DFilter(Plane=3,Sigma=4.0) # High Chroma
V7 = FFT3DFilter(Plane=4,Sigma=1.6) # Light Luma+Chroma
V8 = FFT3DFilter(Plane=4,Sigma=2.0) # Med Luma+Chroma
V9 = FFT3DFilter(Plane=4,Sigma=4.0) # High Luma+Chroma
V10= FlipHorizontal() # Flip-H
V11= FlipVertical() # Flip-V
V12= Invert() # Invert
NickNames =""" # Psuedonyms for clips (clip index number)
L0 = 1 # Light Luma
L1 = 2 # Med Luma
L2 = 3 # High Luma
C0 = 4 # Light Chroma
C1 = 5 # Med Chroma
C2 = 6 # High Chroma
LC0 = 7 # Light Luma + Chroma
LC1 = 8 # Med Luma + Chroma
LC2 = 9 # High Luma + Chroma
FH = 10 # Flip-H
FV = 11 # Flip-V
INV = 12 # Invert
"""
SCMD=""" # Clip editing commands in string, can also use commands in file
C0 0,99 # Light Chroma frames @ 0 -> 99
L0 100,-200 # Light Luma frames @ 100, 200 frames ie frames 100->299
INV 300,399 # Invert 300->399
L0 400,499 # Light Luma frames 400->499
FH 500,599 # Flip-H 500->599
LC2 600,699 # High Luma + Chroma
C1 800 # Med Chroma, Single frame
1 900,999 # Light Luma, We used the clip number instead of a NickName
FV 1000,1099 # Flip-V
LC1 2000,0 # Med Luma + Chroma, 2000 -> lastframe
"""
SHOW=True
ClipClop(ORG,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,scmd=SCMD,nickname=NickNames,show=SHOW)
Above, V1 -> V12 are processed clips [entire clip deshaked with different settings],
The ranges that are not replaced are same as source clip.
In SCMD or CMD file, clip Index 1, or nickname L0 correspond with V1 clip, etc.
If above can suffice, then all and good, I have not wasted my time on the other scripts, it was an interesting excursion,
and could come in handy for other purposes.
EDIT: You can try above example script on some clip or even colorbars.
Supports source clip, and up to 255 edited clips [V1 ... V12 above], those not replaced remain as Source.
StainlessS
2nd February 2023, 13:10
You can use the Range.txt generated by the other scripts, but need to insert a command clip index number for the replacement clip, or a NickName.
With Show=true, will show nicknames/clip index used in ClipClop.
NOTE, Every range in CMD (range.txt) will NEED an INDEX, can use 0 to remain as the src, I'll mod the Make DBase script to output eg "0 1234 5678",
so that it will by default do nothing for each range, and just mod your script as and when necessary.
You have to supply all Vn style clips for however many index/Nicknames you use.
2_Make_DBase.avs [Modded Range.txt for ClipClop]
# 2_Make_DBase.avs
Import(".\Global.avs") # Set SFrames name and load clip, trim, crop, convertbits and anything else needed in all processing files.
MIN_SCENE_LEN = 1 # Whatever you choose (1 will switch off limiting)
##########################
RT_FileDelete(Ranges)
S = RT_ReadTxtFromFile(SFrames)
LINES = RT_TxtQueryLines(S)
RT_DBaseAlloc(DB,0,DB_TypeString) # Create DBase file, with zero pre-existing records, number and type of fields as described by DB_TypeString.
# Here, We dont know how many records there will be.
Start = 0
Record = 0
For(i=0,LINES-1) {
n = S.RT_TxtGetLine(LINE=i).RT_NumberValue()
if(n > 0) { # Skip both zeros in SFrames
End = n - 1 # End frame is frame before a Start frame.
Length = End - Start + 1
if(Length >= MIN_SCENE_LEN) {
# RT_WriteFile(Ranges,"%d %d",Start,End,Append=true)
RT_WriteFile(Ranges,"0 %d %d",Start,End,Append=true)
# Record is the SceneNo (Zero Relative)
RT_DBaseExtend(DB) # Add an empty record, Record = Zero Rel record index # All fields are zeroed (Strings = "", Bool=false).
RT_DBaseSetField(DB,Record,0, Start) # Field 0 = Start of Scene
RT_DBaseSetField(DB,Record,1, End) # Field 1 = End of Scene
RT_DBaseSetField(DB,Record,2, Length) # Field 2 = Length of Scene
# Set Prev Scene Length and Next Scene Length Fields
PrevLen = (Record==0) ? 0 : RT_DBaseGetField(DB,Record-1,2) # Get Length of Previous Scene
RT_DBaseSetField(DB,Record,3, PrevLen) # Set current Record Field 3 with length of Previous Scene.
(Record==0) ? NOP : RT_DBaseSetField(DB,Record-1,4, Length) # Set Prev Record Field 4 (next scene len) with length of current Scene.
# Set any further Fields as desired and as described via DB_TypeString.
Start = n # For Next time around
Record = Record + 1 # Number of records in DBase so far (and next time around zero relative record number).
}
}
}
# REPEAT SETTING OF ALL fields for last record
End = FrameCount - 1
# RT_WriteFile(Ranges,"%d %d",Start,End,Append=true)
RT_WriteFile(Ranges,"0 %d %d",Start,End,Append=true)
Length = End - Start + 1
RT_DBaseExtend(DB) # Add final empty record
RT_DBaseSetField(DB,Record,0, Start) # Field 0 = Start of Scene
RT_DBaseSetField(DB,Record,1, End) # Field 1 = End of Scene
RT_DBaseSetField(DB,Record,2, Length) # Field 2 = Length of Scene
# Set Prev Scene Length and Next Scene Length Fields
PrevLen = RT_DBaseGetField(DB,Record-1,2) # Get Length of Previous Scene
RT_DBaseSetField(DB,Record,3, PrevLen) # Set current Record Field 3 with length of Previous Scene.
RT_DBaseSetField(DB,Record-1,4, Length) # Set Prev Record Field 4 (next scene len) with length of current Scene.
# Set any further Fields as desired and as described via DB_TypeString.
Record = Record + 1 # Number of records in DBase
return MessageClip(RT_String("Wrote %d Records (trims)",Record))
OOooops, forgot to write the last range, fixed above.
Hat3L0v3
2nd February 2023, 13:19
Above, V1 -> V12 are processed clips [entire clip deshaked with different settings],
The ranges that are not replaced are same as source clip.
In SCMD or CMD file, clip Index 1, or nickname L0 correspond with V1 clip, etc.
If above can suffice, then all and good, I have not wasted my time on the other scripts, it was an interesting excursion,
and could come in handy for other purposes.
EDIT: You can try above example script on some clip or even colorbars.
Supports source clip, and up to 255 edited clips [V1 ... V12 above], those not replaced remain as Source.
Don't really understand how it works, yet.
I don't have proper intervals yet. I need script that can make them (convert SOS and EOF with depends to how many frames param1,2)
upd. I guess to convert that created ranges like this:
0 702 -> 698 702 -> 698 704
703 893 -> 889 893 -> 889 895
894 976 -> 972 976 -> 972 978
977 1190 -> 1186 1190 -> 1186 1192
original -> if param1 = 5 -> if param1 = 5
ranges param2 = 0 param2 = 2
Hat3L0v3
2nd February 2023, 13:59
So what I understand - I need to put stabilizer into V1=depanstab(blablabla) . L0 = name1 (just a name?) . and somehow import ranges.txt into SCMD= (don't know how to do it)
But if depanstab need to run esimate for data (like depanestimate(source, parameters) - where to put it on? just somewhere above script? or I can just run like:
###
Avisource("D:\avs\test.avi")
ORG=Last
data1=depanestimate(last, params1)
stab=depanstabilize(last, data=data1, params2)
V1 = stab # stabilized
NickNames =""" # Psuedonyms for clips (clip index number)
L0 = 1 # Light Luma
SCMD="...path.../ranges.txt" # this part I dont know how to import
"""
SHOW=false #
ClipClop(ORG,V1,scmd=SCMD,nickname=NickNames,show=SHOW)
StainlessS
2nd February 2023, 14:04
OK, I guess I did not think about it too much, I forgot the extra few frames. :(
Can you get rid of most of the deshaken clip using just a few settings and no before and after extra frames, and write result clip to AVI, (process as per clipclop).
Then we concentrate on the fewer awkward ranges.
Is that possible, or are all of them awkward ?
EDIT:
Can create two pass filtering like this [Using either ForceProcessAVI() from TWriteAvi dll, or RT_ForceProcess() from RT_Stats.]
WhateverSource(...)
Clip1 = Trim(0,-2000) # 2000 frames
File1="D:\File1.txt"
Clip2 = Trim(2000,0) # remainder
File2="D:\File2.txt"
Clip1.A_Two_Pass_Function(Pass=1,LogFile=File1)
ForceProcessAVI() # Clip1, Force Pass 1
Clip2.A_Two_Pass_Function(Pass=1,LogFile=File2)
ForceProcessAVI() # Clip2, Force Pass 1
Result1 = Clip1.A_Two_Pass_Function(Pass=2,LogFile=File1) # Clip 1 Pass 2
Result2 = Clip2.A_Two_Pass_Function(Pass=2,LogFile=File2) # Clip 2 Pass 2
return Result1++Result2
OR another with only single clip
WhateverSource(...)
Clip1 = Trim(1000,1999) # 2000 frames
File1="D:\File1.txt"
Clip1.A_Two_Pass_Function(Pass=1,LogFile=File1)
ForceProcessAVI() # Clip1, Force Pass 1
Result1 = Clip1.A_Two_Pass_Function(Pass=2,LogFile=File1) # Clip 1 Pass 2
Return Trim(0,999) + Clip1 + Trim(2000,0)
EDIT: Oh good, my bread is done, now for some bacon, egg and mushrooms ,with fresh baked bread. :)
EDIT: Or another example from this thread:- https://forum.doom9.org/showthread.php?p=1782861&highlight=Deshaker#post1782861
DS_ForceProcess(clip, Bool "Debug"=True)
Useful where a clip outputs some kind of file for use in a second filter, this function would in such a case
forcibly read the clip, and therefore write the file, so that it may be available to other filters or to a second pass of the filter that
initially wrote the file.
Debug, default true. Write Progress to DebugView (Google).
Returns only after completed force reading of video frames (and audio samples if any).
Returns 0.
Example, Auto 2 Pass script:-
LoadVirtualDubPlugin ("Deshaker.vdf", "deshaker", preroll=0)
FN="F:\Shaky.avi"
AviSource(FN).ConvertToRGB32.Trim(10000,-500)
DUMMY=Some2PassFunc(Pass=1) # A script function that calls Deshaker to produce log file.
DS_ForceProcess(DUMMY) # Forcibly read all frames in clip and output deshaker.log.
DUMMY=0 # KILL DUMMY clip (Call Deshaker Destructor and close deshaker.log, so that can be reopened for pass 2)
Some2PassFunc(Pass=2) # Pass 2 deshaker function.
Return Last
Hat3L0v3
2nd February 2023, 15:02
OK, I guess I did not think about it too much, I forgot the extra few frames. :(
Can you get rid of most of the deshaken clip using just a few settings and no before and after extra frames, and write result clip to AVI, (process as per clipclop).
Then we concentrate on the fewer awkward ranges.
Is that possible, or are all of them awkward ?
EDIT:
Can create two pass filtering like this [Using either ForceProcessAVI() from TWriteAvi dll, or RT_ForceProcess() from RT_Stats.]
WhateverSource(...)
Clip1 = Trim(0,-2000) # 2000 frames
File1="D:\File1.txt"
Clip2 = Trim(2000,0) # remainder
File2="D:\File2.txt"
Clip1.A_Two_Pass_Function(Pass=1,LogFile=File1)
ForceProcessAVI() # Clip1, Force Pass 1
Clip2.A_Two_Pass_Function(Pass=1,LogFile=File2)
ForceProcessAVI() # Clip2, Force Pass 1
Result1 = Clip1.A_Two_Pass_Function(Pass=2,LogFile=File1) # Clip 1 Pass 2
Result2 = Clip2.A_Two_Pass_Function(Pass=2,LogFile=File2) # Clip 2 Pass 2
return Result1++Result2
OR another with only single clip
WhateverSource(...)
Clip1 = Trim(1000,1999) # 2000 frames
File1="D:\File1.txt"
Clip1.A_Two_Pass_Function(Pass=1,LogFile=File1)
ForceProcessAVI() # Clip1, Force Pass 1
Result1 = Clip1.A_Two_Pass_Function(Pass=2,LogFile=File1) # Clip 1 Pass 2
Return Trim(0,999) + Clip1 + Trim(2000,0)
EDIT: Oh good, my bread is done, now for some bacon, egg and mushrooms ,with fresh baked bread. :)
man, I can't understand what are you talking about... what this A_Two_Pass_Function do? your ClipClop filter doesn't do what I wanted to do?
Am I explaining bad? I have ranges that you help to create, I need to apply deshaker to last 5frames of every scene. thats why I need to convert them like this:
0 702 -> 698 702 -> 698 704
703 893 -> 889 893 -> 889 895
894 976 -> 972 976 -> 972 978
977 1190 -> 1186 1190 -> 1186 1192
original -> if param1 = 5 -> if param1 = 5
ranges param2 = 0 param2 = 2
other parts are beeing untouched (like you said your clipclop do)
StainlessS
2nd February 2023, 15:27
Basically, that is how you can process a two pass script,
eg, pass1 make a deshaker log,
pass2, deshake the clip.
Instead of two different scripts.
give me time, I'll try figure something out.
Hat3L0v3
2nd February 2023, 15:43
Basically, that is how you can process a two pass script,
eg, pass1 make a deshaker log,
pass2, deshake the clip.
Instead of two different scripts.
give me time, I'll try figure something out.
I'm not hurry you, I'm just not programmer to understand your program language.
Imagine you trying to explain Quantum field theory to a monkey that are looking at you like on God. I need something more simple like: banana -> mouth -> eat -> :)
If I tried to load your ClipClop as avs/avsi it gives me error: Platform returned code 193: %1 Is Not a Valid Win32 Application
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.