Last active
May 23, 2019 09:12
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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