Auto-recording in Quicktime, device in use?

I am trying to set up a “poor man’s DVR” and use Quicktime (Player 7, in Snow Leopard) to automatically start recording when the computer starts up (on a schedule). I have a DV camera connected to my Mac with Firewire, and it’s got the video from the vcr coming in. My script, which used to work under 10.5, is giving an error whenever QT opens a new recording, saying that the device is in use. I have no idea what is trying to capture the device on startup. But I am trying to use some GUI scripting to press the OK button on the sheet, in order to dismiss it, and then I think after dismissing it, a new recording can be successfully started.

“The device “GR-D70” could not be opened because it is in use by another application. Stop any operations that are using the device “GR-D70”, wait for those operations to complete, or quit the application using the device.”

Here’s the script I have so far, and I’ve tried several permutations on it already with no success. I’ll also point out that the Mac will be starting up from the Energy Saver schedule. If you test this and can replicate the error, you can’t just restart, that somehow keeps the Firewire input clear and the error does not occur. You have to shut down and then cold start it.


tell application "QuickTime Player 7"
	try
		activate
		new movie recording
		start first recording
		
		delay 30 --90000
		--3600 is 1 hour, 1800 =1/2 hour, 60 =1 min, 300 =5 mins
		--add 300 (5 mins) ahead/behind starting
		stop first recording
	on error
		tell application "QuickTime Player 7"
			activate
			tell first recording
				activate
			end tell
			tell application "System Events"
				tell process "Quicktime Player 7"
					keystroke return
				end tell
			end tell
		end tell
		close window 1 saving no
		
		new movie recording
		start first recording
		
		delay 30 --90000
		stop first recording
	end try
end tell

I will offer some other solutions. First I would try to find out why the device is busy and fix that. My application What’s Keeping Me found here could help you with that. If you can’t figure it out then…

Second, from your description it sounds like the device is only busy for a short time. So I would use a delay of some kind to wait for the device to be free before I tried to start a recording. This would eliminate the error dialog.

I wrote you a handler to perform the delay. This uses cocoa methods to check the device’s busy state, and when the device becomes not-busy it exits the handler. So you just need to call this handler at the start of your script, when the handler returns to your code you can safely proceed with the rest of your script. There is something you have to do first. You need to know the unique ID of the device you’re interested in. So this first script will return a list of all the devices you have connected. Find your device name and copy the unique ID for use in the next script.

tell application "Automator Runner"
	set theDevices to call method "inputDevices" of class "QTCaptureDevice"
	
	set attributesList to {}
	repeat with aDevice in theDevices
		try
			set isInUse to call method "isInUseByAnotherApplication" of aDevice
			set theName to call method "localizedDisplayName" of aDevice
			set uniqueID to call method "uniqueID" of aDevice
			set end of attributesList to {isInUse, theName, uniqueID}
		end try
	end repeat
	return attributesList
end tell

Now you use that unique ID is this handler waitForQTDeviceToBeFree that I mentioned earlier. You can see that I’m using the unique ID of my iSight camera since I don’t have a DV camera to test this on. You pass in the device unique ID, a max wait time which is the max time you are prepared to wait for the busy device to become free (I’m using 30 seconds), and a pause time which is the time the repeat loop pauses between checks for the busy state (I’m using 1 second). I hope that makes sense…

set isFree to waitForQTDeviceToBeFree("0xfd40000005ac8501", 30, 1)
if isFree is false then
	display dialog "The device is not free so I cannot continue!" buttons {"OK"} default button 1
	return
end if

on waitForQTDeviceToBeFree(deviceUniqueID, maxWaitTime, delayTime)
	set startTime to current date
	tell application "Automator Runner"
		set theDevice to call method "deviceWithUniqueID:" of class "QTCaptureDevice" with parameter deviceUniqueID
		
		repeat
			set isInUse to call method "isInUseByAnotherApplication" of theDevice
			if isInUse is 0 then return true
			if ((current date) - startTime) is greater than maxWaitTime then return false
			delay delayTime
		end repeat
	end tell
end waitForQTDeviceToBeFree

Thanks for the great suggestion and code. Sadly none of that worked. And since I’m leaving for vacation I needed to get it running asap. I ended up reinstalling an old clone of Tiger onto one of my drives and used the old script that worked properly.
Maybe later I’ll go back and try to figure out a reasonable solution.

Sorry to hear it didn’t work. Post back later when you have a chance to troubleshoot.