Home
> e-languages, multimedia-recording, service-is-programming, sourcecode > How to build a digital recorder with GUI for free with Windows-Media-Encoder
How to build a digital recorder with GUI for free with Windows-Media-Encoder
- Merely a bit of systems integration. Context: An interpreting study program centered around a conference-interpreting lab that, in 2009, was still analog (tape-based) and could not be upgraded to digital, but each interpreter booth had unintegrated Windows PCs – an opportunity.
- Uses AutoIT and Windows-COM programming, as exemplified in Windows-media-encoder-SDK, against Windows-Media-Encoder.
- make sure that you have
- have all AutoIt packages referenced with #includes below;
- have the windows-media-encoder installed – the windows-media-encoder-SDK should not be needed , except for programming examples;
- make sure you adapt “PUTYOUROWN” to your own environment
- provide your own (equipment-specific) WME files for the Windows-Media-Encoder configuration.
- (While there exists an AutoIt brush for Alex Gorbatchev’s SyntaxHighlighter, WordPress.com does not seem to include it, hence the poor highlighting below:)
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Outfile=g:\myfiles\bureaucracy\proposals\interpreting\digitization\local_hacks\recording.au3\trprecord.exe #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Sample: How to build a digital recorder with GUI for free with Windows-Media-Encoder for an analog interpreting lab that cannot be digitized ; prerequisites: ; make sure you have all autoit packages referenced with #includes below ; make sure you have the windows-media-encoder enstalled - the windows-media-encoder-sdk should not be needed , except for programming examples ; make sure you adapt "PUTYOUROWN" to your own environment ; provide your own WME files ; sorry for the magic strings! ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $GW_HWNDNEXT $FORMAT_MESSAGE_FROM_SYSTEM $GW_CHILD T:\old\trp_l\lang\autoit\Include\Constants.au3(200): Global Const $GW_CHILD = 5 ; $GW_HWNDNEXT $FORMAT_MESSAGE_FROM_SYSTEM $GW_CHILD T:\old\trp_l\lang\autoit\Include\Constants.au3(200): Global Const $GW_CHILD = 5 ; $EM_LINEFROMCHAR etc EditConstants.au3 #include <Constants.au3> #include <GUIConstants.au3> #include <WindowsConstants.au3> ; for gui's #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <ProgressConstants.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <_CSVLib_V1.3.au3> ; #include <Array.au3> ; #include <Array2D.au3> $WS_CLIPSIBLINGS, $WS_OVERLAPPEDWINDOW, WS_VISIBLE: used before declaration, must be outdated #include <date.au3> #include <debug.au3> #include <File.au3> #include <GuiComboBox.au3> #include <GuiListBox.au3> #include <GuiListView.au3> #include <GuiTab.au3> #include <Hash.au3> #include <Screencapture.au3> #include <trpCombo.au3> ; not anymore inline #include <trpListClick.au3> #include <trpOCRTextCapture.au3> #include <utils_array.au3> #include <utils_csv.au3> #include <utils_file.au3> #include <utils_Hash.au3> #include <utils_window.au3> #include <ftp.au3> ; for stream #include <Misc.au3> ; singleton ;#include <PopupChecker.au3> ; #include <trpAuralog.au3> Opt("MustDeclareVars", 0) ; i cannot find where i set thinks to 1, but aat a certain development point autoit would not run w/o complaining about vars not being declaured, including in include files Opt("TrayIconDebug", 1) Opt("WinWaitDelay", 250) ; Alters how long a script should briefly pause after a successful window-related operation; default is250ms Opt("WinTitleMatchMode", 1) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase ; removed may 2008 Opt("RunErrorsFatal", 0) Global $thissingletonid = "trprecord" Global $thiswindowtitle = "TRPRecord" Global $debugtype = "debugconsolescreen"; "debugconsole" ; or run -> screenshots and debug out; consider "release" --> log ; _DebugSetup("debug") _ScreenCapture_SetBMPFormat(0) ; smallest, with default = 24bit, each 1280*1024 (seems to do only primary) is 3.5mb ; dolater: add cmdline: the program looks for params /admin and /video and loads the gui with buttons disabled and with video checked - there are prior solutions ; donot: options/ini: do you have to allow not to use default audio/video device? set the default device in the wme and edit it in there instead of the ini ; donot: logging - just store debug screenshots with names in the local temp, will get erased on restart ; beyond logging into a file for admin (debugging) (1 per student -> cannot be monitored by teacher), ; log for teacher onto a network folder which the instructor can monitor important errors like encoding start failed ; (not filecopy to instructors network folder, that is redundant, since log files are in the same folder) ; yes filecopy to student x: drive -> instructorr can tell students to clean up their x drives ; this functionality to write messages to filenames i devleoped already for auralog screenshots Global $g_eventerror = 0 ; to be checked to know if com error occurs. Must be reset after handling. global $oMyError Global $szDrive, $szDir, $szFName, $szExt Global $arrAutoitExe = _PathSplit(@AutoItExe, $szDrive, $szDir, $szFName, $szExt); Returns an array with 5 elements where 0 = original path, 1 = drive, 2 = directory, 3 = filename, 4 = extension Global $scriptfilewithexe = $arrAutoitExe[3] & $arrAutoitExe[4] ; autoit3.exe if <>@compiled Global $windowtitletrpRecord = "TRPRecord:Set Options, press Start to begin" Global $nowstring = StringRegExpReplace(_NowCalc(), "[\s\/\:]", "_") ; fill this here only for logfile, but later again when record button is pressed Global $networknamefile = "" Global $networkpathfile = "" ; can instead differentiate audio/video in backupRecording, using $ext Global $ext = "" Global $pathfilelog = FileNameEscape("rec" & "_" & $nowstring & "_" & @ComputerName & "_" & @UserName & "_" & ".log", @TempDir) ; wmeditor.exe is not in the path Global $wmeditorpath = "C:\Program Files\Windows Media Components\Encoder\wmeditor.exe" ; dolater: put in central ini Global $wmencexe = "wemenc.exe" Global $wmcmdvbspath = "C:\WMSDK\WMEncSDK9\samples\vb\wmcmd\Wmcmd.vbs" Global $webinterfacestring = "https://thomasplagwitz.com/2009/08/04/digitization-of-the-saville-analogue-conference-interpreting-recording-facility-booths-end-user/" ; "http://plagwitz1.spaces.live.com/blog/cns!4FA3329905D7E1CE!961.entry" Global $recordingstopstring = "stopRecordingAndPlay.exe" Global $ret = 0 Global $set = 0 ; just use TEMPdir=c:\temp ; just use @ComputerName =MORLIB--PCC6392 ; just use @USERNAME instead of $username =plagwitt ; just use @TempDir - $tempdir = "c:\temp"; todo: what if @TempDir dioes not point to c:\temp, but network Global $uncpathwritestudent = "PUTYOUROWN" ; "\\venus\homes\My Documents\My Music" ; todo: handle spaces ; not this, since can't probably be mapped under student account already "\\lgu.ac.uk\lgu$\multimedia student\mmedia\mmedia1\language_services\recordings" Global $usernameinstructor = "PUTYOUROWN"; "plagwitt" ; dolater: todo: move into network ini Global $passwordinstructor = "PUTYOUROWN" ; encrypted "7B5912DCA17955CECED6668C78303A0B" ; todo: 7A5D13D9A10555BCCED462FC7830, dolater:move into network ini Global $passworddecrypt = "record"; todo:ini: leave blank if you do not know how to encrypt your pwd with autoit; level was 1 Global $wmcmdpath = "C:\WMSDK\WMEncSDK9\samples\vb\wmcmd\Wmcmd.vbs" Global $uncpathsharewriteinstructoronly = "PUTYOUROWN" ; "\\lgu.ac.uk\lgu$\londonmet departments" ; old network backup destination for student recordings, replaced by k-drive; ; this worked for thp0136 (with filecopy to $driveletterkreplacementforstudentwrite returned from addinstructornetworkshares?) ; cannot replicate this anymore Global $dirsharewriteinstructoronly = "Humanities arts and languages (HAL)\Language_services\recordings" ; old network backup destination for student recordings, replaced by k-drive; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; done: @LogonDomain is lgu, which suffices - do students and instructors use the same domain? done: test with thp0136, has the same domain Global $domain = "lgu.ac.uk" Global $serverwriteinstructor = "PUTYOUROWN" ; "\\stushare_server" ; we need to disconnect form the entire server computer to be able to reconneec with different permissions Global $sharewriteinstructor = "PUTYOUROWN" ; "StuShare" Global $uncpathsharewriteinstructor = $serverwriteinstructor & "\" & $sharewriteinstructor ; when we reconnect wiht instrucoter permission, this share should receive a driveletter ; done: replace $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig by $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig Global $serverstudentreadconfig = "PUTYOUROWN" ; "\\lgu.ac.uk" ; we need to disconnect form the entire server computer to be able to reconneec with different permissions Global $sharestudentreadconfig = "PUTYOUROWN" ; "lgu$\multimedia student\mmedia" ; \\lgu.ac.uk\lgu$\multimedia student\mmedia Global $uncpathsharestudentreadconfig = $serverstudentreadconfig & "\" & $sharestudentreadconfig ; Global $dirsharestudentreadconfig = "PUTYOUROWN" ; "mmedia1\language_services\configuration" ; now on o:, was on k: "Humanities, Arts and Languages\Language_Services\configuration" ; done: have to put this on K:-uncpath, wmenc runs under student, student cannot read from j ; "\\lgu.ac.uk\lgu$\multimedia student\mmedia\mmedia1\language_services\configuration" ; wmenc.exe running under studentuser needs to be able to read config files; ; done: replace $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadmedia by $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadmedia Global $uncpathstudentreadmedia = "PUTYOUROWN" ; "\\stushare_server\StuShare\Humanities, Arts and Languages\Language_Services\media" ; studentuser can read Global $dirsharestudentreadmedia = "PUTYOUROWN"; "Humanities, Arts and Languages\Language_Services\media" Global $dirsharewriteinstructor = "PUTYOUROWN"; "Humanities, Arts and Languages\Language_Services\recordings" Global $uncpathwritemedia = $uncpathsharewriteinstructor & "\" & $dirsharewriteinstructor ; useful? we currently do not use unc but the driveletter ; done: replace $driveletterwriteinstructor by $driveletterkreplacementforstudentwrite Global $driveletterkreplacementforstudentwrite = ""; will be assigned in setupdrives() Global $driveletterkreplacementforstudentwritenetuse = "K:"; todo: hack for net use Global $driveletterreadconfig = ""; will be assigned in setupdrives() ; todo: build wme out of $driveletterreadconfig and trprecord ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; all the following .wme-files should be in the same network dir $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig - not neccessary anymore Global $wmefilename = "" ; ; will set by the differentiated following Global $wmefilenamerecordaudiolive = "recordaudiolive.wme" ; 64kbps,44khz,stereo,cbr (a default file archive profile)saving to c:\temp\recordaudio.wma - overwrite? Global $wmefilenamerecordvideolive = "recordvideolive.wme" Global $wmefilenamerecordaudiofile = "recordaudiofile.wme" Global $wmefilenamerecordvideofile = "recordvideofile.wme" ; indexing is required for all recordstop()ed files that are not (like audiofile, videofile) postprocessed ; if for indexing you reencode (to same as input) using wmenc.xe with .wme, you need to differentiate between audio, video as source Global $wmefilenamerecordaudioindexing = "recordaudioindexing.wme" Global $wmefilenamerecordvideoindexing = "recordvideoindexing.wme" ; streamudio() sample Global $fullpath, $name, $drv Global $Label_1 Global $Label_2 Global $input_1 Global $button2 Global $button1 Global $guiMsg Global $progbar Global $prioruser Global $wmencoderPID = 0 ; new approach from here using encoder-object.start/stop ; config files for audio-video and audio onlyrecording: edit in windows media encoder/ properties to make changes; assumes exists and have write permissions to "c:\temp" ;todo: either: refer to the drive letter or to the unc path? former should be more stable, but latter is in practice Global $strWMEFileVideoName = "trprecord_av.wme" Global $strWMEFileVideo ; can only be done after setupdrives = $driveletterreadconfig & "\" & $dirsharestudentreadconfig & "\" & $strWMEFileVideoName ; $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig & "\" & $strWMEFileVideoName ; "K:\Humanities, Arts and Languages\Language_Services\configuration\trprecord_av.wme" Global $strWMEFileAudioName = "trprecord_a.wme" Global $strWMEFileAudio ; can only be done after setupdrives = $driveletterreadconfig & "\" & $dirsharestudentreadconfig & "\" & $strWMEFileAudioName ; $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig & "\" & $strWMEFileAudioName ; "K:\Humanities, Arts and Languages\Language_Services\configuration\trprecord_a.wme" Global $objEncoder, $objIWMEncFile, $g_objEncoder, $g_ObjEvent, $g_objIWMEncFile ; done: rather than hardcoding read the tempfilename from the encoder-object.localfilename, which sets it according to load(wmefile) Global $tempfilename = "" Global $wmeoutputbasefilename = "trprecord" ; e.g. trprecord within c:\temp\trprecord.wma Global $wmeoutputbasefilename = "c:\temp" main() ;test() Func test() EndFunc ;==>test Func main() ; MsgBox(0, "test", "test") ; allow only one instance of the program to run If _Singleton($thissingletonid, 1) == 0 Then myDebugOut(@ScriptLineNumber, "An occurence of trprecord is already running") ; following test seems a bit superfluous, but just to make sure: If WinExists($thiswindowtitle) Then ; does work, when case-sensitivity is observed WinActivate($thiswindowtitle) ; remind the user of the running instance by showing it EndIf ; test Exit myDebugOut(@ScriptLineNumber, "singleton @error=" & @error) ; ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : Exit = ' & Exit & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console EndIf ; Msgbox(0,"OK","the first occurence of trprecord is running") killpriorInstance() ; before building a new gui ; was: test:non-interactive setupdrives() ; create an encoder-object here for the entire duration of the program $objEncoder = ObjCreate("WMEncEng.WMEncoder") ; this does not show up in the tasklist $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") ; must be called only once (and the objcreate happens only once, with the gui-creation) ; release: $g_ObjEvent=ObjEvent("AutoIt.Error","nothing"); Equal to VBscript's On Error Resume Next If Not IsObj($objEncoder) Then $set = GUICtrlSetData($guiMsg, "Cannot create encoder, try restarting computer." & @CRLF & "If app still fails, reinstall windwos media encoder with sdk.") myDebugOut(@ScriptLineNumber, "Cannot create encoder") Else ; $objEncoder.Start ; EndIf ; works MsgBox(0, "WMEncEng.WMEncoder", $ret) ; wmeobjects($objEncoder,$strWMEFileAudio) guioptions() ; obsolete removeInstructorNetworkShares() trpCleanup() EndFunc ;==>main Func setupdrives() addStudentReadconfigNetworkshares() ; wme cannot reside on k:, but o: can also be read by student, but wmencoder needs a path deleteStudentShare() ; before we reconnect with different permissions, we need to close all connections with current permissions (unless we were given the ip of the server) ; obsolete disconnectserverwriteinstructor() ; how can this be done? hardly drivemapdel is enough? net use? are local admin credentials necessary? ; determine: do this here? $driveletterkreplacementforstudentwrite = addInstructorNetworkshares() ; returns a driveletter $strWMEFileAudio = $driveletterreadconfig & "\" & $dirsharestudentreadconfig & "\" & $strWMEFileAudioName ; $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig & "\" & $strWMEFileAudioName ; "K:\Humanities, Arts and Languages\Language_Services\configuration\trprecord_a.wme" $strWMEFileVideo = $driveletterreadconfig & "\" & $dirsharestudentreadconfig & "\" & $strWMEFileVideoName ; $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig & "\" & $strWMEFileVideoName ; "K:\Humanities, Arts and Languages\Language_Services\configuration\trprecord_av.wme" EndFunc ;==>setupdrives Func recordstart(ByRef $g_objEncoder, $g_strWMEFile = "") ; this works in principle, with an existing wme-session file, ; done: unlike the gui-wmencoder, the object will overwrite an existing output filename, without need for interaction, even if it is open in wmplayer ; $OEvent=ObjEvent("AutoIt.Error","nothing"); Equal to VBscript's On Error Resume Next ;If a WME file is provided, load the encoding configuration from this WME file. If $g_strWMEFile <> "" Then If Not (FileExists($g_strWMEFile)) Then $set = GUICtrlSetData($guiMsg, "Cannot find config file " & $g_strWMEFile & ", will stop.") myDebugOut(@ScriptLineNumber, "Cannot find wme config file" ) Else ; recordstart($objEncoder, $g_strWMEFile) ; test only, rather stop interactively by passing byref $objEncoder to recordstop ; Sleep(5000) ; recordstop($objEncoder) ; EndIf If IsObj($g_objEncoder) Then $set = GUICtrlSetData($guiMsg, "Now preparing recording...") ; $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") ; done: crashes when called repeatedly = when recordstart is called repeatedly -> moved to after objcreate(encoder) ; Load enocder session from a WME file myDebugOut(@ScriptLineNumber, "attempting to load encoder profile $g_strWMEFile=" & $g_strWMEFile) $g_objEncoder.Load($g_strWMEFile) ; ( g_objFileSystem.GetAbsolutePathName( g_strWMEFile ) ) ; todo: on error returns 0x8007000E Memory cannot be allocated. - how can i sue this for debuging with ObjEvent ; if you try over-load [what? the output filename?], error: "the requested action with this object has failed."" $set = GUICtrlSetData($guiMsg, "One moment, please...") Sleep(2000) ; the mgb-36 computers are so slow, especially at startup (mcafee?) that we seem to need to go slower than 1000 ; todo: can you shave sth off? rather give the user feedback when recording started ; donot: fiddle with WMEncoder.PrepareToEncode , SynchronizeOperation = false $tempfilename = $g_objEncoder.File.LocalFileName ; not anymore: The requested action with this object has failed.: $g_objEncoder.start $set = GUICtrlSetData($guiMsg, "Now recording to localfilename:" & $tempfilename) myDebugOut(@ScriptLineNumber, "recording to localfilename:" & $tempfilename) Else $set = GUICtrlSetData($guiMsg, "Cannot find encoder, try restarting the application.") myDebugOut(@ScriptLineNumber, "error:encoder not isobject:" & $set) EndIf EndIf Else $set = GUICtrlSetData($guiMsg, "No configuration file specified, will stop. Try restarting the application.") myDebugOut(@ScriptLineNumber, "No wme configuration file specified" ) EndIf EndFunc ;==>recordstart Func recordstop(ByRef $g_objEncoder) ; done: interactively stop (without presetting an encoding duration) $g_objEncoder.stop ; This method does not return a value. ; tested: works myDebugOut(@ScriptLineNumber, "is the encoder stopped? how to tell.. ") ; todo: the network file cannot be played, but the tempfile can, what gives? ; is this cause=d by a mere encoder.stop? does not make sense, should be caused by copy ; is there another method short of destroy encoder to flush the file? ; todo: is it not also possible to rename the tempfile, or will another encoder.start otherwise add to it? but encoder.stop is more than encoder.pause ; donot: destroy the object - only destroy the object when gui/window/app is closed ; this cannot work with byref $g_objEncoder = 0 ; todo: i would need to know when the objEncoder is finished = safe to start work on its outputfile ; test: can i override the filename -> no ; Retrieve an IWMEncFile object and override the name of the archive file specified in the predefined configuration. ; $objIWMEncFile = ObjCreate("WMEncEng.WMEncoder.File") ; fails to create an object $objIWMEncFile = ObjCreate($objEncoder.File) ; müssen wir doch mit dem existierenden object arbeiten ; fails to create an object $objIWMEncFile = ObjCreate("WMEncEng.WMEncoder.File") ; müssen wir doch nicht mit dem existierenden object arbeiten ; $g_objIWMEncFile = $g_objEncoder.File ; this creates an object ; $ret = IsObj($g_objIWMEncFile) ; MsgBox(0,"WMEncEng.WMEncoder.File",$ret) ; File = Encoder.File; ; File.LocalFileName = "C:\\file_name.wmv"; ; $g_objIWMEncFile.LocalFileName = "C:\\tmp\\file_name.wmv"; error: Variable must be of type "Object" even though but ObjCreate did not error ; $objEncoder.File = $objIWMEncFile ;test:andersrum ; $g_objEncoder.start ; Sleep(15000) ; $g_objEncoder.stop EndFunc ;==>recordstop Func backupRecording() ; try to read ; todo: create source file path $ret = FileExists($tempfilename) If $ret Then If (StringRight($tempfilename, 4) = ".wma") Then; audio $ext = ".wma" ; handle a wma file ElseIf (StringRight($tempfilename, 4) = ".wmv") Then $ext = ".wmv";handle a wmv file Else ;error $set = GUICtrlSetData($guiMsg, "Not a legal temp file, cannot determine if audio or video.") myDebugOut(@ScriptLineNumber, "$set=" & $set) EndIf ; donot: leave it to the student to make manual backup copies in personal network home ; make instructor permanent copy of audio file ; done: create target file name from computername & username & datetime & ext ; done: create target file path $networknamefile = "trprecord" & "_" & $nowstring & "_" & @ComputerName & "_" & @UserName & $ext myDebugOut(@ScriptLineNumber, "$networknamefile is: " & $networknamefile) $networkpathfile = FileNameEscape($networknamefile, $driveletterkreplacementforstudentwrite & "\" & $dirsharewriteinstructor); YYYY/MM/DD HH:MM:SS myDebugOut(@ScriptLineNumber, "$networkpathfile is: " & $networkpathfile) ; todo: impersonate ; todo: copy $ret = FileCopy($tempfilename, $networkpathfile, 9) ; FileCopy ( "source", "dest" [, flag] ) ; todo: handle exceptions If ($ret == 0) Then myDebugOut(@ScriptLineNumber, "failed to filecopy: " & $networkpathfile) ; todo: this does not $ret 0, but the networkfile is not full size and does not have the complete audio even when it plays in wmp - is the recorded file closed? $set = GUICtrlSetData($guiMsg, "Failed to save to network, make sure you save your recording : " & $tempfilename) myDebugOut(@ScriptLineNumber, "$set=" & $set) Else $set = GUICtrlSetData($guiMsg, "Saved to network: " & $networknamefile) myDebugOut(@ScriptLineNumber, "$set=" & $set) EndIf Else ; todo: what to try if not fileexists $set = GUICtrlSetData($guiMsg, "tmp recording " & $tempfilename & ": does not exist, cannot save to network.") myDebugOut(@ScriptLineNumber, "$set=" & $set) EndIf ; todo: return 0 if error, 1 if success Return $ret EndFunc ;==>backupRecording Func killpriorInstance() $wmencoderPID = ProcessExists("wmencoder.exe") If $wmencoderPID <> 0 Then $prioruser = _ProcessGetOwner($wmencoderPID) If $prioruser <> @UserName Then ; is owner of wmencoder = currentuser than taskkill ; myDebugOut(@ScriptLineNumber, "prior $wmencoderPID ="& $wmencoderPID & ", $prioruser = " & $prioruser & ", @Username =" & @Username) $ret = MsgBox(1, "Error", "Looks like " & $prioruser & " should stop their trprecord on this computer first. Try again afterwards, I will exit now.") Exit Else ; if priorinstance belongs to @username, just kill it If WinExists($windowtitletrpRecord, "") Then WinKill($windowtitletrpRecord) ; always returns1 ; todo: killing the prior script instance is not enough - the instance may have spawned a wmencoder from the cmdline (since we do not use encoder objects here which would presumably be killed with the creating script) ; we need to kill any (todo: w/o warning to user?) wmencoder.exe process ; determine: which privileges are needed to execute taskkill? tested: a non-admin can use taskkill to kill their own tasks ; test: an admin or system account (teacher-> synchroneyes) should also be able to taskkill other admin and student task $ret = RunWait('taskkill /F /fi "imagename eq wmencoder*" /im *') ; return 0 seems good, sometimes? ; determine: do we need to kill other spawned processes like wmeditor (indexing)? or rather give them time to finish, and the calling script to copy the resulting audiofile EndIf Else ; no wmencoder process, nothing to kill EndIf EndFunc ;==>killpriorInstance Func guioptions() Opt("GUICoordMode", 1) ; 1 = absolute coordinates (default) still relative to the dialog box. 0 = relative position to the start of the last control (upper left corner). ; GUICreate ( "title" [, width [, height [, left [, top [, style [, exStyle [, parent]]]]]]] ) GUICreate($windowtitletrpRecord, 800, 180) GUISetHelp(@ProgramFilesDir & "\Internet Explorer\iexplore.exe http://plagwitz1.spaces.live.com"); todo: add the page to the actual blog entry Dim $msg ; which the user sends through the gui - essentially that he is done updating the controls ; Create the controls ; SET controls by using variables already read into from ini ; groups represent the sections of the ini ; A group control is the thin line you see around controls (usually only Radio button) that visually groups them together. ; If you want to have multiple groups without the visible line then you must use GUIStartGroup() to group your Radio buttons. ; horizontal ; GUICtrlCreateGroup ( "text", left, top [, width [, height [, style [, exStyle]]]] ) Dim $actiontyperecordingvideolivestatus = 0 Dim $actiontyperecordingaudioliveStatus = 1 Dim $actiontyperecordingaudiofileStatus = 0 Dim $actiontyperecordingvideofileStatus = 0 Dim $group_action = GUICtrlCreateGroup("Action", 10, 5, 780, 160); creategroup seems just a canvas in the gui GUIStartGroup() Dim $actiontyperecordingaudioliveCtrl = GUICtrlCreateRadio("Audio Live", 20, 20, 80, 15) Dim $actiontyperecordingvideoliveCtrl = GUICtrlCreateRadio("Video Live", 20, 50, 80, 15) Dim $actiontyperecordingaudiofileCtrl = GUICtrlCreateRadio("Audio with File,Path:", 20, 80, 110, 15) Dim $actiontyperecordingvideofileCtrl = GUICtrlCreateRadio("Audio w/ Video File,Path:", 20, 110, 140, 15) GUICtrlSetState($actiontyperecordingvideoliveCtrl, $actiontyperecordingvideolivestatus) GUICtrlSetState($actiontyperecordingaudioliveCtrl, $actiontyperecordingaudioliveStatus) GUICtrlSetState($actiontyperecordingaudiofileCtrl, $actiontyperecordingaudiofileStatus) GUICtrlSetState($actiontyperecordingvideofileCtrl, $actiontyperecordingvideofileStatus) ; todo: enable this if $actiontyperecordingaudiofile chosen Dim $inputAudiofilepath = $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig ; dim $audiofilelabelctrl = GUICtrlcreateLabel( "File with Audio" , 300, 180, 280,15) Dim $inputAudiofilepathCtrl = GUICtrlCreateInput($inputAudiofilepath, 160, 80, 580, 15) Dim $inputvideofilepath = $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig ; dim $audiovideolabelctrl = GUICtrlcreateLabel( "Video File with Audio" , 300, 210, 280,15) Dim $inputvideofilepathCtrl = GUICtrlCreateInput($inputAudiofilepath, 160, 110, 580, 15) Dim $button_start = GUICtrlCreateButton("&Start", 130, 20, 50, 50) Dim $button_stop = GUICtrlCreateButton("Sto&p", 190, 20, 50, 50) Dim $button_play = GUICtrlCreateButton("Play", 250, 20, 50, 50) ; todo: fails: Dim $button_play = GUICtrlCreateButton("Play" & @CRLF & " &Last", 250, 20, 50, 50, $BS_MULTILINE) Dim $button_open = GUICtrlCreateButton("&Open" & @CRLF & "Folder", 310, 20, 50, 50, $BS_MULTILINE) ; todo:fails ; Dim $statuslabelcontrol GUICtrlcreateLabel( "For trpRecording starting, Choose Action and press Start" , 300, 180, 280,15) ;global $guiMsg = GUICtrlCreateLabel("Look here for important messages. Press F1 for help.", 360, 20, 450, 50) ; use with GUICtrlSetData ($guimsg, "my message") GUICtrlSetColor($guiMsg, 0xff0000) ; Red GUICtrlSetState($button_start, $GUI_FOCUS + $GUI_DEFBUTTON) GUICtrlSetState($button_stop, $GUI_DISABLE) GUICtrlSetState($button_play, $GUI_DISABLE) GUICtrlSetState($actiontyperecordingaudiofileCtrl, $GUI_DISABLE) GUICtrlSetState($actiontyperecordingvideofileCtrl, $GUI_DISABLE) GUICtrlSetState($inputAudiofilepathCtrl, $GUI_DISABLE) GUICtrlSetState($inputvideofilepathCtrl, $GUI_DISABLE) GUISetState() While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE ; todo: here also? ; donot: destroy the encoder object - only destroy the object when gui/window/app is closed $g_objEncoder = 0 trpCleanup(); could do ExitLoop, but probably better to exit ; donot: cannot happen, $actiontyperecordingaudiofileCtrl disabled, action not implemented Case $msg = $actiontyperecordingaudiofileCtrl ; todo: how to check for radio button $actiontyperecordingaudiofile selected? $set = GUICtrlSetData($guiMsg, "") myDebugOut(@ScriptLineNumber, "$set=" & $set) ; todo: enable $inputAudiofilepathCtrl GUICtrlSetState($inputAudiofilepathCtrl, $GUI_ENABLE) ; todo: disable $inputAudiofilepathCtrl GUICtrlSetState($inputvideofilepathCtrl, $GUI_DISABLE) $actiontyperecordingvideofileStatus = 0 $actiontyperecordingvideolivestatus = 0 $actiontyperecordingaudioliveStatus = 0 $actiontyperecordingaudiofileStatus = 1 ; donot: cannot happen, $actiontyperecordingvideofileCtrl disabled, action not implemented Case $msg = $actiontyperecordingvideofileCtrl ; todo: how to check for radio button $actiontyperecordingaudiofile selected? $set = GUICtrlSetData($guiMsg, "") myDebugOut(@ScriptLineNumber, "$set=" & $set) GUICtrlSetState($inputvideofilepathCtrl, $GUI_ENABLE) ; todo: disable $inputAudiofilepathCtrl GUICtrlSetState($inputAudiofilepathCtrl, $GUI_DISABLE) $actiontyperecordingvideofileStatus = 1 $actiontyperecordingvideolivestatus = 0 $actiontyperecordingaudioliveStatus = 0 $actiontyperecordingaudiofileStatus = 0 Case $msg = $actiontyperecordingvideoliveCtrl ; todo: how to check for radio button $actiontyperecordingvideofile selected? $set = GUICtrlSetData($guiMsg, "") myDebugOut(@ScriptLineNumber, "clerared gui:" & $set) ; todo: disable $inputvideofilepathCtrl GUICtrlSetState($inputvideofilepathCtrl, $GUI_DISABLE) ; todo: disable $inputAudiofilepathCtrl GUICtrlSetState($inputAudiofilepathCtrl, $GUI_DISABLE) $actiontyperecordingvideofileStatus = 0 $actiontyperecordingvideolivestatus = 1 $actiontyperecordingaudioliveStatus = 0 $actiontyperecordingaudiofileStatus = 0 Case $msg = $actiontyperecordingaudioliveCtrl ; todo: how to check for radio button $actiontyperecordingaudiofile selected? $set = GUICtrlSetData($guiMsg, "") myDebugOut(@ScriptLineNumber, "$set=" & $set) ; todo: disable $inputAudiofilepathCtrl ; was sollte das? ConsoleWrite('@@ Debug(' & @ScriptLineNumber & ') : todo: = ' & todo: & @crlf & '>Error code: ' & @error & @crlf) ;### Debug Console GUICtrlSetState($inputAudiofilepathCtrl, $GUI_DISABLE) ; todo: disable $inputAudiofilepathCtrl GUICtrlSetState($inputAudiofilepathCtrl, $GUI_DISABLE) $actiontyperecordingvideolivestatus = 0 $actiontyperecordingaudioliveStatus = 1 $actiontyperecordingaudiofileStatus = 0 Case $msg = $button_start GUICtrlSetState($button_start, $GUI_DISABLE) GUICtrlSetState($button_stop, $GUI_ENABLE) $set = GUICtrlSetData($guiMsg, "Please wait...") myDebugOut(@ScriptLineNumber, "asking to wait=" & $set) If $actiontyperecordingaudiofileStatus Then ; dolater: not implemented If Not FileExists($inputAudiofilepath) Then MsgBox(0, "Error", "Enter a valid file name!") Else MsgBox(0, "Error", "Not implemented yet!") ; todo: set param, like this recordingstart($actiontyperecording = "audiofile", $inputAudiofilepath) EndIf ElseIf $actiontyperecordingvideolivestatus Then ; todo: set param, like this recordingstart($actiontyperecording = "videolive") ; $ret = recordingstart("videolive") ; old approac $ret = recordingstart("videolive") ; new approach with encoder-object ; done: capture datetime for file-postprocessing $nowstring = StringRegExpReplace(_NowCalc(), "[\s\/\:]", "_") ; done: does now get written, since no illegal chars get passed anymore paassed filenameescape myDebugOut(@ScriptLineNumber, $nowstring & ": trying to encode with $strWMEFileVideo=" & $strWMEFileVideo) myDebugOut(@ScriptLineNumber, "calling recordstart to encode with strWMEFileVideo=" & $strWMEFileVideo) $ret = recordstart($objEncoder, $strWMEFileVideo) ElseIf $actiontyperecordingaudioliveStatus Then ; $ret = recordingstart("audiolive") ; old approach $ret = recordingstart("audiolive") ;new approach encoder-object ; done: capture datetime for file-postprocessing $nowstring = StringRegExpReplace(_NowCalc(), "[\s\/\:]", "_") myDebugOut(@ScriptLineNumber, "calling recordstart to encode with $strWMEFileAudio=" & $strWMEFileAudio) $ret = recordstart($objEncoder, $strWMEFileAudio) ElseIf $actiontyperecordingvideofileStatus Then ; dolater: not implemented If Not FileExists($inputvideofilepath) Then MsgBox(0, "Error", "Enter a valid file name!") Else ; todo: set param, like this recordingstart($actiontyperecording = "videofile") MsgBox(0, "Error", "Not implemented yet!") EndIf EndIf Case $msg = $button_stop GUICtrlSetState($button_stop, $GUI_DISABLE) $set = GUICtrlSetData($guiMsg, "Please wait...") ; GUICtrlSetData($guiMsg, "Now recording to localfilename:" & $tempfilename) myDebugOut(@ScriptLineNumber, "$set=" & $set) ; not together, make a separate play button; $ret = recordingstopandplay() ; donot: (rather use encoder-object) differentiate whether indedexing or postprocessing required and whether to index audio or video ; new approach using encoder-object $ret = recordstop($objEncoder) ; todo: backup file to network, using impersonation Sleep(3000) ; half-done: the backuprecording is not complete when you do not give the enco der time to finish its saving after stop ; todo: is sleep(2000) enough time for large video files? maybe, filecopy comes later, i do not thinkg the encoder flushes all from memory when stopped $ret = backupRecording() GUICtrlSetState($button_start, $GUI_ENABLE) ; enable record again, the object-encoder has been stopped ; done: enable "play last"button GUICtrlSetState($button_play, $GUI_ENABLE) If Not ($ret == 0) Then $set = GUICtrlSetData($guiMsg, "Finished. Play your recording now or open folder to work with it.") myDebugOut(@ScriptLineNumber, "$set=" & $set) Else $set = GUICtrlSetData($guiMsg, "There was a problem saving your file to the network. You should save the local copy manually from " & @TempDir); todo myDebugOut(@ScriptLineNumber, "$set=" & $set) EndIf Case $msg = $button_play ; todo: this does not seem to do anything, not even guictrlsetdata $set = GUICtrlSetData($guiMsg, "Please wait...") myDebugOut(@ScriptLineNumber, "$set=" & $set) ; GUICtrlSetState($button_play, $GUI_DISABLE); donot: you do not know when the player has been close ; not together, make a separate play button; $ret = recordingstopandplay() ; donot: (rather use encoder-object) differentiate whether indexing or postprocessing required and whether to index audio or video ; new approach using encoder-object ; todo: change to proper variable names $networkpath & $currentfilename If FileExists($tempfilename) Then ; todo: i want to open thefile not with the default player which might be vlc, but with wmplayer myDebugOut(@ScriptLineNumber, "$tempfilename exists") ; this is reached $set = GUICtrlSetData($guiMsg, "Playing last recording from local temp recording.") myDebugOut(@ScriptLineNumber, "$set=" & $set) $ret = ShellExecute($tempfilename, "", @TempDir, "open") ; i do not think guimsg will be meaningful ElseIf FileExists($networkpathfile) Then ; fails ElseIf FileExists($driveletterkreplacementforstudentwrite & "\" & $dirsharewriteinstructor & "\" & $networknamefile) Then ;fails $ret = Run($driveletterkreplacementforstudentwrite & "\" & $dirsharewriteinstructor & "\" & $networknamefile, @TempDir, @SW_HIDE, 8) ; i do not think guimsg will be meaningful myDebugOut(@ScriptLineNumber, "$networkpathfile exists") $ret = ShellExecute($networkpathfile, "", @TempDir, "open") ; $set = GUICtrlSetData($guiMsg, "ATTENTION: no local copy") ; todo: & @CRLF & ", instead playing saved file from network.") myDebugOut(@ScriptLineNumber, "$set=" & $set) Else $set = GUICtrlSetData($guiMsg, "ERROR: last recording not found: " & @CRLF & $networknamefile & " or " & $tempfilename) myDebugOut(@ScriptLineNumber, "$set=" & $set) EndIf Case $msg = $button_open $set = GUICtrlSetData($guiMsg, "Please wait...") myDebugOut(@ScriptLineNumber, "$set=" & $set) ; GUICtrlSetState($button_stop, $GUI_DISABLE) ; donot: cannot check whether explore window has been closed, need not, if run open folder reissued, old on will be activatd ; not together, make a separate play button; $ret = recordingstopandplay() ; donot: (rathe use encoder-object) differentiate whether indedexing or postprocessing required and whether to index audio or video ; new approach using encoder-object ; todo: what is the proper variable names $ret = ShellExecute($driveletterkreplacementforstudentwrite & "\" & $dirsharewriteinstructor, "", @TempDir, "open") ; i do not think guimsg will be meaningful ; todo: enable "play last"button GUICtrlSetState($button_start, $GUI_ENABLE) GUICtrlSetState($button_play, $GUI_ENABLE) $set = GUICtrlSetData($guiMsg, "Done...") myDebugOut(@ScriptLineNumber, "$set=" & $set) Case Else ; ExitLoop rubbish, this will lead to an exit EndSelect WEnd ; todo: here? ; donot: destroy the encoder object - only destroy the object when gui/window/app is closed $g_objEncoder = 0 GUIDelete() EndFunc ;==>guioptions Func recordingstart($actiontyperecording = "audiolive", $inputAudiofilepath = "") Dim $arrinputAudiofilepath If $actiontyperecording = "audiolive" Then $wmefilename = $wmefilenamerecordaudiolive ElseIf $actiontyperecording = "videolive" Then $wmefilename = $wmefilenamerecordvideolive ; todo: this uses the default video source for live input - what ever shows there through the crestron, interpreting student or interpreter ElseIf $actiontyperecording = "audiofile" Then ; dolater: file - you cannot omit or override ion the cmdline filesnames in a wme ; - so either work with the cmdline input/output and not with wme ; or (if you need the wme for params that the cmdline cannot have, like timestretch), work with renaming files before inputting/after outputting to wme $wmefilename = $wmefilenamerecordaudiofile ;recordaudiofile.wme ; dolater: me needs to point to the defaultfile source.ext ; dolater: for file, the duration needs to be read from the file and the $wmefilename duration overwritten on the cmdline - is this possible? ; wmcmd.vbs says [-duration] <seconds> Amount of time in seconds to encode. Use when sourcing from devices.- ok with files? ; dolater: rip the audio (also get the duration - needs to be done first) with wemenc:!! ; dolater: how will you also play the file to the student? run(), opening with the default player ; dolater: is it not a restriction that wme can not do multi-channel ; donot: copy the file to a local temp location to avoid concurrency issues and with a generic name equal the the name p filesource hardcoded in $wmefilenamerecord = "recordaudiofile.wme" $ret = FileCopy2LocalTemp($arrinputAudiofilepath) If $ret = 0 Or @error Then ; dolater: making local copy failed EndIf ; we do not need to know whether audio or video, wmencoder can use both as audio source $inputAudiofilepathnameext = ; get file extension ;$ret = FileCopy($inputAudiofilepath, @tempdir & "\"& $inputAudiofilepathname ) ; would need to check whether copy is same as original ; dolater: audiofile (&videofile, audio only): ; wme out of the box does not allow combine audio channels (of pre-existing file and live recording) ; so you need to open the file (with the defaultapp) ; wmenc:captureaudiomonowav.wme: record the live student input, ; save the recording as MONO +WAV ; -> left.wav ; wmenc:rippaudiomonowav.wme rips from the pre-existing file the audio as MONO +WAV (you could use a video directly, but only if it is an WMV->AVI with mono audio) ; -> right.wav ; WavAviMux.exe can combine 2? mono (->monotize) wav(-> unpack! up to 2gb) channels (including from avi, w/o video, w/o 2gb limit) ; -> stereowav.avi: To wrap a stereo file with no video- >: wavavimux -o stereowav.avi -iwav 2 left.wav right.wav -mask 3 ; wmeenc:stereowav2wma.wme can compress avi:audio -> mp3 or wma: stereowav.avi -> [regular filename].wma ElseIf $actiontyperecording = "videofile" Then $wmefilename = $wmefilenamerecordaudiofile ;recordvideofile.wme ; dolater: wme needs to point to the defaultfile source.ext ; dolater: for file, the duration needs to be read from the file and the $wmefilename duration overwritten on the cmdline - is this possible? ; wmcmd.vbs says [-duration] <seconds> Amount of time in seconds to encode. Use when sourcing from devices.- ok with files? ; optional: videofile, with video - $actiontyperecordingavideofileStatus ; videofile optional can also do: ; wmenc:rippvideoavi.wme rips from the pre-existing file the audio as MONO +WAV (you could use a video directly, but only if it is an WMV->AVI with mono audio) ; WavAviMux.exe can combine 2? mono (->monotize) wav(-> unpack! up to 2gb) channels (including from avi, w/o video, w/o 2gb limit) ; To wrap a stereo file with video- >: wavavimux -iavi [input AVI file name] -o videostereowav.avi -iwav 2 left.wav right.wav -mask 3 ; the following indexing postprocessing actions are not needed, if we use encoderobject.stop instead of taskkill ; the following actions are internal (to recordingstopandplay) and not visible in the GUI ElseIf $actiontyperecording = "audioindex" Then ; there is not control for indexing in the gui, it is chose indirectly through button stop $wmefilename = $wmefilenamerecordaudioindexing ElseIf $actiontyperecording = "videoindex" Then ; there is not control for indexing in the gui, it is chose indirectly through button stop $wmefilename = $wmefilenamerecordaudioindexing EndIf ; IDENTIFY THE WMENC PROCESS ;this should check for a wmencoder process initated by admin - a remote controlled version of this script - and exit if there is one ; this should also check for another wemencoder process by current user - maybe user clicked twice, return message to "first stop prior recording session", then If ProcessExists($wmencexe) Then ; who is the owner of the prior wmenc.exe? "user name"of "image name" $strUser = _ProcessGetOwner($wmencexe); todo:requires wmi , does wmi require admin rights? If @error Then ; we cannot determine the user to the process -> play it safe $ret = MsgBox(0, "Error", "First stop current recording session, or talk to admin.") trpCleanup() EndIf ; error If $strUser = @UserName Then ; the process belongs to the current user -> guide her $ret = MsgBox(0, "Error", "First stop your current recording session, by running " & $recordingstopstring) ; browse to web-interface for $recordingstopstring ShellExecute($webinterfacestring) trpCleanup() Else ; todo: is this automatically the admin? what about logging in as different user? $ret = MsgBox(0, "Error", "Smile, you are already being recorded.") Exit ; nor sute i can trpCleanup() here EndIf Else ; no other wmenc process -> proceed normally EndIf ; processexists ; donot: provide an indicator that recording is running ; $ret = ; done: have 2 buttons start/stop and start gets greyed if pressed or, - indicator style only, no gui - , with stop, if admin started from the cmdline ; the trprecord.exe needs to remains running after start on client - whethe started from client or server ; another instance checks not only for wmeenc but also for filename.exe and stops a prior filename.exe also ; should this be autoit ; - then $recordingstopstring needs not only stop wmenc.exe, but also record.exe ; then indicator should contain a link to stop recording, which ends record.exe after launching $recordingstopstring ; or a visible wmcmd.vbs window is enough? ; that however could be stopped by user (could it if launched remotely by admin? but then not visible? psexec not, synchroneyes yes? ) manually also, not tragic while we have no remote control, but once we do, bad EndFunc ;==>recordingstart Func recordingstopandplay() ; todo: destroy gui ; todo: what is a good way to pass the filename to the $recordingstopstring ; mostrecent wma in tempdir? ; there might be more than one unindexed wma (if computer logged off? does this not clean the tempdir?) ; overwrite path to create time-specific (that does not overwrite) local file ; done: do not create file on network (can be down) or local (would probably be lost on restart - copy to network at end) ; find local file ; run ; donot: check homedir ; donot:copy local file to homedir addInstructorNetworkshares() ; identify a prior GUI and stop it (not myself) If ProcessExists($scriptfilewithexe) Then ; it is Not me ; todo EndIf ; IDENTIFY THE WMENC PROCESS ;this should check for a wmencoder process initiated by admin/instructor-user/synchroneyes-user - a remote controlled version of this script - and exit if there is one ; this should also check for another wmencoder process by current user - maybe user clicked twice, return message to "first stop prior recording session", then If ProcessExists($wmencexe) Then ; who is the owner of the prior wmenc.exe? "user name"of "image name" $strUser = _ProcessGetOwner($wmencexe); todo:requires wmi , does wmi require admin rights? If @error Then $ret = MsgBox(0, "Error", "First stop current recording session, or talk to admin.") Exit ; nor sure i can trpCleanup() here EndIf ; error If $strUser = @UserName Then $ret = MsgBox(0, "Error", "First stop your current recording session, by running " & $recordingstopstring) ; browse to web-interface for $recordingstopstring ShellExecute($webinterfacestring) Exit Else ; todo: is this automatically the admin? what about logging in as different user? $ret = MsgBox(0, "Error", "Smile, you are being recorded (let's hope it's your admin).") Exit EndIf Else EndIf ; processexists ; IDENTIFY THE AUDIO FILE WE NEED TO WORK ON $myfiles = _FileListToArray(@TempDir, "rec_*.wma", 1) ; _FileListToArray($sPath[, $sFilter = "*"[, $iFlag = 0]]) ; @Error: 1 = Path not found or invalid ; $iFlag=1 Return files only ; sort the array, excluding the element=0=elemenetcounter, ascending ; todo: how does this arraysort identify the audiofil to work on? only if the audiofilename contains a datetimecreationstring, but then the sort should be descending, to put the largest=latest audiofile first ; todo: better upon fiel creration store the current (datetime) filename in a variable an refer to this variable throughout _ArraySort($myfiles, 1, 1) ; ArraySort(ByRef $avArray[, $iDescending = 0[, $iStart = 0[, $iEnd = 0[, $iSubItem = 0]]]]) ; array elements contain just the filenames, plus the counter, which will always be first element-counter (besides, we exclude the element-counter from sort) after sort (since filenames start with rec_) ; INDEXING (the audio file will (todo: really?) always be unindexed due to taskkill of wmenc to stop) ; donot: open the audio file in wmeditor to index, alt+_file /_save and index, alt+_file /e_xit and close : awkard, and can you issue keystrokes with a hidden window ; wmeditor can not be called form the cmdline, you cannot even run wmeditor with a file to open, so also open has to be done with keystrokes ; rather todo: wmenc can and has an AutoIndex Specifies and retrieves a value indicating whether the archive file will be indexed after the archiving process is completed. ; but it is overkill to reencode and save as the file just to index it ; WMEncoder Encoder; ; Encoder = new WMEncoder(); ; attempt ; oWMEncoder = objcreate("WMEncEng.WMEncoder") ; If @error then ; $ret = msgbox("failed to created object") ; else ; Encoder.Load ("C:\filename.wme") ; basics, same as record.wme, or even entire, but then change source to files and output to new filename, on ; set inputfile ; set outputfile ; bool bAutoIndex; ; // Configure the encoding session to archive encoded content. ; // For a complete example, see either the IWMEncFile object or the IWMEncFileArchiveStats object. ; // Specify the AutoIndex property. ; Encoder.AutoIndex = true; ; Encoder.Start ; endif ; @error objecreate? ; ODER SO, laut chm ; using WMEncoderLib; ; Create the WMEncBasicEdit object. ;todo: use this: WMEncBasicEdit BasicEdit = new WMEncBasicEdit(); ; Specify the input and output files. ;BasicEdit.MediaFile = "C:\\InputFile.wmv"; ; %2 ;BasicEdit.OutputFile = "C:\\OutputFile.wmv"; ; %3 ; Specify a configuration file. ;BasicEdit.ConfigFile = "C:\\ConfigFile.txt"; ; %1 ; Add indexing to the file. ;BasicEdit.Index = True;don't you need to start the encoding bei claling one of tis method after setting its properties? ; oder doch wieder run-wmcmd.vbs ; [-wme] <Windows Media Encoder session file> ; [-profile] <profile code> ; [-loadprofile] <profile file name> // what is the difference between -profile and -loadprofile? a64: Profile_AudioOnly_CDQuality_64K (64 Kbps) ; [-input] ; [-output] <file or directory name> ; cscript.exe c:\windows\wmcmd.vbs -input g:\videoinput.avs -output g:\videooutput.wmv -v_codec WVC1 -videoonly -v_mode 0 -v_preset better -v_bitrate 8000000 -v_keydist 3 -v_buffer 600000 -v_quality 100 -s_config own.weu ; Run ( "filename" [, "workingdir" [, flag[, standard_i/o_flag]]] ) $ret = Run("cscript.exe " & $wmcmdvbspath & " - wme " & $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig & "\" & $wmefilename & " -input " & @TempDir & "\" & $myfiles[1] & "-output " & @TempDir & "\" & "i" & $myfiles[1], @TempDir, @SW_HIDE, 8) If $ret = 0 Then myDebugOut(@ScriptLineNumber, "failed to run indexing vbs: " & $wmcmdvbspath & " - wme " & $driveletterkreplacementforstudentwrite & "\" & $dirsharestudentreadconfig & "\" & $wmefilename & " -input " & @TempDir & "\" & $myfiles[1] & "-output " & @TempDir & "\" & "i" & $myfiles[1]) Else ; no error : replace unindexed original audio file $ret = FileCopy(@TempDir & "\" & "i" & $myfiles[1], @TempDir & "\" & $myfiles[1]) EndIf ; @error indexing? ; todo:open output from local in wmplayer - either the indexed, or, if error, the unindexed version $ret = Run(@TempDir & "\" & $myfiles[1], @TempDir, @SW_HIDE) ; do this first, this will take some time and focus the attention of the user away from the script finishing If $ret = 0 Then myDebugOut(@ScriptLineNumber, "failed to open indexed audio file:" & @TempDir & "\" & "i" & $myfiles[1]) ; make student permanent copy of audio file $ret = FileCopy(@TempDir & "\" & $myfiles[1], $uncpathwritestudent & "\" & $myfiles[1], 9) ; FileCopy ( "source", "dest" [, flag] ) If $ret = 0 Then myDebugOut(@ScriptLineNumber, "failed to filecopy:" & $uncpathwritestudent & "\" & $myfiles[1]) ; make instructor permanent copy of audio file $ret = FileCopy(@TempDir & "\" & $myfiles[1], $driveletterkreplacementforstudentwrite & "\" & $dirsharewriteinstructor & "\" & $myfiles[1], 9) ; FileCopy ( "source", "dest" [, flag] ) If $ret = 0 Then myDebugOut(@ScriptLineNumber, "failed to filecopy:" & $driveletterkreplacementforstudentwrite & "\" & $dirsharewriteinstructor & "\" & $myfiles[1]) ; cleanup before next iteration $ret = DriveMapDel($driveletterkreplacementforstudentwrite) If $ret = 0 Then myDebugOut(@ScriptLineNumber, "failed to DriveMapDel for: " & $driveletterkreplacementforstudentwrite & ", @error=" & @error) Exit EndFunc ;==>recordingstopandplay Func streamVideo() Dim $WMENC_VIDEO = 2 Dim $WMENC_AUDIO = 1 Dim $WMENC_PROTOCOL_HTTP = 1 $object = ObjCreate("WMEncEng.WMEncoder") If @error Then MsgBox(0, "Error", "Couldn't create object! Exiting...") Else $SrcGrpColl = $object.SourceGroupCollection $SrcGrp = $SrcGrpColl.Add("SG_1") $SrcVid = $SrcGrp.AddSource($WMENC_VIDEO) $SrcAud = $SrcGrp.AddSource($WMENC_AUDIO) $SrcVid.SetInput("DEVICE://Default_Video_Device") $SrcAud.SetInput("DEVICE://Default_Audio_Device") $ProColl = $object.ProfileCollection $lLength = $ProColl.Count For $i = 0 To $lLength - 1 $Pro = $ProColl.Item($i) If $Pro.Name = "Windows Media Video 8 for Local Area Network (384 Kbps)" Then $SrcGrp.Profile = $Pro ExitLoop EndIf Next $Broadcast = $object.Broadcast $Broadcast.PortNumber($WMENC_PROTOCOL_HTTP) = 8010 $object.Start While 1 Sleep(100) WEnd $object.Stop EndIf EndFunc ;==>streamVideo Func streamAudio() ; Overview: This script opens a default.wme file and edits it to suit ; our needs. Then it runs the encoder application in hidden mode ; and begins both broadcasting a live stream ; and saving a copy to a network drive for archival purposes. ; When the user stops the broadcast ; the application is closed and the archived file is FTP'd to another server GUICreate("Audio Encoder", 410, 200) $Label_1 = GUICtrlCreateLabel("Type in a title for the broadcast and then click the button below", 30, 20, 300, 21, 0x00000020) $Label_2 = GUICtrlCreateLabel("", 30, 130, 300, 21, 0x00000020) $input_1 = GUICtrlCreateInput("", 30, 40, 350, 21) $button2 = GUICtrlCreateButton("Stop Broadcasting", 150, 80, 100, 30) GUICtrlSetState($button2, $GUI_HIDE) $button1 = GUICtrlCreateButton("Begin Broadcasting", 150, 80, 100, 30) $progbar = GUICtrlCreateProgress(30, 150, 350, 30, $PBS_SMOOTH) GUISetState() While 1 $msg = GUIGetMsg() Select Case $msg = $button1 ; begin broadcasting $data = GUICtrlRead($input_1) ; title for broadcast GUICtrlSetData($Label_1, $data) GUICtrlDelete($input_1) GUICtrlDelete($button1) GUICtrlSetState($button2, $GUI_SHOW) Initiate($data) Case $msg = $button2 GUICtrlSetData($Label_2, "Stopping Encoder") trpCleanup() Case $msg = $GUI_EVENT_CLOSE GUICtrlSetData($Label_2, "Stopping Encoder") trpCleanup() EndSelect WEnd EndFunc ;==>streamAudio Func Initiate($var) elog("=============================") GUICtrlSetData($Label_2, "Configuring System") GUICtrlSetData($progbar, 0) $newtitle = $var elog(day() & time() & " User input Title: " & Chr(34) & $newtitle & Chr(34)) ; open files for reading / re-writing ; todo: this opens wme-gui and automates it, not what i want $default = FileOpen("C:\encode\script\default.wme", 0) ; todo: remove strings $start = FileOpen("C:\encode\script\start.wme", 2); todo: remove strings If $default = -1 Then MsgBox(0, "Error", "Unable to open 'default.wme' file.") trpCleanup() EndIf If $start = -1 Then MsgBox(0, "Error", "Unable to open 'start.wme' file.") myCleanup() EndIf ; map network drive for temp storing the archive file ; If you specify "*" an unused drive letter will be automatically selected. $drv = DriveMapAdd("*", "\\Server\ShareName$") ; todo: remove string elog(day() & time() & " Attempting to map Network Drive - " & $drv) Sleep(2000) If $drv = "" Then ; todo: seems wrong check, DriveMapAdd Returns 0 if a new mapping could not be created and sets @error (see below). $drv = "C:\encode\archive" Select Case @error = 1 $comment = "1. Undefined / Other error" Case @error = 2 $comment = "2. Access to the remote share was denied" Case @error = 3 $comment = "3. The device is already assigned" Case @error = 4 $comment = "4. Invalid device name" Case @error = 5 $comment = "5. Invalid remote share" Case @error = 6 $comment = "6. Invalid password" EndSelect elog(day() & time() & " Could not map network drive. Error was: " & $comment) EndIf GUICtrlSetData($Label_2, "Creating system parameters") GUICtrlSetData($progbar, 25) ; format necessary info $oldtitle = "CHANGE_TITLE" $oldpath = "C:\CHANGE_PATH.wma" $name = StringLeft($newtitle, 10) ; $newtitle is what the user entered $name = StringReplace($name, " ", "") $name = StringReplace($name, "/", "") $name = StringReplace($name, ";", "") $name = StringReplace($name, ",", "") $name = StringReplace($name, "'", "") $name = StringReplace($name, ":", "") $name = StringReplace($name, "?", "") $name = StringReplace($name, "~", "") $name = StringReplace($name, "@", "") $name = StringReplace($name, "!", "") $name = StringReplace($name, "$", "") $name = StringReplace($name, "*", "") $name = StringReplace($name, "<", "") $name = StringReplace($name, ">", "") $name = day() & $name & ".wma" $fullpath = $drv & "\" & $name elog(day() & time() & " Archive file = " & $fullpath) ; create a custom start.wme file While 1 $line = FileReadLine($default) If @error = -1 Then ExitLoop; -1 means the end of the file If StringInStr($line, $oldtitle) Then $line = StringReplace($line, $oldtitle, $newtitle) ElseIf StringInStr($line, $oldpath) Then $line = StringReplace($line, $oldpath, $fullpath) EndIf FileWriteLine($start, $line) WEnd FileClose($default) FileClose($start) GUICtrlSetData($Label_2, "Starting Encoder Program") GUICtrlSetData($progbar, 50) ; run encoding program in hidden mode Run("C:\Program Files\Windows Media Components\Encoder\wmenc.exe c:\encode\script\start.wme", "", @SW_HIDE) WinActivate("Audio Encoder"); shift focus back to our app While 1 Sleep(500) If WinExists("start - Windows Media Encoder") Then Sleep(2000); give it a couple seconds before proceeding ExitLoop EndIf WEnd GUICtrlSetData($Label_2, "Initiating Encoder") GUICtrlSetData($progbar, 75) ; Send keys to begin broadcasting ControlSend("start - Windows Media Encoder", "", "Titan:CToolBar1", "^E", 0) elog(day() & time() & " Started Encoding") ; Do some error checking to ensure the archive file is being created $count = 0 While 1 If FileExists($fullpath) Then elog(day() & time() & " Archive file took " & $count & " sec to create") ExitLoop Else Sleep(1000) $count = $count + 1 If $count > 10 Then elog(day() & time() & " File not found within 10 seconds, killing process") WinKill("start - Windows Media Encoder") DriveMapDel($drv) $msg = MsgBox(0, "Error", "There has been an error, please " _ & "contact an administrator if this problem persists") Exit EndIf EndIf WEnd GUICtrlSetData($progbar, 100) GUICtrlSetData($Label_2, "Broadcasting Live") EndFunc ;==>Initiate Func myCleanup() ControlSend("start - Windows Media Encoder", "", "Titan:CToolBar1", "^S", 0) GUICtrlSetData($progbar, 0) GUICtrlSetData($Label_2, "Ending Session") ; give the encoder enough time to stop (move progress bar while waiting) $movebar = 0 While 1 GUICtrlSetData($progbar, $movebar) Sleep(1000) $movebar = $movebar + 10 If $movebar > 99 Then ExitLoop WEnd WinClose("start - Windows Media Encoder") ; wait for encoder program to close GUICtrlSetData($Label_2, "Closing Encoder Application") $movebar = 0 While 1 Sleep(500) If WinExists("start - Windows Media Encoder") Then GUICtrlSetData($progbar, $movebar) $movebar = $movebar + 10 If $movebar > 99 Then $movebar = 0 Else ExitLoop EndIf WEnd elog(day() & time() & " Begin FTP") ; FTP file to media server If FileExists($fullpath) Then GUICtrlSetData($progbar, 60) GUICtrlSetData($Label_2, "Sending Archive file to Media Server") $server = '192.168.1.1'; IP of server $username = 'UserName' $pass = "PassWord" $Open = _FTPOpen('MyFTP Control') $Conn = _FTPConnect($Open, $server, $username, $pass) $Ftpp = _FtpPutFile($Conn, $fullpath, $name) $Ftpc = _FTPClose($Open) elog(day() & time() & " Completed FTP of temp file") FileDelete($fullpath) elog(day() & time() & " Deleted temp file") GUICtrlSetData($Label_2, "Transfer Completed... Closing Application") GUICtrlSetData($progbar, 100) DriveMapDel($drv) Sleep(2000) Exit Else MsgBox(0, "Done", "Archived File not found.") elog(day() & time() & " Temp file did not exist") DriveMapDel($drv) Exit EndIf elog(day() & time() & " Closing Application Successfully") EndFunc ;==>myCleanup Func elog($txt) $ix = FileOpen("C:\encode\script\errorlog.txt", 1) FileWriteLine($ix, $txt) If $ix = -1 Then MsgBox(0, "Error", "Unable to open 'error.txt' file.") Exit EndIf FileClose($ix) EndFunc ;==>elog Func day() $iday = @YEAR & @MON & @MDAY Return $iday EndFunc ;==>day Func time() $iTime = @HOUR & @MIN & @SEC Return $iTime EndFunc ;==>time ; Function Name: _ProcessGetOwner() ; Description: Get the owner of an open process ; Parameter(s): $vProcess - PID of a process. ; $strComputer - Name of target computer ; Requirement(s): AutoIt Beta v3.2.+ ; cimwin32.dll (included with Windows) ; Return Value(s): On Success - Returns owners username of process ; 0 - Successful, returns username ; ; On Failure: Returns friendly errormessage and sets @Error to: ; 2 - Access denied ; 3 - Insufficient privilege ; 8 - Unknown failure ; 21 - Path not found ; Author(s): Andreas Fälldin ;=============================================================================== Func _ProcessGetOwner($vProcess, $strComputer = "") Local $i_PID = ProcessExists($vProcess) If Not $i_PID Then SetError(1) Return -1 EndIf Local $wbemFlagReturnImmediately = 0x10 Local $wbemFlagForwardOnly = 0x20 Local $colItems = "" Local $strUser = "" ; The local computer name in the object path can be replaced with '.' ; The computer name can also be omitted from the object path, in which case the local computer is assumed. If $strComputer = "" Then $strComputer = "localhost" $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\CIMV2") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE ProcessID = " & $i_PID, "WQL", _ $wbemFlagReturnImmediately + $wbemFlagForwardOnly) If IsObj($colItems) Then For $objItem In $colItems $rc = $objItem.GetOwner($strUser) Switch $rc Case 0 SetError(0) Return $strUser Case 2 SetError(2) Return "ACCESS DENIED" Case 3 SetError(3) Return "INSUFFICIENT PRIVILEGE" Case 8 SetError(8) Return "UNKNOWN FAILURE" Case 9 SetError(9) Return "PATH NOT FOUND" Case 21 SetError(21) Return "INVALID PARAMETER" Case Else SetError(1) Return -1 EndSwitch Next EndIf EndFunc ;==>_ProcessGetOwner ; automates adding contextinfo to the debug msg (screenshot, scriptlinenumber) ; parameters: $ScriptLineNumber needs to be set to @ScriptLineNumber ; better with $tempdir ; requires screencapture.au3, debug.au3 with _debugsetup ; todo: would be nicer if $ScriptLineNumber need not be set explicitly, but default value would work (test), but then the parameter sequence needs to be switched ; i think $ScriptLineNumber = @ScriptLineNumber does not work ; updated ver below not documented above Func myDebugOut($ScriptLineNumber = @ScriptLineNumber, $msg = "Error") ; requires global setting of $debugtype = "debug" Local $debugstring Local $debugfilename Local $tabhandle Local $tabmaxnumber Local $tempdir ; must be global local $pathfilelog $tempdir = @TempDir If $tempdir == "" Then $tempdir = "c:\temp" $debugstring = $ScriptLineNumber & "~" & _Now() & "~" & $msg ; changed : to ~to have delimiters -> tab -> excel -> filter If $debugtype = "debug" Then Local $activewindowtitle = WinGetTitle("") ; todo: test: is using this necessary to give focus back to the window after oking msgbox? MsgBox(0, "debug", $debugstring) WinActivate($activewindowtitle) ElseIf $debugtype = "debugconsole" Then ConsoleWrite($debugstring & Chr(13)) ElseIf $debugtype = "run" Then If $tempdir == "" Then $tempdir = "c:\temp" $debugfilename = FileNameEscape($debugstring, $tempdir) & ".jpg" ; ".bmp" ; can this do jpg also, and jsut by changing the extension? ; works _DebugOut("$debugfilename:" & $debugfilename) _ScreenCapture_Capture($debugfilename); [$sFileName = ""[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]]) _DebugOut($debugstring) ElseIf $debugtype = "debugconsolescreen" Then ; do both ConsoleWrite($debugstring & Chr(13)) $debugfilename = FileNameEscape($debugstring, $tempdir) & ".jpg" ; ".bmp" ; can this do jpg also, and jsut by changing the extension? ; works _DebugOut("$debugfilename:" & $debugfilename) ; todo: filenameescape does not result in a legit filename, it seems: debug - problem is the \ ; works better now that backslash is escaped ConsoleWrite("$debugfilename:" & $debugfilename & Chr(13)) _ScreenCapture_Capture($debugfilename); [$sFileName = ""[, $iLeft = 0[, $iTop = 0[, $iRight = -1[, $iBottom = -1[, $fCursor = True]]]]]]) ElseIf $debugtype = "releasetextlog" Then ; todo ; todo: consider "release" --> log ; file open append file close If $pathfilelog == "" Then $pathfilelog = @TempDir & "\" & "autoitlogfile.log" $loghandle = FileOpen($pathfilelog, 1); Success: Returns a file "handle" for use with subsequent file functions. If $ret = 0 Or @error Then Exit ; Failure: Returns - 1 If error occurs. $ret = FileWriteLine($loghandle, $debugstring & Chr(13)) If $ret = 0 Or @error Then Exit ; Failure: Returns - 1 If error occurs. $ret = FileClose($loghandle) ElseIf $debugtype = "releasewordpad" Then ; todo Else ; do nothing or error ; can one paste behind the scenes screenshots into wordpad? eaiser for the betatester to send SetError(1) EndIf EndFunc ;==>myDebugOut Func FileNameEscape($filename, $tempdir) ; return a filename which has no special chars - todo: should be unescapable ; StringReplace ( "string", "searchstring" or start, "replacestring" [, count [, casesense]] ) ; added for mydebugout() $filename = StringReplace($filename, ":", "_"); cannot have : in filename $filename = StringReplace($filename, ">", "larger_than"); cannot have > in filename $filename = StringReplace($filename, "<", "smaller_than"); cannot have > in filename ; end added for mydebugout() $filename = StringReplace($filename, " ", "_"); have no spaces in filenames ? $filename = StringReplace($filename, "/", "&"); "Picture/Word_Association" ; todo: & is not save on the commandline - does + work better $filename = StringReplace($filename, "/", "+"); "Picture/Word_Association" $filename = StringReplace($filename, "&", "+"); occurs in some titles $filename = StringReplace($filename, Chr(92), "_") ; tabs - todo: what about other space characters $filename = StringReplace($filename, Chr(9), "_") ; tabs - todo: what about other space characters ; todo: fails again, without warning, file save dialogue remains open: ; Language=1[British_English]_Family=2[Intermediate]_Contenttype=1[Activity]_ActivityOrUnitOrCulture=1[Dialogue]_Exercise=10['Still_hungry?'_Intermediate_1elements]_error171 ; replace questionmark, exclamation mark, quotationmark $filename = StringReplace($filename, "?", "questionmark") $filename = StringReplace($filename, "!", "exclamationmark") $filename = StringReplace($filename, "'", "quotationmark") ; todo: should say single or sth else unique $filename = StringReplace($filename, Chr(34), "doublequotationmark") ; 34 Quotation mark (" in HTML) $filename = StringReplace($filename, "__", "_") ; todo: can stringreplace handle multicharacter? $filename = StringReplace($filename, "__", "_") ; $filename = StringReplace($filename, "__", "_") ; $filename = StringReplace($filename, "__", "_") ; $filename = $tempdir & "\" & $filename ; end filename routine Return $filename EndFunc ;==>FileNameEscape Func FileCopy2LocalTemp($filepath) ; ex: Dim $arrfilepath, $filepathname, $arrfilepathname, $filepathnameext $blnValid = True If Not FileExists($filepath) Then If Not DriveMapAdd("", $filepath) Then ; todo: try also unc paths $blnValid = False EndIf EndIf If $blnValid Then $arrfilepath = _StringSplit($filepath, "\") If @error Then SetError(1) myDebugOut(@ScriptLineNumber, "error stringsplit filepath") EndIf $filepathname = $arrfilepath(UBound($arrfilepath) - 1); get !!filename ; ould be used to give the file a new basename, which would have to be passed as 2nd param $basename ;$arrfilepathname = _StringSplit($filepathname,".") ;if @error then ; myDebugOut(@ScriptLineNumber, "error stringsplit filepathname") ; seterror(1) ;endif ;$filepathnameext = $arrfilepathname(UBound($arrfilepathname) -1); get ext $ret = FileCopy($filepath, @TempDir & "\" & $filepathname) Else SetError(1) EndIf EndFunc ;==>FileCopy2LocalTemp Func taskkillsamples() Local $ret3, $ret4, $filename, $windowtitlePDFCreate myDebugOut(@ScriptLineNumber, "trying to use taskkill to bypass window:" & $windowtitlePDFCreate & " for: " & $filename) $ret3 = RunWait('taskkill /F /fi "imagename eq acro*" /im *') ; return 0 seems good, sometimes? ; single quotes error from the commandline , doublequotes do not, they close the process(including multiple process using wildcard) myDebugOut(@ScriptLineNumber, "runwait returned " & $ret3) ; ERROR: The process "'acro*.exe'" not found. Sleep(5000) ; trying to find a mazimum taskkill that won't shutdown the system ; return 0 seems good, sometimes? requires script-exe name start with auralog ; do close tutortools, /fi "imagename ne tutortools*" $ret4 = RunWait('taskkill /F /fi "username ne SYSTEM" /fi "username ne LOCAL SERVICE" /fi "username ne NETWORK SERVICE" /fi "imagename ne autoit*" /fi "imagename ne notepad*" /fi "imagename ne scite*" /fi "imagename ne ' & $scriptfilewithexe & '*" /im *') ; return 0 seems good, sometimes? myDebugOut(@ScriptLineNumber, "checkercounter > 5, Exterminate all user tasks, returns :" & $ret4) EndFunc ;==>taskkillsamples ; todo: test this with student permissions Func addStudentReadconfigNetworkshares() ; wmencoder cannot handle wme load as uncpath ;SETTINGS $driveletterreadconfig = DriveMapAdd("*", $uncpathsharestudentreadconfig, 0) ; connect as logged in user - works only for students myDebugOut(@ScriptLineNumber, "$driveletterreadconfig is: " & $driveletterreadconfig & ", $uncpathsharestudentreadconfig is " & $uncpathsharestudentreadconfig & ", @error=" & @error) If @error > 0 Then demandloginasstudent() EndIf If (($driveletterreadconfig == "") Or $driveletterreadconfig == 0) Then ; todo:hack $driveletterreadconfig = "O:" EndIf ; if StringLen($driveletterreadconfig) > 0 then ; no error mapping: If there was an error using "*" then a blank string "" will be returned. ; todo: you have added the drives, but for whom? do you no need to impersonate as this user when you filecopy? ; endif ; another interesting idea is this (but how to pass the original username as parameter? could save to and read from ini) ; If Not IsAdmin() Then RunAs($user, $domain, $pass, 0, @ScriptFullPath), Exit EndIf Return $driveletterreadconfig EndFunc ;==>addStudentReadconfigNetworkshares Func deleteStudentShare() ; net use or drivemapdel ; To disconnect from the \\Financial\Public directory, type: net use f: \\financial\public /delete , /y = do not ask the user to type Y or N ; To run DOS commands, try RunWait(@ComSpec & " /c " & "commandName") ; don't forget " " before "/c" ; check first whether the drive / share is connected If Not (FileExists($uncpathsharewriteinstructor) Or FileExists($driveletterkreplacementforstudentwritenetuse)) Then; todo: works with dirs? todo: not uses - now what? safe to connect with sever permissions myDebugOut(@ScriptLineNumber, $driveletterkreplacementforstudentwrite & " nor " & $uncpathsharewriteinstructor & "exist, cannot disconnect") Else ; exists - todo: what exactly? share, driveletter, which permissions $ret = DriveMapDel($driveletterkreplacementforstudentwritenetuse) ; todo: stupid hack, essentially hardcoded k: myDebugOut(@ScriptLineNumber, "disconnect for $driveletterkreplacementforstudentwritenetuse=" & $driveletterkreplacementforstudentwritenetuse & ", $ret=" & $ret & ", @error=" & @error) EndIf EndFunc ;==>deleteStudentShare Func addStudentShare() If Not (FileExists($driveletterkreplacementforstudentwritenetuse)) Then $ret = RunWait(@ComSpec & " /c net use " & $driveletterkreplacementforstudentwritenetuse, "", @SW_HIDE) ; default permissions Sleep(1000) EndIf EndFunc ;==>addStudentShare ; todo: when is removeInstructorNetworkShares called? Func removeInstructorNetworkShares() ; this does not work ; cleanup before next iteration $ret = DriveMapDel($driveletterkreplacementforstudentwrite) If $ret = 0 Then myDebugOut(@ScriptLineNumber, "failed to DriveMapDel for: " & $driveletterkreplacementforstudentwrite & ", @error=" & @error) EndFunc ;==>removeInstructorNetworkShares Func addInstructorNetworksharesNetuse() ; even if we write to K; which the student has a mapping to, it is crucial (and more important than a confusing driveletter) that we map as instructor, or else no write permission of script to folder ; this hardcodes k: ; the command completed successfully: net use k: \\stushare_server\StuShare "friday12" /user:lgu.ac.uk\plagwitt ;SETTINGS If FileExists($driveletterkreplacementforstudentwritenetuse) Then ; if it was not connected and the disconnect fails, xit the program with msg close all files and programms from k: ; net use k: /delete /y $ret = RunWait(@ComSpec & " /c net use " & $driveletterkreplacementforstudentwritenetuse & " /delete /y", "", @SW_HIDE) Sleep(1000) If $ret = 0 Then demanddisconnectkfirst() EndIf EndIf If StringLen($passworddecrypt) > 0 Then ; allows the user in the ini to leave the pwd blank to not have to encrypt the password (which amy be too difficult for the user) $run = RunWait(@ComSpec & " /c net use " & $driveletterkreplacementforstudentwritenetuse & " " & $uncpathsharewriteinstructor & " """ & _StringEncrypt(0, $passwordinstructor, $passworddecrypt) & """ " & " /user:" & @LogonDomain & "\" & $usernameinstructor, "", @SW_HIDE) myDebugOut(@ScriptLineNumber, "connect $ret=" & $ret) Else $run = RunWait(@ComSpec & " /c net use " & $driveletterkreplacementforstudentwritenetuse & " " & $uncpathsharewriteinstructor & " """ & $passwordinstructor & """ " & " / user:" & @LogonDomain & " \" & $usernameinstructor, "", @SW_HIDE) myDebugOut(@ScriptLineNumber, "connect $ret=" & $ret) EndIf EndFunc ;==>addInstructorNetworksharesNetuse Func addInstructorNetworkshares() ; even if we write to K; which the student has a mapping to, it is crucial (and more important than a confusing driveletter) that we map as instructor, or else no write permission of script to folder ;SETTINGS If StringLen($passworddecrypt) > 0 Then ; allows the user in the ini to leave the pwd blank to not have to encrypt the password (which amy be too difficult for the user) $driveletterkreplacementforstudentwrite = DriveMapAdd("*", $uncpathsharewriteinstructor, 0, @LogonDomain & "\" & $usernameinstructor, _StringEncrypt(0, $passwordinstructor, $passworddecrypt)) Else $driveletterkreplacementforstudentwrite = DriveMapAdd("*", $uncpathsharewriteinstructor, 0, @LogonDomain & "\" & $usernameinstructor, $passwordinstructor) EndIf myDebugOut(@ScriptLineNumber, "$driveletterkreplacementforstudentwrite is: " & $driveletterkreplacementforstudentwrite & ", $uncpathsharewriteinstructor is " & $uncpathsharewriteinstructor & ", $usernameinstructor, $passwordinstructor are " & $usernameinstructor & $passwordinstructor & ", @error=" & @error) If (($driveletterkreplacementforstudentwrite == "") Or $driveletterkreplacementforstudentwrite == 0) Then ; todo:hack $driveletterkreplacementforstudentwrite = "K:" EndIf ; if StringLen($driveletterkreplacementforstudentwrite) > 0 then ; no error mapping: If there was an error using "*" then a blank string "" will be returned. ; todo: you have added the drives, but for whom? do you no need to impersonate as this user when you filecopy? ; endif ; another interesting idea is this (but how to pass the original username as parameter? could save to and read from ini) ; If Not IsAdmin() Then RunAs($user, $domain, $pass, 0, @ScriptFullPath), Exit EndIf Return $driveletterkreplacementforstudentwrite EndFunc ;==>addInstructorNetworkshares Func demanddisconnectkfirst() myDebugOut(@ScriptLineNumber, "disconnect $ret=" & $ret) $ret = MsgBox(1, "Error!", "Close all files and programms running from K: first, then restart trprecord. Will exit now...") myCleanup() EndFunc ;==>demanddisconnectkfirst Func demandloginasstudent() myDebugOut(@ScriptLineNumber, "disconnect $ret=" & $ret) $ret = MsgBox(1, "Error!", "You are logged in as: " & @UserName & ". Make sure you are logged in as student with access to \\lgu.ac.uk\lgu$\multimedia student\mmedia, then restart trprecord. Will exit now...") myCleanup() EndFunc ;==>demandloginasstudent Func trpCleanup() removeInstructorNetworkShares() addStudentShare() Exit EndFunc ;==>trpCleanup Func MyErrFunc() $myMessage = "err.description_" & $oMyError.description & "." & "err.windescription_" & $oMyError.windescription & "." & "err.number_" & Hex($oMyError.number,8) & "." & "err.lastdllerror_" & $oMyError.lastdllerror & "." & "err.scriptline_" & $oMyError.scriptline & "." & "err.source_" & $oMyError.source & "." & "err.helpfile_" & $oMyError.helpfile & "." & "err.helpcontext_" & $oMyError.helpcontext myDebugOut(@ScriptLineNumber, "Com Error: " & $myMessage) MsgBox(0, "trpRecord WME SDK COM Error", "Alt+Print Screen, then paste this into an email to ictservicedesk@londonmet.ac.uk! I will exit after you press OK." & @CRLF & $myMessage) Local $err = $oMyError.number If $err = 0 Then $err = -1 Exit ; added trp $g_eventerror = $err ; to check for after this function returns - spar ich mir EndFunc ;==>MyErrFunc ; done: why does on exit a cmd window flash? is there a comspec without sw_hide somewhere? b/o forgottem "", @SW_HIDE wiht runwait(@comspec ; todo: drivemapadd * does not give k: even if i drivemapdel k: - nor surprise, you allow any drivleietter iwth * , it would be bette to reconnect as k:, but this would require additional checking
Comments (0)
Trackbacks (0)
Leave a comment
Trackback