"""Detect silent intervals at beginning and end of audio.""" 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 JOB_INPUTS = [ 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.AUDIO_STREAM_DURATION_SECONDS, ] @activity_task_logger(JOB_INPUTS) def detect_silent_intervals_at_beginning_and_end_of_audio(inputs): """Detect silent intervals at beginning and end of audio. 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.AUDIO_STREAM_DURATION_SECONDS] # silencedetect parameters # https://ffmpeg.org/ffmpeg-filters.html#silencedetect duration = seconds_per_frame noise = '-90dB' output_options = { 'vn': None, # don't process video stream } video_s3_url = s3_connector.get_url_for_s3_object(s3_bucket, s3_key) (stdout, stderr) = ( ffmpeg .input(video_s3_url) .filter( 'silencedetect', duration=duration, noise=noise, ) .output('pipe:', format='null', **output_options) .run(capture_stderr=True) ) silence_start_regex = r'silence_start:\s*(\S*)' silence_end_regex = r'silence_end:\s*(\S*)' stderr_lines = text.bytes_to_lines_of_text(stderr) outputs = { job_io_fields.SILENT_INTERVAL_AT_BEGINNING_ENDS_AT_SECONDS: None, job_io_fields.SILENT_INTERVAL_AT_END_BEGINS_AT_SECONDS: None, } silence_start = None silence_end = None for line in stderr_lines: silence_start_match = re.search(silence_start_regex, line) if silence_start_match: silence_start = float(silence_start_match.group(1)) silence_end_match = re.search(silence_end_regex, line) if silence_end_match: silence_end = float(silence_end_match.group(1)) if silence_start == 0 and silence_end: outputs[ job_io_fields.SILENT_INTERVAL_AT_BEGINNING_ENDS_AT_SECONDS ] = silence_end if silence_end and silence_end >= duration_seconds: outputs[ job_io_fields.SILENT_INTERVAL_AT_END_BEGINS_AT_SECONDS ] = silence_start return outputs