"""Detect black intervals at beginning and end of video.""" import re import ffmpeg from video.connectors import s3 as s3_connector from video.constants import job_io_fields from video.logic.activity_task_logger import activity_task_logger from video.utils import text INPUT_FIELDS = [ job_io_fields.INPUT_VIDEO_S3_BUCKET, job_io_fields.INPUT_VIDEO_S3_KEY, job_io_fields.VIDEO_STREAM_FRAME_RATE_FRAMES_PER_SECOND, job_io_fields.VIDEO_STREAM_DURATION_SECONDS, ] @activity_task_logger(INPUT_FIELDS) def detect_black_intervals_at_beginning_and_end_of_video(inputs): """Detect black intervals at beginning and end of video. Args: inputs (dict): Inputs. Returns: dict: Outputs. """ s3_bucket = inputs[job_io_fields.INPUT_VIDEO_S3_BUCKET] s3_key = inputs[job_io_fields.INPUT_VIDEO_S3_KEY] frames_per_second = inputs[ job_io_fields.VIDEO_STREAM_FRAME_RATE_FRAMES_PER_SECOND] seconds_per_frame = 1 / frames_per_second duration_seconds = inputs[job_io_fields.VIDEO_STREAM_DURATION_SECONDS] last_frame_start_time = duration_seconds - seconds_per_frame # blackdetect parameters # https://ffmpeg.org/ffmpeg-filters.html#blackdetect black_min_duration = seconds_per_frame picture_black_ratio_th = 1 pixel_black_th = 0 output_options = { 'an': None, # don't process audio stream } video_s3_url = s3_connector.get_url_for_s3_object(s3_bucket, s3_key) (stdout, stderr) = ( ffmpeg .input(video_s3_url) .filter( 'blackdetect', black_min_duration=black_min_duration, picture_black_ratio_th=picture_black_ratio_th, pixel_black_th=pixel_black_th, ) .output('pipe:', format='null', **output_options) .run(capture_stderr=True) ) black_start_regex = r'black_start:\s*(\S*)' black_end_regex = r'black_end:\s*(\S*)' stderr_lines = text.bytes_to_lines_of_text(stderr) outputs = { job_io_fields.BLACK_INTERVAL_AT_BEGINNING_ENDS_AT_SECONDS: None, job_io_fields.BLACK_INTERVAL_AT_END_BEGINS_AT_SECONDS: None, } black_start = None black_end = None for line in stderr_lines: black_start_match = re.search(black_start_regex, line) if black_start_match: black_start = float(black_start_match.group(1)) black_end_match = re.search(black_end_regex, line) black_end = float(black_end_match.group(1)) if black_start == 0: outputs[ job_io_fields.BLACK_INTERVAL_AT_BEGINNING_ENDS_AT_SECONDS ] = black_end if black_end == last_frame_start_time: outputs[ job_io_fields.BLACK_INTERVAL_AT_END_BEGINS_AT_SECONDS ] = black_start return outputs