HeartlessS Usurer
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
|
Post #1 of 2
Not releasing RT_Stats v1.31 with docs just yet, but here it is without new docs or source.
Also includes Prune for Audio. (copy plugs to Plugins dir).
Have implemented for Audio anyways, and two scripts, one to keep unique frames, and one that dont.
See beginning of avs for config.
Here are dll's (still need Gscript and FrameSel v1.12) : LINK REMOVED
Keep Unique script:
Code:
# ############################
# Fsel_EduardobedoyaKeepUnique_Batch.avs, by StainlessS
# ############################
# Alter below to Config
########################################################################
########################################################################
########################################################################
ScanAheadSecs = 10 * 60 # Search ahead range in seconds
####
# Below settings, as close to zero as possible (faster but might miss duplicates), used by QWIK scan routines
LODIFFMED = 1 # INT, Max diff (-ve tolerance) of YMedian between i frame and possible duplicate (may vary with clip, 0.0 for EXACT match)
HIDIFFMED = 1 # INT, Max diff of YMedian between i frame and possible duplicate (may vary with clip, 0.0 for EXACT match)
#
LODIFFAL = 0.01 # Float, Max diff (-ve tolerance) of AverageLuma between i frame and possible duplicate (may vary with clip, 0.0 for EXACT match)
HIDIFFAL = 0.01 # Float, Max diff of AverageLuma between i frame and possible duplicate (may vary with clip, 0.0 for EXACT match)
#
LODIFFSTD = 0.01 # Float, Max diff (-ve tolerance) of YPlaneStdev between i frame and possible duplicate (may vary with clip, 0.0 for EXACT match)
HIDIFFSTD = 0.01 # Float, Max diff of YPlaneStdev between i frame and possible duplicate (may vary with clip, 0.0 for EXACT match)
#
LODIFFINR = 0.01 # Float, Max diff (-ve tolerance) of YInRange between i frame and possible duplicate (may vary with clip, 0.0 for EXACT match)
HIDIFFINR = 0.01 # Float, Max diff of YInRange between i frame and possible duplicate (may vary with clip, 0.0 for EXACT match)
####
####
# Below used to identify if candidate frames found by QWIK SCAN routines are good.
MAX_LDIFF = 0.01 # Float, LumaDifference between candidate frame and duplicate (average pixel diff rather than frame diff, 0.0 Exact match)
####
####
AUDIO = True # False, no audio. True Supports audio, Audio requires Prune Plugin
####
########################################################################
########################################################################
########################################################################
FSEL_TITLE="Select AVI, files Will Batch create FrameSel command files"
FSEL_DIR="."
FSEL_FILT="Avi files|*.avi"
FSEL_MULTI=True
AVIFILE_LIST = RT_FSelOpen(title=FSEL_TITLE,dir=FSEL_DIR,filt=FSEL_FILT,multi=FSEL_MULTI)
Assert(AVIFILE_LIST.IsString,"RT_FSelOpen: Error="+String(AVIFILE_LIST))
NFILES=RT_TxtQueryLines(AVIFILE_LIST) # Query Number of lines in String ie number of files.
myName="Fsel_EduardobedoyaKeepUnique_Batch: "
LOG="Fsel_EduardobedoyaKeepUnique_Batch.Log"
RT_TxtWriteFile(LOG,LOG,Append=False)
GSCript("""
TOTSTART = RT_Timer
For(i=0,NFILES-1) {
START = RT_Timer
FN=RT_TxtGetLine(AVIFILE_LIST,i) # Filename of avi file i
S=RT_String("\n\n%d/%d ] Processing %s",i+1,NFILES, FN)
RT_DebugF(S,name=myName)
RT_TxtWriteFile(S,LOG,Append=True)
DropDupSequencesKeepUnique(FN,ScanAheadSecs,
\ ldm=LODIFFMED, hdm=HIDIFFMED,
\ ldL=LODIFFAL, hdL=HIDIFFAL,
\ lds=LODIFFSTD, hds=HIDIFFSTD,
\ ldr=LODIFFINR, hdr=HIDIFFINR,
\ LDThresh=MAX_LDIFF,audio=AUDIO,log=LOG)
T = RT_Timer - START
S=RT_String(" %s Tot File Time = %.2f Seconds (%.2f Mins)",FN, T,T/60.0)
RT_DebugF(S,name=myName)
RT_TxtWriteFile(S,LOG,Append=True)
}
T = RT_Timer - TOTSTART
S=RT_String("\n\nTOTAL Time = %.2f Seconds (%.2f Mins)\n",T,T/60.0)
RT_DebugF(S,name=myName)
S=RT_String("\n\nDONE\n\n%s\n",S)
RT_TxtWriteFile(S,LOG,Append=True)
S=RT_StrReplace(S,Chr(10),"\n")
""")
Return blankclip(length=24*60*60*24).Subtitle(S,Align=5,Y=100,lsp=0,Size=30)
Function DropDupSequencesKeepUnique(String "AviName",int "ScanAheadSecs",
\ int "ldM",int "hdM",Float "ldL",Float "hdL",Float "ldS",Float "hdS",Float "ldR",Float "hdR",Float "LDThresh",Bool "Audio",String "Log") {
myName="DropDupSequencesKeepUnique: "
ScanAheadSecs=Default(ScanAheadSecs,10*60)
ldM = Default(ldM,1) hdM = Default(hdM,1)
ldL = Float(Default(ldL,0.01)) hdL = Float(Default(hdL,0.01))
ldS = Float(Default(ldS,0.01)) hdS = Float(Default(hdS,0.01))
ldR = Float(Default(ldR,0.01)) hdR = Float(Default(hdR,0.01))
LDThresh = Float(Default(LDThresh,0.01))
LOG = Default(LOG,"DropDupSequencesKeepUnique.LOG")
Assert(Exist(AviName),myName+AviName+" Does Not Exist")
Avisource(AviName)
Audio=Default(Audio,False) # Needs Prune plugin if Audio
Audio=(!HasAudio) ? False : Audio
Assert(ScanAheadSecs>=0,myName+"ScanAheadSecs Must be greater than zero")
Assert(ldM>=0 && hdM >0,myName+"ldM and hdM Must be greater than zero")
Assert(ldL>=0.0 && hdL >=0.0,myName+"ldL and hdL Must be greater or equal to zero")
Assert(ldS>=0.0 && hdS >=0.0,myName+"ldS and hdS Must be greater or equal to zero")
Assert(ldR>=0.0 && hdR >=0.0,myName+"ldR and hdR Must be greater or equal to zero")
PathAndNode = RT_FilenameSplit(AviName,7) # Drive + Dir + Name
CMDFrames=PathAndNode+"_KUnique_Frames.txt"
ScriptFile=PathAndNode+"_KUnique_SelectFrames.AVS"
ScanAheadFrames = Int(ScanAheadSecs*FrameRate)
DB=PathAndNode+".DB"
NextDB=PathAndNode+"_Next.DB"
RT_FileDelete(CMDFrames) # Delete any existing frames file
FrameSel_Select="""
Avisource("%s")
CmdFrames="%s"
(Exist(CmdFrames)) ? FrameSel(cmd=CmdFrames,reject=True) : NOP
Return Last
"""
Prune_Select="""
Avisource("%s")
CmdFrames="%s"
PruneFrames=CmdFrames+"_Prune.txt"
Ex=(Exist(CmdFrames))
(Ex) ? FrameSel_CmdReWrite(PruneFrames,Cmd=CmdFrames,reject=True,Range=True,Prune=True) : NOP
(Ex) ? Prune(cmd=PruneFrames,Fade=10,FadeIn=True,FadeSplice=True,FadeOut=True) : NOP
Return Last
"""
Select_S = (Audio) ? Prune_Select : FrameSel_Select # Select FrameSel or Prune extraction
Select_S = RT_StrReplaceDeep(RT_StrReplace(Select_S,Chr(9)," ")," "," ") # TAB and SPACE compact
Select_S = RT_String(Select_S,AviName,CmdFrames) # Insert filenames
START = RT_Timer
RT_QwikAveLumaScanCreateDB(DB,prevdb="",nextdb=NextDB,debug=true) # Forward scanning
T= RT_Timer - START
S = RT_String(" QWIK Scan DBase creation = %.2f Secs (%.2f Mins)",T,T/60.0)
RT_TxtWriteFile(S,LOG,Append=True)
GSCript("""
START = RT_Timer
Dropped = 0
LastFrame=FrameCount-1
RT_DebugF(" QWIK Scanning file ... Please Wait",name=myName)
For(i=0,LastFrame) {
EndLimit = Min(i + ScanAheadFrames,LastFrame) # Searching i+1 to Endlimit inclusive
# QWIK Find a series of likely matching frames
For(j = i + 1,EndLimit) {
j = RT_QwikAveLumaScanGetNear(DB,NextDB,j,
\ findframe=i,
\ LoDiffMed =ldM, HiDiffMEd =hdM,
\ LoDiffAl =ldL, HiDiffAL =hdL,
\ LoDiffStd =ldS, HiDiffStd =hdS,
\ LoDiffInr =ldR, HiDiffInr =hdR,
\ maxdistance=EndLimit-j, Inclusive=True)
if(j < 0) { # j Will be -1, ie Not Found
j = EndLimit # Early break from j, DONT delete frame
} Else { # We found a candidate frame, j will be greater than i
dif=RT_LumaDifference(Last,Last,n=i,n2=j) # Average pixel diff between i frame and candidate j
if(dif <= LDThresh) { # is candidate frame a good match ?
Dropped = Dropped + 1
RT_TxtWriteFile(String(i),
\ CMDFrames,Append=True) # Frame to DELETE, Keep later frame, delete earlier
j = EndLimit # Early break, move on to next i frame
} # Otherwise continue QWIK scan for next candidate in series
}
}
}
RT_TxtWriteFile(Select_S,ScriptFile,Append=False)
RT_FileDelete(DB)
RT_FileDelete(NextDB)
T = RT_Timer - START
FT=FrameCount / FrameRate
S=RT_String(" Dropping %d of %d frames [%dx%d %.2f secs (%.2f Mins) @ %.2f FPS]\n QWIK SCAN %.2f Secs (%.2f Mins) InFPS=%.2f OutFPS=%.2f", \
Dropped, FrameCount,Width,Height,FT,FT/60.0,FrameRate,T,T/60.0,FrameCount/T,(FrameCount-Dropped)/T)
RT_DebugF(S,name=myName)
RT_TxtWriteFile(S,LOG,Append=True)
""")
Return 0
}
EDITED:
and log
Code:
Fsel_EduardobedoyaKeepUnique_Batch.Log
1/4 ] Processing D:\AVS\AVI\IN\FLASHTEST.avi
QWIK Scan DBase creation = 15.75 Secs (0.26 Mins)
Dropping 0 of 7342 frames [640x400 293.68 secs (4.89 Mins) @ 25.00 FPS]
QWIK SCAN 5.42 Secs (0.09 Mins) InFPS=1354.36 OutFPS=1354.36
D:\AVS\AVI\IN\FLASHTEST.avi Tot File Time = 21.25 Seconds (0.35 Mins)
2/4 ] Processing D:\AVS\AVI\IN\Scrambled.avi
QWIK Scan DBase creation = 244.28 Secs (4.07 Mins)
Dropping 25500 of 45000 frames [720x576 1800.00 secs (30.00 Mins) @ 25.00 FPS]
QWIK SCAN 524.80 Secs (8.75 Mins) InFPS=85.75 OutFPS=37.16
D:\AVS\AVI\IN\Scrambled.avi Tot File Time = 769.27 Seconds (12.82 Mins)
3/4 ] Processing D:\AVS\AVI\IN\TEST2.avi
QWIK Scan DBase creation = 46.72 Secs (0.78 Mins)
Dropping 0 of 15319 frames [720x576 612.76 secs (10.21 Mins) @ 25.00 FPS]
QWIK SCAN 20.47 Secs (0.34 Mins) InFPS=748.40 OutFPS=748.40
D:\AVS\AVI\IN\TEST2.avi Tot File Time = 67.47 Seconds (1.12 Mins)
4/4 ] Processing D:\AVS\AVI\IN\TEST.avi
QWIK Scan DBase creation = 57.47 Secs (0.96 Mins)
Dropping 0 of 13861 frames [720x576 554.44 secs (9.24 Mins) @ 25.00 FPS]
QWIK SCAN 13.17 Secs (0.22 Mins) InFPS=1052.31 OutFPS=1052.31
D:\AVS\AVI\IN\TEST.avi Tot File Time = 70.84 Seconds (1.18 Mins)
DONE
TOTAL Time = 928.83 Seconds (15.48 Mins)
Only Scrambled.avi is scrambled, others just to test that it dont delete frames where not required.
Here MakeScrambled.avs, test clip
Code:
###################
# MakeScrambled.avs
###################
# Only of use in testing, (If you dont have a real problem clip)
Function ScrambleClip(clip c) { # intended for PAL source [numbers may not work for NTSC, have not tried, use AssumeFPS(25.0) beforehand]
c
fc=FrameCount
Need = 27 * 750
Assert(fc >= Need,"ScrambleClip:, need at least "+String(Need)+" Frame clip as source(got "+String(fc)+")")
# Below XYZ isolated sequence. Will keep all upper case letters (including XYZ in Keep Unique script).
# Keep unique script will keep LAST instance of ALL frames within Scanahead.
# Non Keep Unique avs will jump past XYZ frames and they will not be kept, but faster. (jumps from 1st lowercase 'a' to
# last 'A', and omits everything between.
Test = Ucase("abcdabcdXYZdefdefgABCdefdefgDEFghijGHIJKLmnopmnopMNOPQRSTUVW")
CC=C.BlankClip(length=0) # zero length clip
GScript("""
For(i=1,StrLen(Test)) {
s = MidStr(Test,i,1)
si = RT_ORD(s) - RT_Ord("A") # Subtract 65, make 'A'=0, 'Z' = 25
CT=C.Trim(si*750,-750).Subtitle(S,Size=20)
CT = (s>="X" && s<="Z") ? CT.Subtitle("UNIQUE",Align=5,size=60) : CT
CC = CC ++ CT
}
""")
return CC
}
avisource("JurassicPark.avi")
Trim(16854,182049) # Chop off intro
ScrambleClip()
return last
Last edited by StainlessS; 17th December 2014 at 21:40.
|