Search code examples
javaapplescriptquicktime

Recording with Quicktime through Java


I want to make a recording with Quicktime using Java but there is some issue when I try to enter the folder and file. I though it might be a timing issue so put in delays but it still happens. The code to start the recording is:

public static void startQTrecord(){     
        //Activate QT
        try{
            String[] go = { "osascript", "-e", "tell application \"QuickTime Player\" to activate" };
            Process process = Runtime.getRuntime().exec(go);
            process.waitFor();

        } catch (IOException ex) {
            System.out.println(ex.toString());
        } catch (InterruptedException ex) {
            System.out.println(ex.toString());
        }    
        //Start new recording
        try{
            String[] go = { "osascript", "-e", "tell application \"QuickTime Player\" to start new movie recording" };
            Process process = Runtime.getRuntime().exec(go);
            process.waitFor();    
        } catch (IOException ex) {
            System.out.println(ex.toString());
        } catch (InterruptedException ex) {
            System.out.println(ex.toString());
        }

And the code to stop and save is:

public static void closeQT(){
        //Go to QT
        try {
            String[] go = {"osascript", "-e", "tell application \"QuickTime Player\" to activate"};
            Process process = Runtime.getRuntime().exec(go);
            process.waitFor();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        } catch (InterruptedException ex) {
            System.out.println(ex.toString());
        }
        //Stop the recording
        try {
            String[] go = {"osascript", "-e", "tell application \"QuickTime Player\" to stop document \"movie recording\""};
            Process process = Runtime.getRuntime().exec(go);
            process.waitFor();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        } catch (InterruptedException ex) {
            System.out.println(ex.toString());
        }
        //Save
        try {
            sleep(100);
            String[] go = {"osascript", "-e", "tell application \"System Events\" to keystroke \"s\" using {command down}", "-e", "delay 1"};         
            Process process = Runtime.getRuntime().exec(go);
        process.waitFor();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        } catch (InterruptedException ex) {
            System.out.println(ex.toString());
        }
        //Enter the save directory
        try {
            sleep(100);
            String[] go = {"osascript", "-e", "tell application \"System Events\" to keystroke \"G\" using {command down, shift down}", "-e", "delay 1"};
            Process process = Runtime.getRuntime().exec(go);
            process.waitFor();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        } catch (InterruptedException ex) {
                System.out.println(ex.toString());
        }
        try {
            sleep(100);
            String gofolder = "tell application \"System Events\" to keystroke \"" + folder + "\"";
            String[] go = {"osascript", "-e", gofolder, "-e", "delay 1", "-e", "tell application \"System Events\" to keystroke return", "-e", "delay 1"};
            Process process = Runtime.getRuntime().exec(go);
            process.waitFor();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        } catch (InterruptedException ex) {
                System.out.println(ex.toString());
        }
        try {
            sleep(100);
            String[] go = {"osascript", "-e", "tell application \"System Events\" to keystroke\""+file+"\"", "-e", "tell application \"System Events\" to keystroke return", "-e", "delay 1"};         
            Process process = Runtime.getRuntime().exec(go);
            process.waitFor();
        } catch (IOException ex) {
            System.out.println(ex.toString());
        } catch (InterruptedException ex) {
            System.out.println(ex.toString());
        }
        /////////////////////////////////////////////
        //Wait for save then quit
        boolean keepWaiting = true;
        while(keepWaiting){
            try{
                Runtime rt = Runtime.getRuntime();
                String[] commands = {"osascript", "-e", "delay 5", "-e", "tell application \"QuickTime Player\" to quit"};
                Process proc = rt.exec(commands);
                proc.waitFor();
                BufferedReader stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
                String s = null;
                // read any errors from the attempted command
                if(stdError.readLine() == null){keepWaiting = false;}
            } catch (IOException ex) {
                System.out.println(ex.toString());
            } catch (InterruptedException ex) {
                System.out.println(ex.toString());
            }
        }

    }

Sometimes it works fine but other times it will get to the folder window and not paste in the correct text.

Any ideas on why this isn't working or if there is a better way?

Thanks!


Solution

  • It's better to use the appleScript's save command instead of using the keystroke command

    public static void closeQT(){
            //Pause the recording, save and quit
            try {
                String[] go = {"osascript", "-e", "set tFile to \""+fullPosixPathOfFile+"\" as posix file", "-e", "do shell script \"touch \" & quoted form of posix path of tFile", "-e", "tell application \"QuickTime Player\"", "-e", "pause document 1", "-e", "save document 1 in tFile", "-e", "stop document 1", "-e", "close document 1 saving no", "-e", "quit", "-e", "end tell"};
                Process process = Runtime.getRuntime().exec(go);
                process.waitFor();
            } catch (IOException ex) {
                System.out.println(ex.toString());
            } catch (InterruptedException ex) {
                System.out.println(ex.toString());
            }
        }
    

    put the file path where you want to save the movie in the fullPosixPathOfFile variable


    Here's an example of an AppleScript that works

    set tFile to (path to desktop folder as string) & "MyMovie.mov" -- save the movie to the desktop
    
    do shell script "touch " & quoted form of POSIX path of tFile  --  "QuickTime Player" need an existing file (otherwise permissions issue), so the touch command create an empty file 
    tell application "QuickTime Player"
        launch
        set newMovieRec to new movie recording
        tell newMovieRec
            start
            delay 10 -- duration in seconds of this new movie
            pause
            save in (file tFile) -- The term "file" is necessary when the type of the path is HFS (path with colon character --> "diskName:folder1:subFolder2:myMovie.mov")
            --save in tFile -- use this line when the tFile variable contains a posix file (a posix path converted to a posix file)
            stop
            close saving no
        end tell
        quit
    end tell
    

    To check the version of Quicktime:

    tell application "QuickTime Player"
        set v to version
        considering numeric strings
            set newVersion to v > "7.6.6" -- change it to the old version which not work
        end considering
        if newVersion then
            -- code to save
        else
            -- code to save as
        end if
    end tell