def update_channel(mediapackage, event, context): """ Update a MediaPackage channel Return the channel URL, username and password generated by MediaPackage """ if 'PhysicalResourceId' in event: channel_id = event["PhysicalResourceId"] else: channel_id = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) try: result = delete_channel(mediapackage, event, context) if result['Status'] == 'SUCCESS': result = create_channel(mediapackage, event, context, False) except Exception as ex: print(ex) result = { 'Status': 'FAILED', 'Data': { "Exception": str(ex) }, 'ResourceId': channel_id } return result
def create_endpoint(mediapackage, event, context, auto_id=True): """ Create a MediaPackage channel Return the channel URL, username and password generated by MediaPackage """ if auto_id: endpoint_id = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) else: endpoint_id = event["PhysicalResourceId"] channel_id = event["ResourceProperties"]["ChannelId"] rotation_interval = event["ResourceProperties"]["RotationInterval"] role_arn = event["ResourceProperties"]["RoleArn"] server_url = event["ResourceProperties"]["ServerUrl"] try: response = mediapackage.create_origin_endpoint( Id=endpoint_id, Description="CloudFormation Stack ID %s" % event["StackId"], ChannelId=channel_id, ManifestName="index", StartoverWindowSeconds=0, HlsPackage={ "SegmentDurationSeconds": 6, "PlaylistWindowSeconds": 60, "PlaylistType": "event", "AdMarkers": "none", "IncludeIframeOnlyStream": True, "UseAudioRenditionGroup": True, "StreamSelection": { "StreamOrder": "original" }, "Encryption": { "EncryptionMethod": "AES_128", "KeyRotationIntervalSeconds": int(rotation_interval), "RepeatExtXKey": False, "SpekeKeyProvider": { "ResourceId": str(uuid.uuid4()), "RoleArn": role_arn, "SystemIds": ["81376844-f976-481e-a84e-cc25d39b0b33"], "Url": server_url } } }) print(json.dumps(response)) outputs = {"OriginEndpointUrl": response['Url']} result = { 'Status': 'SUCCESS', 'Data': outputs, 'ResourceId': endpoint_id } except Exception as ex: print(ex) result = { 'Status': 'FAILED', 'Data': { "Exception": str(ex) }, 'ResourceId': endpoint_id } return result
def delete_channel(mediapackage, event, context): """ Delete a MediaPackage channel Return success/failure """ if 'PhysicalResourceId' in event: channel_id = event["PhysicalResourceId"] else: channel_id = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) try: response = mediapackage.delete_channel(Id=channel_id) result = { 'Status': 'SUCCESS', 'Data': response, 'ResourceId': channel_id } except Exception as ex: print(ex) result = { 'Status': 'FAILED', 'Data': { "Exception": str(ex) }, 'ResourceId': channel_id } return result
def update_configuration(mediatailor, event, context): """ Update a mediatailor configuration Return the configuration URL generated by mediatailor """ if 'PhysicalResourceId' in event: channel_id = event["PhysicalResourceId"] else: channel_id = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) try: result = delete_configuration(mediatailor, event, context) if result['Status'] == 'SUCCESS': result = create_configuration(mediatailor, event, context, False) except Exception as ex: print(ex) result = { 'Status': 'FAILED', 'Data': {"Exception": str(ex)}, 'ResourceId': channel_id } return result
def lambda_handler(event, context): """ Lambda entry point. Print the event first. """ print("Event Input: %s" % json.dumps(event)) settings_table = event["ResourceProperties"]["SettingsTable"] result = {'Status': 'SUCCESS', "StackId": event["StackId"], "RequestId": event["RequestId"], "LogicalResourceId": event["LogicalResourceId"], 'Data': {}, 'ResourceId': settings_table} if event.get("PhysicalResourceId", False): result["PhysicalResourceId"] = event["PhysicalResourceId"] else: result["PhysicalResourceId"] = "{}-{}".format(resource_tools.stack_name(event), event["LogicalResourceId"]) try: if event["RequestType"] == "Create" or event["RequestType"] == "Update": print(event["RequestType"]) make_default_settings(settings_table) except ClientError as client_error: print("Exception: %s" % client_error) result = { 'Status': 'FAILED', "StackId": event["StackId"], "RequestId": event["RequestId"], "LogicalResourceId": event["LogicalResourceId"], 'Data': { "Exception": str(client_error) }, 'ResourceId': None } resource_tools.send(event, context, result['Status'], result['Data'], result["PhysicalResourceId"])
def create_channel(mediapackage, event, context, auto_id=True): """ Create a MediaPackage channel Return the channel URL, username and password generated by MediaPackage """ if auto_id: channel_id = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) else: channel_id = event["PhysicalResourceId"] channel = { "Id": channel_id, "Description": "CloudFormation Stack ID %s" % event["StackId"], "HlsIngest": {} } try: response = mediapackage.create_channel( Id=channel_id, Description="CloudFormation Stack ID %s" % event["StackId"]) print(json.dumps(response)) print(response["Arn"]) attributes = { "Arn": response["Arn"], "PrimaryUrl": response["HlsIngest"]["IngestEndpoints"][0]["Url"], "PrimaryUsername": response["HlsIngest"]["IngestEndpoints"][0]["Username"], "PrimaryPassword": response["HlsIngest"]["IngestEndpoints"][0]["Password"], "SecondaryUrl": response["HlsIngest"]["IngestEndpoints"][1]["Url"], "SecondaryUsername": response["HlsIngest"]["IngestEndpoints"][1]["Username"], "SecondaryPassword": response["HlsIngest"]["IngestEndpoints"][1]["Password"] } print(attributes) result = { 'Status': 'SUCCESS', 'Data': attributes, 'ResourceId': channel_id } except Exception as ex: print(ex) result = { 'Status': 'FAILED', 'Data': { "Exception": str(ex) }, 'ResourceId': channel_id } return result
def create_channel(medialive, event, context, auto_id=True): """ Create a MediaLive channel Return the channel URL, username and password generated by MediaLive """ if auto_id: channel_id = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) else: channel_id = event["PhysicalResourceId"] try: destinations = { 'p_url': event["ResourceProperties"]["PackagerPrimaryChannelUrl"], 'p_u': event["ResourceProperties"]["PackagerPrimaryChannelUsername"], 'p_p': event["ResourceProperties"]["PackagerPrimaryChannelPassword"], 'b_url': event["ResourceProperties"]["PackagerSecondaryChannelUrl"], 'b_u': event["ResourceProperties"]["PackagerSecondaryChannelUsername"], 'b_p': event["ResourceProperties"]["PackagerSecondaryChannelPassword"] } print("The Destinations are: %s \n" % destinations) channel_id = create_live_channel( event["ResourceProperties"]["MediaLiveInputId"], channel_id, event["ResourceProperties"]["Resolutions"], destinations, event["ResourceProperties"]["MediaLiveAccessRoleArn"], medialive) result = {'Status': 'SUCCESS', 'Data': {}, 'ResourceId': channel_id} # wait until the channel is idle, otherwise the lambda will time out resource_tools.wait_for_channel_states(medialive, channel_id, ['IDLE']) if event['State'] == "ON": medialive.start_channel(ChannelId=channel_id) except Exception as ex: print(ex) result = { 'Status': 'FAILED', 'Data': { "Exception": str(ex) }, 'ResourceId': channel_id } return result
def create_endpoint(mediapackage, event, context, auto_id=True): """ Create a MediaPackage channel Return the channel URL, username and password generated by MediaPackage """ if auto_id: endpoint_id = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) else: endpoint_id = event["PhysicalResourceId"] channel_id = event["ResourceProperties"]["ChannelId"] try: response = mediapackage.create_origin_endpoint( Id=endpoint_id, Description="CloudFormation Stack ID %s" % event["StackId"], ChannelId=channel_id, ManifestName="index", StartoverWindowSeconds=3600, HlsPackage={ "SegmentDurationSeconds": 6, "PlaylistWindowSeconds": 60, "PlaylistType": "event", "AdMarkers": "none", "IncludeIframeOnlyStream": True, "UseAudioRenditionGroup": True, "StreamSelection": { "StreamOrder": "original" } }) print(json.dumps(response)) outputs = {"OriginEndpointUrl": response['Url']} result = { 'Status': 'SUCCESS', 'Data': outputs, 'ResourceId': endpoint_id } except Exception as ex: print(ex) result = { 'Status': 'FAILED', 'Data': { "Exception": str(ex) }, 'ResourceId': endpoint_id } return result
def create_configuration(mediatailor, event, context, auto_id=True): """ Create a mediatailor configuration Return the configuration URL generated by mediatailor """ if auto_id: channel_id = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) else: channel_id = event["PhysicalResourceId"] try: response = mediatailor.put_playback_configuration( Name = channel_id, AdDecisionServerUrl = event["ResourceProperties"]['AdDecisionServerUrl'], DashConfiguration = { 'MpdLocation': 'DISABLED' }, CdnConfiguration={ 'AdSegmentUrlPrefix': event["ResourceProperties"]['AdSegmentUrlPrefix'], 'ContentSegmentUrlPrefix': event["ResourceProperties"]['ContentSegmentUrlPrefix'] }, SlateAdUrl = event["ResourceProperties"]["SlateAdUrl"], TranscodeProfileName = event["ResourceProperties"]["TranscodeProfileName"], VideoContentSourceUrl = event["ResourceProperties"]["VideoContentSourceUrl"] ) print(json.dumps(response)) result = { 'Status': 'SUCCESS', 'Data': response, 'ResourceId': channel_id } except Exception as ex: print(ex) result = { 'Status': 'FAILED', 'Data': {"Exception": str(ex)}, 'ResourceId': channel_id } return result
def create_input(medialive, event, context, auto_id=True): """ Create a MediaLive input """ if auto_id: input_id = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) else: input_id = event["PhysicalResourceId"] try: response = medialive.create_input( Name=input_id, Type="%s" % event["ResourceProperties"]["InputType"], InputSecurityGroups=event["ResourceProperties"] ["InputSecurityGroup"]) print(json.dumps(response)) # wait for the new input to reach detached state resource_tools.wait_for_input_states(medialive, response['Input']['Id'], ['DETACHED']) result = { 'Status': 'SUCCESS', 'Data': response, 'ResourceId': response['Input']['Id'] } except Exception as ex: print(ex) result = { 'Status': 'FAILED', 'Data': { "Exception": str(ex) }, 'ResourceId': response['Input']['Id'] } return result
def lambda_handler(event, context): print("Event Input: %s" % json.dumps(event)) emt_client = boto3.client('mediatailor') # get environment variables distribution_id = os.environ["CloudFrontDistributionId"] video_source = os.environ["VideoSource"] ad_server = os.environ["ADS"] # make up the configuration name emt_config_name = "%s-%s" % (resource_tools.stack_name(event), event["LogicalResourceId"]) response = {} result = { "Status": "SUCCESS", "Data": response, "ResourceId": emt_config_name } if event["RequestType"] == "Create" or event["RequestType"] == "Update": cf_client = boto3.client('cloudfront') session = boto3.session.Session() region = session.region_name # all the info we need to set up a proper distribution parsed_url = urlparse(video_source) source_domain_name = parsed_url.netloc # remove the asset name (eg. index.m3u8) from the path url_path_list = parsed_url.path.split('/') asset_name = url_path_list.pop(-1) source_path = ('/').join(url_path_list) # CloudFront distro info distribution_info = cf_client.get_distribution(Id = distribution_id) distribution_domain_name = distribution_info['Distribution']['DomainName'] distribution_config = distribution_info['Distribution']['DistributionConfig'] etag = distribution_info['ETag'] cdn_prefix = "https://" + distribution_domain_name cdn_segment_prefix = cdn_prefix + source_path video_source_without_asset_name = "https://" + source_domain_name + source_path emt_data = {} try: emt_data = emt_client.put_playback_configuration( AdDecisionServerUrl=ad_server, Name=emt_config_name, VideoContentSourceUrl=video_source_without_asset_name, CdnConfiguration={ "AdSegmentUrlPrefix": cdn_prefix, "ContentSegmentUrlPrefix": cdn_segment_prefix } ) parsed_emt_url = urlparse(emt_data["HlsConfiguration"]["ManifestEndpointPrefix"]) hls_playback_path = parsed_emt_url.path ads_domain_name = "ads.mediatailor." + region + ".amazonaws.com" meditailor_domain_name = parsed_emt_url.netloc result["Data"] = { "ConfigurationName": emt_config_name, "HLSPlaybackURL": emt_data["HlsConfiguration"]["ManifestEndpointPrefix"] + asset_name, "CloudFrontPlaybackURL": cdn_prefix + hls_playback_path + asset_name } #update the origins of the CloudFront Distribution response = update_distribution_origins(cf_client, distribution_config, distribution_id, etag, source_domain_name, meditailor_domain_name, ads_domain_name ) print("CloudFront update origins response: %s" % response) #if successful, update the cache behaviors of the distribution if response['ResponseMetadata']['HTTPStatusCode'] == 200: #get the latest distribution information after origin update distribution_info = cf_client.get_distribution(Id = distribution_id) distribution_config = distribution_info['Distribution']['DistributionConfig'] etag = distribution_info['ETag'] response = update_distribution_cache_behaviors(cf_client, distribution_config, distribution_id, etag) if response['ResponseMetadata']['HTTPStatusCode'] == 200: print("CloudFront update cache behaviors response: %s" % response) else: result["Status"] = "FAILED", except Exception as exp: print("Exception: %s" % exp) result["Status"] = "FAILED" result["Data"] = {"Exception": str(exp)} elif event["RequestType"] == "Delete": try: result["Data"] = emt_client.delete_playback_configuration(Name=emt_config_name) except Exception as exp: print("Exception: %s" % exp) result["Status"] = "FAILED", result["Data"] = {"Exception": str(exp)} resource_tools.send(event, context, result["Status"], result["Data"], result["ResourceId"]) return