Archive

Posts Tagged ‘Saville’

Digitization of the SAVILLE analogue Conference interpreting recording facility: Lecture/Floor recording and CCTV streaming

The original conference interpreting lab setup had no provision for digital video recording of the lecture/floor. A workaround used on of the booth VCRs for analogue recording, with video form an ELMO dome cameras and audio from a lectern microphone – an audio installation which ran in parallel to the main DSI conference interpreting facility (and covered only the lectern, not the conference table).

A home-brew add-on was based on a consumer handheld digital camera for video. Experiments with different add-on microphones for audio from the lectern and floor were less than successful.

The DIS system however provides an audio out of the lectern an/or floor audio, as well as the capability for the conference administrator to open or mute floor microphones and for the technical administrator to set the maximum number of open microphones, and control their gain.

For the digitization of this system, I used

  1. an already retired standard university student lab computer
  2. to which I added an old spare ATI All-in-Wonder video card
  3. to which I connected a TEVION home TV switch as a poor man’s (~5£) video splitter into which I fed
  4. the (hitherto unused) DIS audio out balanced stereo, using an RCA adapter, as well as
  5. the ELMO video, using  a coax to RCA adapter (video signal was split into the ATI as well as back into the original SAVILLE Kramer AV switch).

While originally coming with its own digitization software, the ATI All-in-wonder also works well with Windows Media Encoder.

Two wme configuration files were created:

  1. capturetestaticomposite_pal-l_480x320works.wme(find this file on the computer connected to the central rack, then double-click it in order to start Windows Media Encoder, then click the Record button in the top menu – no custom GUI was deemed necessary for this non-student operated recording)  for recording to files that can be played with Windows media player, whether on Windows or on Mac OS X.
  2. streamtest480x320_15fps_pal.wme (again, simply find this file on the central rack computer, then double-click it) for streaming CCTV live to the back office. An onsite admin office was one of the usual features of a teaching lab which was missing in this installation. CCTV allows to keep an eye on teaching activities in the conference interpreting lab, proactively spot support needs ands absorb feature requirements which instructors tend to have problems articulating (or even seeing the need for articulating). A (lower quality archived stream is created on the side and can be picked up, post-processed and archived at TBA).

    

Digitization of the SAVILLE analogue Conference interpreting recording facility: Booths. Technical instructions

Prerequisites:

The original SAVILLE setup to add (floor and booth) video and enable recording in the DIS 6000 conference interpreting facility. The cabling, switching and interfacing can all be used unchanged, and the VHS recorders should indeed be used as backup. OTOH, once you feel confident about digital recording, you can  fade out the VHS recorders (or replace them by yet another output device).

Digital video capture card – the cheapest I could find was this and it tested to work (including lip synching),

Miscellaneous AV splitters and cables.

Windows Media Encoder 9 and the Windows Media Encoder SDK, both available from Microsoft and installed by campus ICT support.

Windows Media Encoder Configuration Files trprecord_a.wme and trprecord_av.wme in \\stushare_server\StuShare\Humanities, Arts and Languages\Language_Services\configuration

AutoIt3, a scripting language used on campus for computer deployment.  The compiled executable I provide has no prerequisites on our MS-Windows installation. If you want to make changes in the au3 script, you will need the free AutoIt3 language and development environment.

The script relies on impersonation to access the network shares. If the user/password this impersonation is based on changes, you can still work with the recordings on the local PC. To restore the network archiving/sharing functionality, you have to run trpPwdEncrypt.exe (a slight adaptation from the AutoIT3 help file example) and follow the included instructions:

Then recompile the script trprecord.au3 (both files are stored on the instructors-only share) and put the resulting trprecord.exe on the student-accessible share.

Troubleshooting:

  1. Check the AV cables and connectors.
  2. Check the screenshots and their filenames which the software produces for logging in the local temp directory (note that this directory gets purged on restart).
  3. If you make changes in the environment, do not fail to also change the corresponding configuration strings at the top of trprecord.au3,  then recompile.

Digitization of the SAVILLE analogue Conference interpreting recording facility: Booths: End-user

The instructor sets the booth AV sources as usual (using the CRESTRON remote control).

The student in the booth starts the trprecord.exe from the student-accessible share (if the application is already running, an attempt to start another instance brings the current instance to the foreground).

In the GUI (which should not be hidden by blocking the student screen with AV signal; one more reason to stop the wasteful sharing of one screen between AV and VGA signal):

  1. choose whether to record “Audio” or “Video”(the disabled (grayed out) non-live recording modes are not yet implemented. they would be a completely separate extension of the SAVILLE system.).
  2. press “Start”, wait for the message indicating recording has begun
  3. pressing “Start” enables the “Stop” button; press “Stop” when finished
  4. once the “Play” button has been activated, the student can listen to the last recording in the default player for WMA or WMV files (normally Windows Media Player).
  5. both student and instructors can listen to other (past and/or peer) recordings by “open[ing the network share] folder”. The instructor (having full control permissions on the network share folder) controls the release of network share videos. Students can only read from this network share folder. The filename, e.g. trprecord_2009_08_04_18_24_47_MORLIB–PCC6392_plagwitt.wma, indicates this:
  6. Prefix

    Date  recording started

    Time recording started

    on which computer

    for which logged-in user

    Audio or video

    trprecord_

    2009_08_04_

    18_24_47_

    MORLIB–PCC6392_

    plagwitt

    .wma/v

  7. Currently, the computer in the booths of the interpreting suite have the following names (note that the computer names are not aligned with the booth numbers; update this when the computers get upgraded):
  8. Booth

    Computer

    mgb-41

    morb43-6374

    mgb-42

    morb44-6344

    mgb-43

    morb45-6363

    mgb-44

    morb46-6353

    mgb-45

    morb42-6368

    mgb-46

    morb47-6359

  9. When listening to the recording in Windows Media Player, use the “Balance” slider which you can enable by clicking Menu:File / View / Enhancements / Graphics Equalizer. Wiggle the slider
  10. Press F1-key for (this) Help. Pay attention to program feedback messages in red.

View trprecord_demo_walkthrough.AVI (your problems with videos are addressed here; no screencast this time, as 2 simultaneous video encoding sessions would overtax the recording computer and could not demonstrate the interaction with the new secondary video screen) which demonstrates ease of use of the program itself and recording files it

How to build a digital recorder with GUI for free with Windows-Media-Encoder

  1. 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.
  2. Uses AutoIT and Windows-COM programming, as exemplified in Windows-media-encoder-SDK, against Windows-Media-Encoder.
  3. make sure that you have
    1. have all AutoIt packages referenced with #includes below;
    2. have the windows-media-encoder installed – the windows-media-encoder-SDK should not be needed , except for programming examples;
    3. make sure you adapt “PUTYOUROWN” to your own environment
    4. provide your own (equipment-specific) WME files for the Windows-Media-Encoder configuration.
  4. (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 (&quot; 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