| REM VBSMAKEWEBM.VBS | |
| REM Author: Matthew Heaney | |
| REM mailto:matthewjheaney@google.com | |
| REM | |
| REM This script demonstrates how to call the MAKEWEBM.EXE app from | |
| REM a Visual Basic script. | |
| REM | |
| REM This particular script synthesizes the name of the output file | |
| REM from the name of the input file (although the app can do that | |
| REM itself already), and puts it in the user's My Videos directory. | |
| REM | |
| REM The script captures the text sent to stdout by the app, parses | |
| REM it using a regex, and then writes the value of the time to | |
| REM stdout from the script itself. This is exactly what the app does. | |
| REM | |
| REM To run this script, you can specify the script filename as an argument | |
| REM to the cscript interpreter: | |
| REM cscript //nologo vbsmakewebm.vbs <path to input file> | |
| REM | |
| REM Alternatively, you can invoke the cscript interpreter implicitly. | |
| REM First configure your environment to make cscript the default: | |
| REM cscript //H:cscript | |
| REM This configuration only needs to be done once. Now you can | |
| REM run the script directly: | |
| REM vbsmakewebm <path to input file> | |
| Option Explicit | |
| Dim i, str 'scratch | |
| Dim objArgs | |
| Dim objFSO, objSrc, objTgt | |
| Dim objShell, objExec, objStdOut | |
| Dim strCmd, strLine, strTime, strDuration | |
| Dim strInput, strOutput | |
| Dim reTime, reDuration, mm | |
| 'We accept a single command-line argument, which is the path to | |
| 'the input file. | |
| Set objArgs = Wscript.Arguments | |
| If objArgs.Count <= 0 Then | |
| Wscript.Echo "too few arguments" | |
| Wscript.Quit | |
| End If | |
| If objArgs.Count > 1 Then | |
| Wscript.Echo "too many arguments" | |
| Wscript.Quit | |
| End If | |
| Set objFSO = CreateObject("Scripting.FileSystemObject") | |
| Set objShell = CreateObject("Wscript.Shell") | |
| 'Find the path to the makewebm executable. | |
| 'First try the folder that contains the script. | |
| str = objFSO.GetParentFolderName(Wscript.ScriptFullName) | |
| str = objFSO.BuildPath(str, "makewebm.exe") | |
| If Not objFSO.FileExists(str) Then | |
| 'Try C:\bin | |
| str = objFSO.BuildPath("C:\bin", "makewebm.exe") | |
| End If | |
| If Not objFSO.FileExists(str) Then | |
| Wscript.Echo "Unable to find path to MAKEWEBM.EXE app" | |
| Wscript.Quit | |
| End If | |
| 'We have found the path to the exe, so we use that to | |
| 'form the command string, which we assemble incrementally. | |
| strCmd = """" & str & """ --script-mode" 'exe | |
| strInput = objArgs(0) 'the path to the input file | |
| If Not objFSO.FileExists(strInput) Then | |
| Wscript.Echo "Input file not found" | |
| Wscript.Quit | |
| End If | |
| 'We have confirmed the existence of the input file, | |
| 'so we append it to the command string. | |
| strCmd = strCmd & " --input=""" & strInput & """" 'exe + input | |
| 'We next find the output file path. We first locate the folder | |
| 'named "My Videos" (creating it if necessary) under "My Documents". | |
| str = objShell.SpecialFolders("MyDocuments") | |
| If Not objFSO.FolderExists(str) Then | |
| Wscript.Echo "Documents folder not found" | |
| Wscript.Quit | |
| End If | |
| Set objTgt = objFSO.GetFolder(str) | |
| str = objFSO.BuildPath(objTgt.Path, "My Videos") | |
| If objFSO.FolderExists(str) Then | |
| Set objTgt = objFSO.GetFolder(str) | |
| Else | |
| Set objTgt = objFSO.CreateFolder(str) | |
| End If | |
| 'We have the folder for the output file. Next we name | |
| 'the output file based on the basename of the input file. | |
| strOutput = objFSO.GetBaseName(strInput) & ".webm" 'just name | |
| strOutput = objFSO.BuildPath(objTgt.Path, strOutput) 'full path | |
| 'Finally we append the output file to the command string. | |
| strCmd = strCmd & " --output=""" & strOutput & """" | |
| 'For Debugging: | |
| 'strCmd = strCmd & " --list --verbose" | |
| 'Wscript.Echo strCmd | |
| 'Wscript.Quit | |
| 'adjust deadline value as you see fit | |
| strCmd = strCmd & " --deadline=realtime" | |
| 'We create a regex that matches the output of the app | |
| 'when it is run in script mode. | |
| Set reTime = New RegExp | |
| reTime.Pattern = "TIME=(\S+)" | |
| Set reDuration = New RegExp | |
| reDuration.Pattern = "DURATION=(\S+)" | |
| 'Finally we run the app, using the command line we assembled incrementally. | |
| Set objExec = objShell.Exec(strCmd) | |
| Set objStdOut = objExec.StdOut | |
| 'We use AtEndOfStream to terminate the loop. The end of stream is | |
| 'reached when the app terminates, which is exactly what we want. | |
| Do Until objStdOut.AtEndOfStream | |
| 'Consume a line of output from the app: | |
| strLine = objStdOut.ReadLine | |
| 'Parse the line to find the time | |
| Set mm = reTime.Execute(strLine) | |
| If mm.Count <> 1 Then 'regex error | |
| Wscript.StdOut.WriteLine | |
| 'TODO: find a better way to handle this: | |
| Wscript.StdOut.WriteLine "TEXT: " & strLine | |
| Else | |
| 'Write the time value to stdout. This duplicates the behavior | |
| 'of what the app would do, if it were run directly from the shell. | |
| Wscript.StdOut.Write vbCR | |
| Wscript.StdOut.Write mm(0).Submatches(0) | |
| 'Parse the line to find the duration | |
| Set mm = reDuration.Execute(strLine) | |
| If mm.Count = 1 Then | |
| Wscript.StdOut.Write "/" | |
| Wscript.StdOut.Write mm(0).Submatches(0) | |
| End If | |
| End If | |
| Loop | |
| Wscript.StdOut.WriteLine |