Python: Automating Analog Video Capture with pyautogui

Early in December I was talking to a co-worker about how expensive tape-to-digital conversion was. I was charged over $60 locally for less than a couple hours of tape – and when I saw their setup, it was an Elgato Video Capture device. I put it on my Amazon wishlist, and it went on sale (almost immediately after I had the aforementioned conversation) for $50-ish. I bought it, and I’ve been impressed with the results, so I volunteered to do a bunch of conversions (8MM) for my parents.

The end product is good, but the software managing the capture is a little bit clunky and doesn’t “sense” when a tape hits dead air, which means I have to babysit the process or let it take a long time and then trim it back down to size. The process goes like this:

  1. Give your project (video) a name.
  2. Click continue a couple times confirming that the device is receiving video and audio.
  3. Click a big red button to “Start Recording”.
  4. When you hit the point on the tape where there is no more content, you click “Stop Recording”.
  5. You are then given the opportunity to trim the beginning and end of the capture, and click continue.
  6. “Please wait while the movie is being processed.” For a long capture, this can take a half hour.
  7. Done!

So, this is a perfect opportunity to use what I learned in the last chapter of Al Sweigart’s (free) book “Automate the Boring Stuff with Python” regarding automating programs that cannot be manipulated through other means. Al wrote a really useful Python module that uses image recognition to automate, called pyautogui. I have been looking for a good opportunity to use this, because most of the tasks I run into can be broken down into a faster (and more efficient) manipulation type. Elgato’s video capture interface doesn’t let me intervene through an API, so this was perfect.

import pyautogui
import time
import requests
def ifttt_alert():"")

nosignal = pyautogui.locateOnScreen('no-signal.png', grayscale=True)
while nosignal is None:
    print("Still getting signal.")
    nosignal = pyautogui.locateCenterOnScreen('no-signal.png', grayscale=True)
    if nosignal is not None:
        print("Looks like the signal went out. Giving it 20 seconds to recover.")
        nosignal = pyautogui.locateCenterOnScreen('no-signal.png', grayscale=True)
print("Stopping recording.")
stoprecording = pyautogui.locateCenterOnScreen('stoprecording.png', grayscale=True)
continuebutton = pyautogui.locateCenterOnScreen('continue.png', grayscale=True)
pleasewait = pyautogui.locateCenterOnScreen('pleasewait.png', grayscale=True)
while pleasewait is not None:
    pleasewait = pyautogui.locateCenterOnScreen('pleasewait.png', grayscale=True)
print("Process complete.")

It’s pretty straightforward. The idea is that I have to be there to cue up the tape, so I can manually handle starting the program and hitting play on the camcorder. Then I start this script and it is constantly scraping the screen for an image that looks like this: 
If the script detects that image, then it is going to give the signal 20 seconds to recover. It’s possible that there is just a break on the tape between recordings, and this gives us a chance to see if there is more before we shut down. If 20 seconds do pass, and the image is still found on the screen, we click “Stop Recording”, which looks like this: 

We then give it ten seconds to wrap up it’s process (which is generous, but just in case) and click the “Continue” button. 

Now this is the point where we run into the “Please wait while the movie is being processed” part. So we are going to search the screen every 10 seconds for the following image until it doesn’t exist on the screen anymore.

When it doesn’t exist anymore, the process is finished. As an added bonus, I make an API call to the IFTTT service that will then send a notification to my phone letting me know that it’s time to cue up another tape. The only thing left to do is to rewind the current tape – which I’m actually trying to find out if it’s possible to use an IR blaster to do that!

This was a lot of fun, just had to share.