def probe_video(self, video_file): if os.path.exists(self.job.source_file): success('source probe info exists') return info('probing video...') probe = ffmpeg.probe(video_file) store_json(probe, self.job.source_file)
def publish_html(self): info('generating html...') video_id = self.job.video_source_name # video_type = self.job.video_type # force it to use the local template, even for youtube videos video_type = 'local' copyfile('templates/template-' + video_type + '.html', self.job.result_html_file) if video_type == 'youtube': video_id = YouTube(self.job.video_url).video_id subjects = Path(self.job.subjects_file).read_text() matches = Path(self.job.matches_file).read_text() results = Path(self.job.results_file).read_text() with fileinput.FileInput(self.job.result_html_file, inplace=True) as file: for line in file: print( line.replace('%frame_interval_seconds%', str(self.job.frame_interval_seconds)) .replace('%video_id%', video_id) .replace('%video_url_mp4%', self.job.video_source_path) .replace('%video_poster_url%', self.job.video_poster_path) .replace('%subjects%', subjects) .replace('%matches%', matches) .replace('%results%', results) , end='') success('stored to ' + self.job.result_html_file) webbrowser.open('file:///' + self.job.result_html_file, new=2)
def extract_frames(self, area_key, output_dir): # extract frames info('extracting frames from ' + area_key + ' area ...') # area definitions crop_areas = { 'rt': ('(in_w/4)*3', '0', 'in_w/4', 'in_h/3'), 'rb': ('(in_w/4)*3', '(in_h/3)*2', 'in_w/4', 'in_h/3'), 'lt': ('0', '0', 'in_w/4', 'in_h/3'), 'lb': ('0', '(in_h/3)*2', 'in_w/4', 'in_h/3'), } crop_area = crop_areas.get(area_key) create_dir(output_dir) # for area_key, crop_area in crop_areas.items(): try: ( ffmpeg .input(self.job.video_source_path) .crop(*crop_area) .filter('fps', '1/' + str(self.job.frame_interval_seconds)) .output(os.path.join(output_dir, '%05d.jpg')) .run(quiet=True, capture_stderr=True) ) except ffmpeg.Error as err: # decode error message and print to stdout # from: https://stackoverflow.com/a/37059682/580651 error(codecs.escape_decode(err.stderr)[0].decode("utf-8")) success('stored ' + str(len(glob.glob(os.path.join(output_dir, '*.jpg')))) + ' frames to ' + output_dir)
def download_subjects(self): if os.path.exists(self.job.subjects_dir): success('subjects exists') return create_dir(self.job.subjects_dir) # delegate to handler self.job.handler.download_subjects(self.job)
def download_subjects(self, job): # download subjects info('downloading subjects definition from "' + self.xml_stats_url + '"...') # download xml stats_xml = os.path.join(job.job_dir, 'subjects.xml') urllib.request.urlretrieve(self.xml_stats_url, stats_xml) # parse xml to json root = ET.parse(stats_xml).getroot() subjects = parker.data( root.find("./achievements"), preserve_root=True).get('achievements').get('achievement') store_json(subjects, job.subjects_file) # download icons info('downloading subjects...') i = 0 total = len(subjects) progress(i, total) for subject in subjects: subject_url = subject.get('iconClosed') urllib.request.urlretrieve( subject_url, os.path.join(job.subjects_dir, ntpath.basename(subject_url))) i = i + 1 progress(i, total) success('stored ' + str(len(glob.glob(os.path.join(job.subjects_dir, "*.jpg")))) + ' subjects to ' + job.subjects_dir)
def store_json(payload, file): # store the whole result to json to be worked with somewhere else def default(o): if isinstance(o, np.int64): return int(o) raise TypeError json.dump(payload, codecs.open(file, 'w', encoding='utf-8'), separators=(',', ':'), sort_keys=True, indent=4, default=default) success('stored to ' + file)
def extract_poster(self, video_file, output, time): if os.path.exists(self.job.video_poster_path): success('poster exists') return info('extracting poster at ' + str(int(time)) + '...') try: ( ffmpeg.input(video_file, ss=time) .output(output, vframes=1) .overwrite_output() .run(quiet=True, capture_stderr=True) ) except ffmpeg.Error as err: error(codecs.escape_decode(err.stderr)[0].decode("utf-8"))
def download_video(self): if os.path.isfile(self.job.video_source_path): success('source video exists') return info('downloading "' + self.job.video_url + '"...') create_dir(self.job.source_dir) if self.job.video_type == 'youtube': # from: https://stackoverflow.com/a/46562895/580651 YouTube(self.job.video_url).streams.first() \ .download(output_path=self.job.source_dir, filename=self.job.job_id) if self.job.video_type == 'local': extension = Path(self.job.video_url).suffix copy(self.job.video_url, os.path.join(self.job.source_dir, self.job.video_source_name + extension)) success('stored to ' + self.job.source_dir)