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

