View Single Post
Old 25th March 2014, 09:39   #18  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
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
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 17th December 2014 at 21:40.
StainlessS is offline   Reply With Quote