Skip to content

Instantly share code, notes, and snippets.

@robinvanemden
Last active May 23, 2019 09:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robinvanemden/025058f7e68d6f0fdea81d81a6094165 to your computer and use it in GitHub Desktop.
Save robinvanemden/025058f7e68d6f0fdea81d81a6094165 to your computer and use it in GitHub Desktop.
Basic Python script for fast extraction of stills from videos through calls to ffmpeg using filenames and timestamps from an SPSS file
import os
import subprocess
import pyreadstat
import logging
import datetime
# configuration
input_directory = 'C:/Users/robin/PycharmProjects/asmir_cry_project/in'
output_directory = 'C:/Users/robin/PycharmProjects/asmir_cry_project/out'
spss_file = "C:/Users/robin/PycharmProjects/asmir_cry_project/crying_points_and_periods.sav"
# setup logging
def setup_logger(name, log_file, level=logging.INFO):
handler = logging.FileHandler(log_file, mode='w')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger = logging.getLogger(name)
logger.setLevel(level)
logger.addHandler(handler)
return logger
success_log = setup_logger('success', 'success.log')
fail_log = setup_logger('failure', 'fail.log')
# case insensitive file matching
def getfile_insensitive(path):
directory, filename = os.path.split(path)
directory, filename = (directory or '.'), filename.lower()
for f in os.listdir(directory):
newpath = os.path.join(directory, f)
if os.path.isfile(newpath) and f.lower() == filename:
return newpath
def isfile_insensitive(path):
return getfile_insensitive(path) is not None
# main
def extract_frame(video_name, ss_time, in_dir, out_dir, name_append=""):
if not os.path.exists(out_dir):
os.makedirs(out_dir)
output_name = os.path.splitext(video_name)[0] + name_append + ".jpg"
video_with_path_and_ext = os.path.join(in_dir, video_name)
if isfile_insensitive(video_with_path_and_ext + ".wmv"):
video_with_path_and_ext = getfile_insensitive(video_with_path_and_ext + ".wmv")
elif isfile_insensitive(video_with_path_and_ext + ".mp4"):
video_with_path_and_ext = getfile_insensitive(video_with_path_and_ext + ".mp4")
else:
fail_log.info(video_name + " " + ss_time + " file_missing")
return
output_name = os.path.join(out_dir, output_name)
try:
subprocess.call(['ffmpeg', '-y', '-ss', ss_time, '-i', video_with_path_and_ext, '-vframes', '1',
'-q:v', '2', output_name])
except subprocess.CalledProcessError:
fail_log.info(video_name + " " + ss_time + " conversion_failed")
return
success_log.info(video_name + " " + ss_time + " conversion_completed")
df, meta = pyreadstat.read_sav(spss_file)
for index, row in df.iterrows():
file_name = str.strip(row['file_name'])
start_time = datetime.datetime.strptime(row["start_time"].lstrip(), '%M:%S').strftime('%H:%M:%S')
string_time = start_time.replace(':', '_')
crying_type = "__" + string_time + "__" + str(int(row["crying_type"]))
extract_frame(file_name, start_time, input_directory, output_directory, crying_type)
logging.shutdown()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment