Jump to content

WM Recorder 11 GUI automation script


Maxim Vexler
 Share

Recommended Posts

Hi guys,

I've written a little automation for WM Recorder because that is the only application I could find that would record the propriaty mms streaming protocol.

Here it is, in the hope that It would be useful to some one.

It works pretty well but it's not perfect and some features are still missing.

Enjoy!

;AutoIt 3 automation script for WM Recorder 11.0
;Copyright (C) 2006  Maxim Veksler hq4ever-@-gmail-com 
;
;This program is free software; you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;as published by the Free Software Foundation; either version 2
;of the License, or (at your option) any later version.
;
;This program is distributed in the hope that it will be useful,
;but WITHOUT ANY WARRANTY; without even the implied warranty of
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;GNU General Public License for more details.
;
;http://www.gnu.org/copyleft/gpl.html


;;;;;;;;;;;;; FUNCTIONS

Func _nixNOW()
    Return @MON & @MDAY & @HOUR & @MIN & @YEAR & @SEC
EndFunc

Func FileNameFromURI($uri)
    $_position = StringInStr ( $uri, "/" , 0, -1 )
    $_filename = StringMid ( $uri , $_position+1 )
    Return $_filename
EndFunc

Func FileNameFromPath($file_path)
    $_position = StringInStr ( $file_path, "\" , 0, -1 )
    $_filename = StringMid ( $file_path, $_position+1 )
    Return $_filename
EndFunc
    
Func RecordingPath($uri)
    Local Const $ROOT_PATH = "c:\videos"
    $_position_from = StringInStr ( $uri, "/", 0, -2 )
    $_position_to = StringInStr ( $uri, "/", 0, -1 )
    $_fldr_name = StringMid ( $uri, $_position_from+1, ($_position_to-$_position_from)-1 )
    Return $ROOT_PATH & $_fldr_name
EndFunc

Func WaitDownload($mainwnd_hndl, $dest_file_pattern, $dest_file_path)
    Local Const $GRACE_TIMER = 50000
    Dim $_ctrl_status_init_time = TimerInit()
    Dim $_ctrl_status_lastrun_text

    While 1 = 1
        $_ctrl_status_text = ControlGetText ( $mainwnd_hndl, "", "Edit1" )
        $_status = StringSplit ( StringStripWS($_ctrl_status_text, 4), " " )
        
        ;; TODO: First check should be how many times we've run this baby (based on time diff)
        ;; Could be we're in some nice endless loop, and as you know it : Endless loops are not nice
        ;;;;;; Check to see if we oversteped permitted run times
        ; if TRIED TO DOWNLOAD TOO MUCH TIMES() > HOW_MUCH_TIMES_CAN_I_RUN then
        ;   return -4

        ;;;;;; Wait until we get "real status" from extenal application and not some unknown junk
        if ($_status[0] <> 7) then
            If ($_status[1] == "Mode:") then
                Return -1;
            Else
                sleep(250)
                ContinueLoop
            Endif
        Endif

        ;;;;;; Check If download finished
        ;; example text: "0. Numerical%20...  100% 82.436 MB 0 Kbps"
        If ( ($_status[3] == "100%") AND ($_status[6] == "0") ) then
            Return 0 ;Downloaded (finished)
        Endif
        
        ;;;;;; Check if download hung
        if ($_ctrl_status_text == $_ctrl_status_lastrun_text) then
            if ( TimerDiff($_ctrl_status_init_time) > $GRACE_TIMER ) then
                Return -1 ;Download stopped (hung)
            Endif
        Else
            $_ctrl_status_init_time = TimerInit()
        Endif

        ;;;;;; Do total file size logic as soon as possible, i.e. as we reach 2%
        If ( (Not IsDeclared("_total_fl_size")) AND (Number(StringTrimRight($_status[3], 1)) == 1) ) then
            $_1percent_fl_size = Number($_status[4])
        Endif
        
        If ( (Not IsDeclared("_total_fl_size")) AND (Number(StringTrimRight($_status[3], 1)) == 3) ) then
            $_2percent_fl_size = Number($_status[4])
            $_total_fl_size = (($_2percent_fl_size - $_1percent_fl_size) * 100)
            $_ondisk_dest_files = FileFindToArray($dest_file_pattern,$dest_file_path)           
            If IsArray ( $_ondisk_dest_files ) then
                $_ondisk_dest_file_size = FileGetSize($dest_file_path & $_ondisk_dest_files[0]) / 1048576
            Else
                $_ondisk_dest_file_size = (-999999999)
            Endif

            If ( IsDeclared("_total_fl_size") AND IsDeclared("_ondisk_dest_file_size") ) then
                If ( Abs($_total_fl_size - $_ondisk_dest_file_size) < 6 ) then
                    return -2 ;File exists full (downloaded)
                Endif
            Endif
        Endif

        ;;;;;; Loop internal variable initialization
        $_ctrl_status_lastrun_text = ControlGetText ( $mainwnd_hndl, "", "Edit1" )
        Sleep(250)
    Wend
EndFunc

Func delay_WaitForControl($handle, $text, $controlID, $delay_ms_limit=300000)
    Dim $_ctrl_delay_init_time = TimerInit()
    Do
        If ( TimerDiff($_ctrl_delay_init_time) > $delay_ms_limit ) then
            Return @error
        Endif
        sleep(5)
        AutoItSetOption("WinTitleMatchMode", 4)
        ControlGetPos ( $handle, $text, $controlID )
    Until (@error == 0)
    Return @error
EndFunc

Func FileFindToArray( $filename_pattern, $path="" )
;;
;; Will return an array of files name, sorted by biggest first.
;; Note the case of return value (-1) if no files found.
;;
    Dim $MatchFileName[1]
    
    If ( (StringLen($path) > 0) AND (StringRight($path,1) <> "\") ) then 
        $path = $path & "\"
    Endif
    $search = FileFindFirstFile($path & $filename_pattern)  

    If $search = (-1) Then
        Return 0
    EndIf

    While 1 = 1
        $file = FileFindNextFile($search) 
        If @error Then ExitLoop
        $MatchFileName[Ubound($MatchFileName)-1] = $file
        ReDim $MatchFileName[UBound($MatchFileName)+1]
    WEnd
    
    ; Close the search handle
    FileClose($search)
    ReDim $MatchFileName[UBound($MatchFileName)-1]

    For $i = (UBound($MatchFileName)-2) to 0 Step -1; (-2) because = 1 for UBound, 1 to loop not reaching last object.
        for $j = 0 to $i 
            If FileGetSize( $path & $MatchFileName[$j] ) < FileGetSize( $path & $MatchFileName[$j+1] ) then
                $swap = $MatchFileName[$j]
                $MatchFileName[$j] = $MatchFileName[$j+1]
                $MatchFileName[$j+1] = $swap
            Endif
        Next
    Next

    Return $MatchFileName
EndFunc

Func _Change_Folder_WMR11( $folder_path )
    delay_WaitForControl("classname=#32770", "General", "Button4")
    ControlClick ( WinGetHandle("classname=#32770", "General"), "", "Button4" )
    
    delay_WaitForControl("classname=#32770", "If you are using an older version of WM Recorder", "Button1")
    ControlClick ( WinGetHandle("classname=#32770", "If you are using an older version of WM Recorder"), "", "Button1" )
    
    delay_WaitForControl("classname=#32770", "Recordings directory", "Edit1")
    ControlSetText ( WinGetHandle("classname=#32770", "Recordings directory"), "", "Edit1",  RecordingPath($folder_path) )
    
    delay_WaitForControl("classname=#32770", "Recordings directory", "Button2")
    ControlClick ( WinGetHandle("classname=#32770", "Recordings directory"), "", "Button2" )
    
    delay_WaitForControl("classname=#32770", "General", "Button8")
    ControlClick ( WinGetHandle("classname=#32770", "General"), "", "Button8" )
EndFunc

Func _Close_Recording_Window_WMR11()
    delay_WaitForControl("classname=#32770", "Right click the File Name for options", "Button1")
    ControlClick ( WinGetHandle("classname=#32770", "Right click the File Name for options"), "", "Button1" )
    If delay_WaitForControl("classname=#32770", "This will stop all current recordings", "Button1", 7000) == 0 then
        ControlClick ( WinGetHandle("classname=#32770", "This will stop all current recordings"), "", "Button1" )
    Endif
EndFunc

Func SearchWindowByTitle($WindowList, $TitleText)
    Dim $i = 0

    For $i = 1 to $WindowList[0][0]
        If ( $WindowList[$i][0] == $TitleText ) then
            Return $WindowList[$i][1]
        Endif
    Next
    Return 0
EndFunc

Func WindowMakeActive( $handle )
    $_wnd_state = WinGetState($handle) 
    WinSetState( $handle, "", @SW_ENABLE )
    WinSetState( $handle, "", @SW_SHOW )
    WinSetState( $handle, "", @SW_RESTORE )
    WinActivate ( $handle )
    Return $_wnd_state
EndFunc


Func WindowRestoreState( $handle, $wnd_state )
    If BitAnd($wnd_state, 4) then
        WinSetState( $handle, "", @SW_ENABLE)
    Else
        WinSetState( $handle, "", @SW_DISABLE)
    Endif
    
    If BitAnd($wnd_state, 2) then
        WinSetState( $handle, "", @SW_SHOW)
    Else
        WinSetState( $handle, "", @SW_HIDE)
    Endif
    
    Select
        case BitAnd($wnd_state, 16)
            WinSetState( $handle, "", @SW_MINIMIZE )
        case BitAnd($wnd_state, 32)
            WinSetState( $handle, "", @SW_MAXIMIZE )
    EndSelect
EndFunc

;; An enhanced MouseClick that would do anything it can to click-that-button
Func MouseKick( $wnd_handle=0, $x="XPOS", $y="YPOS", $aio_MouseCoordMode=0, $mouse_button="primary", $clicks=1, $speed=0 )
    AutoItSetOption ( "MouseCoordMode", $aio_MouseCoordMode )
    $_app_state = WindowMakeActive ( $wnd_handle )
    If ( IsNumber($x) AND IsNumber($y) ) then
        MouseClick ( $mouse_button, $x, $y, $clicks, $speed )
    Else
        $pos = MouseGetPos()
        MouseClick ( $mouse_button, $pos[0], $pos[1], $clicks, $speed )
    Endif
    WindowRestoreState ( $wnd_handle, $_app_state )
EndFunc

;;;;;;;;;;;;; DATA

Dim $StreamingSources[7]
;; StringFormat = "protocol://URI/static-name,TRAILING-ZEROS,FROM-COUNT,TO-COUNT,.extension"

$StreamingSources[0] = "mms://video.sub.domain.tld/path/to/streaming/source/FILENAME-,2,6,27,.wmv"
$StreamingSources[1] = "mms://video.sub.domain.tld/path/to/streaming/source/OTHERNAME_,2,1,28,.wmv"

; Example: $StreamingSources[0] = "mms://video.site.com/video/hot/movie-,5,1,4,.wmv" would download :
; mms://video.site.com/video/hot/movie-00001.wmv
; mms://video.site.com/video/hot/movie-00002.wmv
; mms://video.site.com/video/hot/movie-00003.wmv
; mms://video.site.com/video/hot/movie-00004.wmv


;;;;;;;;;;;;; INITIALIZATION

AutoItSetOption( "WinTitleMatchMode", 4 )
AutoItSetOption( "MouseCoordMode", 0 )
AutoItSetOption( "TrayIconDebug", 1 )
$_wmr_winlist = WinList("classname=#32770")

;;;;;;;;;;;;; START HELPER APPLICATIONS

;; So, what am I doing here ? 
;; If all checks for application parts return false: I'm assuming application is not launched.
;; If all checks for application parts return true: I'm assuming application is launched and active
;; If some parts return true and others say false: I'm assuming application is semi loaded, so lets reload it

If ( (SearchWindowByTitle( $_wmr_winlist, "" ) == 0) AND _
    (SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Windows Media" ) == 0) AND _
    (SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Recording Window" ) == 0) ) then
    ;; Good, no memory resistent copies of application, launch it
    run("C:\Program Files\WMR11\WMR11.exe")
Elseif ( (SearchWindowByTitle( $_wmr_winlist, "" ) <> 0) AND _
        (SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Windows Media" ) <> 0) AND _
        (SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Recording Window" ) <> 0) ) then
    ;; looks like the application is fully loaded, let it be
    msgbox(0,"","Looks fine to me, application is active")
Else
    ;; If we got here that means part of the application is still in memory
    ;; Kill all available parts and then reload.
    WinKill( SearchWindowByTitle( $_wmr_winlist, "" ) )
    WinKill( SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Windows Media" ) )
    WinKill( SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Recording Window" ) )
    ProcessClose ( "WMR11.exe" )
    ProcessWaitClose("WMR11.exe")
    run("C:\Program Files\WMR11\WMR11.exe")
endif

;; Loop until splashscreen gone, which has the same classname and same text :(
delay_WaitForControl("classname=#32770", "", "Edit2")

;; Second run of WinList() to include changes occured after HELPER APPLICATION logic
$_wmr_winlist = WinList("classname=#32770")

;;;;;;;;;;;;; RUN MAIN RECORDING LOOP

if WinWait("classname=#32770") then
    
    $handle_mainwnd = SearchWindowByTitle( $_wmr_winlist, "" )

    For $indx = 0 to UBound($StreamingSources)-1
        $_strmInfo = StringSplit ( $StreamingSources[$indx], "," )
        
        DirCreate ( RecordingPath($_strmInfo[1]) )

        For $i = Number($_strmInfo[3]) to Number($_strmInfo[4])             ;; download from [number] to [how many there are]...
            $_strformat = "%." & $_strmInfo[2] & "d" & $_strmInfo[5]
            $_waitdl_file = FileNameFromURI($_strmInfo[1]) & StringFormat($_strformat, $i)
            $_waitdl_file_pattern = FileNameFromURI($_strmInfo[1]) & StringFormat("%." & $_strmInfo[2] & "d*" & $_strmInfo[5],$i)

            delay_WaitForControl($handle_mainwnd, "", "Edit2")
            ControlSetText ( $handle_mainwnd, "", "Edit2", $_waitdl_file )
            ControlSetText ( $handle_mainwnd, "", 321, $_strmInfo[1] & StringFormat($_strformat, $i) )
            
            ;; STATR: Folder change sequance for application
            MouseKick( $handle_mainwnd, 250, 50 )
            _Change_Folder_WMR11( RecordingPath($_strmInfo[1]) )    
            ;; END: Do folder change sequance

            ;; Click on the record button
            MouseKick( $handle_mainwnd, 45, 75 )
            

            $_waitdl_ret = WaitDownload( $handle_mainwnd, $_waitdl_file_pattern,  RecordingPath($_strmInfo[1]) & "\" )
            
            Select 
                case $_waitdl_ret == (-1)
                    ;; msgbox (1, "", "WaitDownload sayed -1 == application did nothing for Xms time")
                    ;; OK, wait a couple of min and try again will'ya ;)
                    sleep (15000)
                    $i=$i-1
                    
                case $_waitdl_ret == 0
                    ; Very Cool !
                    ; Here we go for the biggest of them all with FileFindToArray() and then delete all the rest(?)
                    $_ondisk_media_files = FileFindToArray( $_waitdl_file_pattern, RecordingPath($_strmInfo[1]) & "\" )         
                    If IsArray ( $_ondisk_media_files ) then
                        for $ifile = 1 to UBound($_ondisk_media_files)-1
                            FileMove( RecordingPath($_strmInfo[1]) & "\" & $_ondisk_media_files[$ifile], _
                                RecordingPath($_strmInfo[1]) & "\" & _nixNOW() & "_" & $_ondisk_media_files[$ifile] )
                        Next
                        FileMove( RecordingPath($_strmInfo[1]) & "\" & $_ondisk_media_files[0], _
                                RecordingPath($_strmInfo[1]) & "\" & $_waitdl_file )
                    Endif
                    
                case $_waitdl_ret == (-2)
                    ; Very Cool !
                    ; Here we go for the biggest of them all with FileFindToArray() and then delete all the rest(?)
                    $_ondisk_media_files = FileFindToArray( $_waitdl_file_pattern, RecordingPath($_strmInfo[1]) & "\" )         
                    If IsArray ( $_ondisk_media_files ) then
                        for $ifile = 1 to UBound($_ondisk_media_files)-1
                            FileMove( RecordingPath($_strmInfo[1]) & "\" & $_ondisk_media_files[$ifile], _
                                RecordingPath($_strmInfo[1]) & "\" & _nixNOW() & "_" & $_ondisk_media_files[$ifile] )
                        Next
                        FileMove( RecordingPath($_strmInfo[1]) & "\" & $_ondisk_media_files[0], _
                                RecordingPath($_strmInfo[1]) & "\" & $_waitdl_file )
                    Endif

                case $_waitdl_ret == (-4)
                    ; msgbox (1, "", "WaitDownload sayed -4 == dude, your over your limits")
                    ; Fuck it, fuck him, fuck everyone. "If YOU don't want to be downloaded I am surely not going to do it for you ;)"
                    $_foo = "foo"

                case else
                    msgbox (1, "", "WaitDownload sayed " & $_waitdl_ret & "(wtf?)" )
            Endselect
            
            ;; Helper application logic: End recording session before starting new one
            _Close_Recording_Window_WMR11()
        Next
    Next 
endif
Link to comment
Share on other sites

Whats WMrecorder?

I tried not to, but you are forcing me to do promotion for the product :whistle:

WM Recorder is an application wrapper for common streaming protocols such as mms and rtsp, it uses the open source libpcap library on windows to record the network traffic the comes from the streaming source to the viewer and then dumps this stream to a file on the hard disk for later review. Very useful and works great. The only downside is that it's (like most windows applications) totaly non scriptable and GUI only based, that's when I believe my script comes into play allowing to interface with the application using it's GUI.

I'm using it to record video lectures for later viewing and to save bandwidth if I wish to view the same lecture twice.

Check http://www.wmrecorder.com/

I would love to hear someone trying the script and reporting if it worked for him.

Cheers,

Maxim.

Link to comment
Share on other sites

Major update and bugfix :">

I think that even you guys who don't use WM Recorder could find this code useful, for example check MouseKick() function.

Enjoy !

Maxim.

;AutoIt 3 automation script for WM Recorder 11.0
;Copyright (C) 2006  Maxim Veksler hq4ever-@-gmail-com 
;
;This program is free software; you can redistribute it and/or
;modify it under the terms of the GNU General Public License
;as published by the Free Software Foundation; either version 2
;of the License, or (at your option) any later version.
;
;This program is distributed in the hope that it will be useful,
;but WITHOUT ANY WARRANTY; without even the implied warranty of
;MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;GNU General Public License for more details.
;
;http://www.gnu.org/copyleft/gpl.html


;;;;;;;;;;;;; FUNCTIONS

Func _nixNOW()
    Return @MON & @MDAY & @HOUR & @MIN & @YEAR & @SEC
EndFunc

Func FileNameFromURI($uri)
    Local $_position = StringInStr ( $uri, "/" , 0, -1 )
    Local $_filename = StringMid ( $uri , $_position+1 )
    Return $_filename
EndFunc

Func FileNameFromPath($file_path)
    Local $_position = StringInStr ( $file_path, "\" , 0, -1 )
    Local $_filename = StringMid ( $file_path, $_position+1 )
    Return $_filename
EndFunc
    
Func RecordingPath($uri)
    Local $_position_from = StringInStr ( $uri, "/", 0, -2 )
    Local $_position_to = StringInStr ( $uri, "/", 0, -1 )
    Local $_fldr_name = StringMid ( $uri, $_position_from+1, ($_position_to-$_position_from)-1 )
    Return $_fldr_name
EndFunc

Func WaitDownload($mainwnd_hndl, $dest_file_pattern, $dest_file_path)
    Local Const $GRACE_TIMER = 120000
    Local $_ctrl_status_init_time = TimerInit()
    Local $_ctrl_status_lastrun_text

    While 1 = 1
        Local $_ctrl_status_text = ControlGetText ( $mainwnd_hndl, "", "Edit1" )
        Local $_status = StringSplit ( StringStripWS($_ctrl_status_text, 4), " " )
        
        ;; TODO: First check should be how many times we've run this baby (based on time diff)
        ;; Could be we're in some nice endless loop, and as you know it : Endless loops are not nice

        ;;;;;; Wait until we get "real status" from extenal application and not some unknown junk
        if ($_status[0] <> 7) then
            If ( ($_status[1] == "Mode:") AND (TimerDiff($_ctrl_status_init_time) > $GRACE_TIMER) ) then
                Return -1;
            Else
                sleep(250)
                ContinueLoop
            Endif
        Endif

        ;;;;;; Check If download finished
        ;; example text: "0. Numerical%20...  100% 82.436 MB 0 Kbps"
        If ( ($_status[3] == "100%") AND ($_status[6] == "0") AND (TimerDiff($_ctrl_status_init_time) > 15000) ) then
            Return 0 ;Downloaded (finished)
        Endif
        
        ;;;;;; Check if download hung
        if ($_ctrl_status_text == $_ctrl_status_lastrun_text) then
            if ( TimerDiff($_ctrl_status_init_time) > $GRACE_TIMER ) then
                Return -1 ;Download stopped (hung)
            Endif
        Else
            $_ctrl_status_init_time = TimerInit()
        Endif

        ;;;;;; Do total file size logic as soon as possible, i.e. as we reach 2%
        If ( (Not IsDeclared("_total_fl_size")) AND (Number(StringTrimRight($_status[3], 1)) == 1) ) then
            Local $_1percent_fl_size = Number($_status[4])
        Endif
        
        If ( (Not IsDeclared("_total_fl_size")) AND (Number(StringTrimRight($_status[3], 1)) == 3) ) then
            Local $_2percent_fl_size = Number($_status[4])
            Local $_total_fl_size = (($_2percent_fl_size - $_1percent_fl_size) * 100)
            Local $_ondisk_dest_files = FileFindToArray($dest_file_pattern,$dest_file_path)         
            If IsArray ( $_ondisk_dest_files ) then
                Local $_ondisk_dest_file_size = FileGetSize($dest_file_path & $_ondisk_dest_files[0]) / 1048576
            Else
                Local $_ondisk_dest_file_size = (-999999999)
            Endif

            If ( IsDeclared("_total_fl_size") AND IsDeclared("_ondisk_dest_file_size") ) then
                If ( Abs($_total_fl_size - $_ondisk_dest_file_size) < 6 ) then
                    return -2 ;File exists full (downloaded)
                Endif
            Endif
        Endif

        ;;;;;; Check to see if we oversteped permitted run times
        ; if TRIED TO DOWNLOAD TOO MUCH TIMES() > HOW_MUCH_TIMES_CAN_I_RUN then
        ;   return -4

        ;;;;;; Loop internal variable initialization
        $_ctrl_status_lastrun_text = ControlGetText ( $mainwnd_hndl, "", "Edit1" )
        Sleep(250)
    Wend
EndFunc

Func _delay_WaitForControl($handle, $text, $controlID, $delay_ms_limit=20000)
    Local $_ctrl_delay_init_time = TimerInit()
    Do
        If ( TimerDiff($_ctrl_delay_init_time) > $delay_ms_limit ) then
            Return 0
        Endif
        sleep(5)
        AutoItSetOption("WinTitleMatchMode", 4)
        ControlGetPos ( $handle, $text, $controlID )
    Until (@error == 0)
    Return ( @error == 0 )
EndFunc

Func FileFindToArray( $filename_pattern, $path="" )
;;
;; Will return an array of files name, sorted by biggest first.
;; Note the case of return value (-1) if no files found.
;;
    Local $MatchFileName[1]
    
    If ( (StringLen($path) > 0) AND (StringRight($path,1) <> "\") ) then 
        Local $path = $path & "\"
    Endif
    $search = FileFindFirstFile($path & $filename_pattern)  

    If $search = (-1) Then
        Return 0
    EndIf

    While 1 = 1
        Local $file = FileFindNextFile($search) 
        If @error Then ExitLoop
        $MatchFileName[Ubound($MatchFileName)-1] = $file
        ReDim $MatchFileName[UBound($MatchFileName)+1]
    WEnd
    
    ; Close the search handle
    FileClose($search)
    ReDim $MatchFileName[UBound($MatchFileName)-1]
    Local $i

    For $i = (UBound($MatchFileName)-2) to 0 Step -1; (-2) because = 1 for UBound, 1 to loop not reaching last object.
        for $j = 0 to $i 
            If FileGetSize( $path & $MatchFileName[$j] ) < FileGetSize( $path & $MatchFileName[$j+1] ) then
                Local $swap = $MatchFileName[$j]
                $MatchFileName[$j] = $MatchFileName[$j+1]
                $MatchFileName[$j+1] = $swap
            Endif
        Next
    Next

    Return $MatchFileName
EndFunc

Func _change_Folder_WMR11( $folder_path )
    _delay_WaitForControl("classname=#32770", "General", "Button4")
    ControlClick ( WinGetHandle("classname=#32770", "General"), "", "Button4" )
    
    _delay_WaitForControl("classname=#32770", "If you are using an older version of WM Recorder", "Button1")
    ControlClick ( WinGetHandle("classname=#32770", "If you are using an older version of WM Recorder"), "", "Button1" )
    
    _delay_WaitForControl("classname=#32770", "Recordings directory", "Edit1")
    ControlSetText ( WinGetHandle("classname=#32770", "Recordings directory"), "", "Edit1",  $ROOT_RECORDING_PATH & RecordingPath($folder_path) )
    
    _delay_WaitForControl("classname=#32770", "Recordings directory", "Button2")
    ControlClick ( WinGetHandle("classname=#32770", "Recordings directory"), "", "Button2" )
    
    _delay_WaitForControl("classname=#32770", "General", "Button8")
    ControlClick ( WinGetHandle("classname=#32770", "General"), "", "Button8" )
EndFunc

Func _close_Recording_Window_WMR11( $handle_recwnd )
    _delay_WaitForControl( $handle_recwnd, "", "Button1" )
    ControlClick ( $handle_recwnd, "", "Button1" )
    If _delay_WaitForControl("classname=#32770", "This will stop all current recordings", "Button1", 3500) then
        ControlClick ( WinGetHandle("classname=#32770", "This will stop all current recordings"), "", "Button1" )
    Endif
EndFunc

Func SearchWindowByTitle($WindowList, $TitleText)
    Local $i = 0

    For $i = 1 to $WindowList[0][0]
        If ( $WindowList[$i][0] == $TitleText ) then
            Return $WindowList[$i][1]
        Endif
    Next
    Return 0
EndFunc

Func WindowMakeActive( $handle )
    Local $_wnd_state = WinGetState($handle) 
    WinSetState( $handle, "", @SW_ENABLE )
    WinSetState( $handle, "", @SW_SHOW )
    WinSetState( $handle, "", @SW_RESTORE )
    WinActivate ( $handle )
    Return $_wnd_state
EndFunc

Func WindowRestoreState( $handle, $wnd_state )
    If BitAnd($wnd_state, 4) then
        WinSetState( $handle, "", @SW_ENABLE)
    Else
        WinSetState( $handle, "", @SW_DISABLE)
    Endif
    
    If BitAnd($wnd_state, 2) then
        WinSetState( $handle, "", @SW_SHOW)
    Else
        WinSetState( $handle, "", @SW_HIDE)
    Endif
    
    Select
        case BitAnd($wnd_state, 16)
            WinSetState( $handle, "", @SW_MINIMIZE )
        case BitAnd($wnd_state, 32)
            WinSetState( $handle, "", @SW_MAXIMIZE )
    EndSelect
EndFunc

;; An enhanced MouseClick that would do anything it can to click-that-button
Func MouseKick( $wnd_handle=0, $x="XPOS", $y="YPOS", $aio_MouseCoordMode=0, $mouse_button="primary", $clicks=1, $speed=0 )
    AutoItSetOption ( "MouseCoordMode", $aio_MouseCoordMode )
    Local $_app_state = WindowMakeActive ( $wnd_handle )
    If ( IsNumber($x) AND IsNumber($y) ) then
        MouseClick ( $mouse_button, $x, $y, $clicks, $speed )
    Else
        Local $pos = MouseGetPos()
        MouseClick ( $mouse_button, $pos[0], $pos[1], $clicks, $speed )
    Endif
    WindowRestoreState ( $wnd_handle, $_app_state )
EndFunc

Func TouchHttpCGI( $static_serverurl, $dynamic_dirurl, $static_fileurl, $dynamic_fileurl, $static_servparam, $local_path)
    Local $_url = $static_serverurl & $dynamic_dirurl & $static_fileurl & $dynamic_fileurl & $static_servparam
    DirCreate ( $local_path & "_stream_source\" )
    InetGet ( $_url, $local_path & "_stream_source\" & $static_fileurl & $dynamic_fileurl & ".asx" )
EndFunc

Func IsIntStr ( $str_value )
;; This function is a work around for IsInt()
;; Return value: True when string contains only digits
    Return ( ($str_value > 0) or ($str_value == 0) or ($str_value < 0) )
EndFunc

Func ReadMarker ( $marker_path )
    Local $file = FileOpen( $marker_path & "\_stream_source\download_marker.txt", 0)
    If ( $file == -1 ) Then
        Return "NULL"
    Endif

    Local $line = FileReadLine ( $file, 1 )
    FileClose ( $file )
    If (@error == 1) OR (Not IsIntStr($line) ) then
        Return "NULL"
    Else
        Return Int($line)
    Endif
EndFunc

Func WriteMarker ( $marker_path, $marker_value )
    Local $file = FileOpen( $marker_path & "\_stream_source\download_marker.txt", 2)
    If ( $file == -1 ) Then
        Return "NULL"
    Endif
    FileWriteLine ( $file, $marker_value )
    FileClose ( $file )
EndFunc

;;;;;;;;;;;;; DATA

Dim $StreamingSources[7]
;; StringFormat = "protocol://URI/static-name,TRAILING-ZEROS,FROM-COUNT,TO-COUNT,.extension"
$StreamingSources[0] = "mms://demo.domain.com/path/to_stream/FILEINITIAL-,2,1,27,.wmv"

;;;;;;;;;;;;; INITIALIZATION

AutoItSetOption( "WinTitleMatchMode", 4 )
AutoItSetOption( "MouseCoordMode", 0 )
AutoItSetOption( "TrayIconDebug", 1 )
Global $_wmr_winlist = WinList("classname=#32770")
Global Const $ROOT_RECORDING_PATH = "I:\place_to_store\videos\"

;;;;;;;;;;;;; START HELPER APPLICATIONS

;; So, what am I doing here ? 
;; If all checks for application parts return false: I'm assuming application is not launched.
;; If all checks for application parts return true: I'm assuming application is launched and active
;; If some parts return true and others say false: I'm assuming application is semi loaded, so lets reload it

If ( (SearchWindowByTitle( $_wmr_winlist, "" ) == 0) AND _
    (SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Windows Media" ) == 0) AND _
    (SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Recording Window" ) == 0) ) then
    ;; Good, no memory resistent copies of application, launch it
    run("C:\Program Files\WMR11\WMR11.exe")
Elseif ( (SearchWindowByTitle( $_wmr_winlist, "" ) <> 0) AND _
        (SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Windows Media" ) <> 0) AND _
        (SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Recording Window" ) <> 0) ) then
    ;; looks like the application is fully loaded, let it be
Else
    ;; If we got here that means part of the application is still in memory
    ;; Kill all available parts and then reload.
    WinKill( SearchWindowByTitle( $_wmr_winlist, "" ) )
    WinKill( SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Windows Media" ) )
    WinKill( SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Recording Window" ) )
    ProcessClose ( "WMR11.exe" )
    ProcessWaitClose("WMR11.exe")
    run("C:\Program Files\WMR11\WMR11.exe")
endif

;; Loop until splashscreen gone, which has the same classname and same text :(
_delay_WaitForControl("classname=#32770", "", "Edit2")

;; Second run of WinList() to include changes occured after HELPER APPLICATION logic
$_wmr_winlist = WinList("classname=#32770")

;;;;;;;;;;;;; RUN MAIN RECORDING LOOP

if WinWait("classname=#32770") then
    
    $handle_mainwnd = SearchWindowByTitle( $_wmr_winlist, "" )

    For $indx = 0 to UBound($StreamingSources)-1
        $_strmInfo = StringSplit ( $StreamingSources[$indx], "," )
        DirCreate ( $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) )
        
        ;; Do a quick marker check, maybe we can skip a few loops ;)
        $_marker_from = ReadMarker ( $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) )
        if ( $_marker_from == "NULL" ) then
            $_marker_from = Number($_strmInfo[3])
        Endif

        For $i = $_marker_from to Number($_strmInfo[4])             ;; download from [number] to [how many there are]...
            $_strformat = "%." & $_strmInfo[2] & "d" & $_strmInfo[5]
            $_waitdl_file = FileNameFromURI($_strmInfo[1]) & StringFormat($_strformat, $i)
            $_waitdl_file_pattern = FileNameFromURI($_strmInfo[1]) & StringFormat("%." & $_strmInfo[2] & "d*" & $_strmInfo[5],$i)

            _delay_WaitForControl($handle_mainwnd, "", "Edit2")
            ControlSetText ( $handle_mainwnd, "", "Edit2", $_waitdl_file )
            ControlSetText ( $handle_mainwnd, "", 321, $_strmInfo[1] & StringFormat($_strformat, $i) )
    
            ;; STATR: Folder change sequance for application
            MouseKick( $handle_mainwnd, 250, 50 )
            _change_Folder_WMR11( $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) ) 
            ;; END: Do folder change sequance

            ;; Fool remote server into thinking IE is "doing him"
            $_server_cgi_root = "http://demo.domain.com/path/to/video/STATIC?url/"
            TouchHttpCGI( $_server_cgi_root, RecordingPath($_strmInfo[1]) & "/", FileNameFromURI($_strmInfo[1]),_
                            StringFormat("%."&$_strmInfo[2]&"d",$i), "&mswmext=.asx",_
                            $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\")

            ;; Start recording (click the button)
            MouseKick( $handle_mainwnd, 45, 75 )
            $_waitdl_ret = WaitDownload( $handle_mainwnd, $_waitdl_file_pattern,  $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" )

            Select 
                case $_waitdl_ret == (-1)
                    ;; msgbox (1, "", "WaitDownload sayed -1 == application did nothing for Xms time")
                    ;; OK, wait a couple of min and try again will'ya ;)
                    $i = $i-1
                    sleep ( 30000 )

                case $_waitdl_ret == 0
                    ; Download finished 
                    WriteMarker ( $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]), $i+1 )
                    sleep ( 600000 )
                    $_ondisk_media_files = FileFindToArray( $_waitdl_file_pattern, $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" )          
                    If IsArray ( $_ondisk_media_files ) then
                        for $ifile = 1 to UBound($_ondisk_media_files)-1
                            FileMove( $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" & $_ondisk_media_files[$ifile], _
                                $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" & _nixNOW() & "_" & $_ondisk_media_files[$ifile] )
                        Next
                        FileMove( $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" & $_ondisk_media_files[0], _
                                $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" & $_waitdl_file )
                    Endif
                    
                case $_waitdl_ret == (-2)
                    ; A file in the requested download size has been identified on the hardisk
                    WriteMarker ( $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]), $i+1 )
                    sleep ( 30000 )
                    $_ondisk_media_files = FileFindToArray( $_waitdl_file_pattern, $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" )          
                    If IsArray ( $_ondisk_media_files ) then
                        for $ifile = 1 to UBound($_ondisk_media_files)-1
                            FileMove( $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" & $_ondisk_media_files[$ifile], _
                                $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" & _nixNOW() & "_" & $_ondisk_media_files[$ifile] )
                        Next
                        FileMove( $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" & $_ondisk_media_files[0], _
                                $ROOT_RECORDING_PATH & RecordingPath($_strmInfo[1]) & "\" & $_waitdl_file )
                    Endif

                case $_waitdl_ret == (-4)
                    ; msgbox (1, "", "WaitDownload sayed -4 == dude, your over your limits")
                    ; Fuck it, fuck him, fuck everyone. "If you don't want to be downloaded then I am surely not going to do it for you"
                    $_foo = "foo"

                case else
                    msgbox (1, "", "WaitDownload sayed " & $_waitdl_ret & "(wtf?)" )
            Endselect

            ;; Helper application logic: End recording session before starting new one
            _close_Recording_Window_WMR11( SearchWindowByTitle( $_wmr_winlist, "WM Recorder - Recording Window" ) )
        Next
    Next 
endif
Edited by Maxim Vexler
Link to comment
Share on other sites

  • 1 month later...
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...