import argparse import json import subprocess import boto3 from botocore.exceptions import ClientError client = boto3.client('s3', region_name='us-east-1') def upload_s3_file(source_path: str, destination_bucket: str, destination_key: str) -> None: """Copy file from source_path to s3 bucket. Args: source_path (str): Source file path. destination_bucket (str): S3 bucket. destination_key (str): S3 bucket key. Returns: response.Response: Response with success or error message. Raises: ClientError: If ClientError happens during upload. Exception: In case of any other error during upload. """ try: file_body = open(source_path, 'rb') upload_response = client.upload_fileobj( file_body, destination_bucket, destination_key, ExtraArgs={'ACL': 'public-read'} ) return upload_response except ClientError as e: error_code = e.response['Error']['Code'] error_message = 'S3 file upload failed with code {code}'.format( code=error_code) print(error_message) raise e except Exception as e: error_message = 'S3 file upload failed with error {error}'.format( error=(str(e))) print(error_message) raise e def sign_url(bucket: str, key: str) -> str: return client.generate_presigned_url( 'get_object', Params={'Bucket': bucket, 'Key': key}, ExpiresIn=86400 ) def public_url(bucket: str, key: str) -> str: return 'https://{}.s3.amazonaws.com/{}'.format(bucket, key) def handler(bucket: str, key: str) -> bool: """worker main handler.""" try: print(key) if '.json' in key: f = client.get_object(Bucket=bucket, Key=key) instructions = json.loads(f['Body'].read()) with open('textfile.txt', 'w') as txt_file: txt_file.write(instructions['song']) txt_file.write('by \n') txt_file.write(instructions['artist']) filter_complex = '[1:v]scale=800:800,format=argb,colorchannelmixer=aa=0.9 [ovrl], ' \ '[0:v][ovrl]overlay=x=\'if(lte(-w+(t)*100,100),-w+(t)*100,100)\':y=(main_h-overlay_h)/2, ' \ 'drawtext=fontfile=FreigMicMedIta.ttf:' \ 'textfile=textfile.txt: ' \ 'x=10: y=10: ' \ 'fontsize=60: ' \ 'box=1: boxcolor=black@0.8: bordercolor=orange@0.8: borderw=3: boxborderw=5: alpha=0.7: ' \ 'fontcolor=white@0.8' process = subprocess.Popen( [ 'ffmpeg', '-stream_loop', '-1', '-i', sign_url(bucket, instructions['template']), '-i', sign_url(bucket, instructions['image']), '-i', sign_url(bucket, instructions['audio']), '-filter_complex', filter_complex, '-shortest', '-map', '0:v:0', '-map', '2:a:0', '-y', 'out.mp4' ], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True ) out, err = process.communicate() print(out, err) upload_s3_file('/var/app/out.mp4', bucket, instructions['output']) return True except Exception as e: print(key, str(e)) raise e if __name__ == '__main__': parser = argparse.ArgumentParser(prog='video_generator') parser.add_argument('-b', '--bucket', required=True, help='bucket') parser.add_argument('-o', '--object', required=True, help='object') args = parser.parse_args() handler(bucket=args.bucket, key=args.object)