구축 계획

  1. MediaConvert의 Job 상태가 변할 때 마다 CloudWatch 에서 Event를 발생시킨다.
  2. Event가 Lambda function을 실행시키는 트리거가 된다.
  3. WAS System으로 특정 API를 호출하여 관련 정보를 업데이트 할 수 있게 한다.

범위

참고: VOD Streaming Server 구축 1 (AWS)
참고: VOD Streaming Server 구축 2 (AWS)
참고: VOD Streaming Server 구축 3 (AWS)
참고: VOD Streaming Server 구축 4 (AWS)

  1. CloudWatch 에 MediaConvert Job Event를 발생시켜 Lambda function에 trigger source로 사용한다.
  2. Lambda에서 MediaConvert의 metadata를 기반으로 외부 API를 호출한다.

Lambda Function 만들기

Create Function

  1. Author from scratch 선택
  2. Function Name: call_extapi_by_mediaconvert_status
  3. Runtime: Python 3.9
  4. Execution Role: Crate a new role with basic Lambda permissions 선택
  5. Create function

CloudWatch Evnet 설정

Back to CloudWatch Events

Create rult버튼 클릭

Create rule


Name: rule_call_lambda_by_mediaconvert_status
Description: Rule: Call Lambda Function When MediaConvert status changes

Create버튼 클릭

Lambda Function으로 돌아가 보면 EventBridge가 트리거로 설정된 것을 확인할 수 있다.

Lambda Function 업데이트

Test Event 설정

  1. Test new event: Create new event
  2. Event name: evt_cloudwatch_mc_status
  3. Template: cloudwatch-scheduled-event
  4. 아래의 코드를 Event JSON에 추가하기
  5. Save버튼 클릭
{
   "version":"0",
   "id":"20021120-6965-5c15-ee24-41a90566bbfe",
   "detail-type":"MediaConvert Job State Change",
   "source":"aws.mediaconvert",
   "account":"667614052497",
   "time":"2022-07-19T02:01:14Z",
   "region":"ap-northeast-2",
   "resources":[
      "arn:aws:mediaconvert:ap-northeast-2:123456789:jobs/1658196072804-pvwz52"
   ],
   "detail":{
      "timestamp":1658196074770,
      "accountId":"123456789",
      "queue":"arn:aws:mediaconvert:ap-northeast-2:123456789:queues/Default",
      "jobId":"1658196072804-pvwz52",
      "status":"PROGRESSING", 
      "userMetadata":{
         "assetID":"8495a26b-0706-11ed-9cea-0a6161afe472",
         "baseFolder":"vod",
         "serverType":"dev",
         "fileType":"mp4",
         "memberSeq":"1",
         "fileName":"Lake-67201.mp4",
         "outBucket":"sotwo-output",
         "outputPath":"vod/dev/hls/8495a26b-0706-11ed-9cea-0a6161afe472/Lake-67201",
         "outputExtension":".m3u8"
      }
   }
}

MediaConvert의 status: PROGRESSING -> INPUT_INFORMATION -> COMPLETE


Lambda Function에 Custom API 올리기

Custom API를 올리기 위해서는 API를 특정 folder에 다운받고 ZIP 파일로 압축하고 올리면 된다.

Mac에서 Python API (requests) 특정 폴더에 다운받기

PIP 버전 확인

iTerms를 킨다. (or Terminal)

기본적으로 mac에 pip3가 설치되어 있다.

pip3 -[대문자 V]

 pip3 -V 
 pip 22.1.1 from /opt/homebrew/lib/python3.9/site-packages/pip (python 3.9)

PC에 python 3.9가 설치되어 있는 것을 확인할 수 있다.

폴더 만들기

~/Workspace/example_python/cust_lib 라는 폴더를 만들었음

API call을 위한 requests API cust_lib 폴더에 설치

  cd ~/Workspace/examples_python/cust_lib # 폴더 이동
  pip3 install requests -t .

마지막에 . 을 해주게 되면 현재 폴더에 라이브러리를 설치해 준다.

lambda_function.py 파일 만들기

import json
import requests

def lambda_handler(event, context):
    print(event)
    
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

zip 파일 만들기

  zip -r cust_lib.zip .

위의 명령어로 zip 파일을 만들 수 있다.
현재 폴더를 모두 압축하여 cust_lib.zip 으로 만들어 준다.

Upload Zip file

Save버튼을 클릭하면

External API 호출하기

import json
import requests

DEV_API_HOST = 'https://[domain name for dev]'
QA_API_HOST = 'https://[domain name for qa]'
PROD_API_HOST = 'https://[domain name for prod]'

API_TYPE = 'POST'

API_PATH = '/[path-api]/update_by_media_convert_status'

headers = {'accept': 'application/json', 'Content-Type': 'application/json; charset=utf-8'}

def conv_to_param(event):
    metadata = event['detail']['userMetadata']
    metadata['mediaConvertStatus'] = event['detail']['status'] # PROGRESSING -> INPUT_INFORMATION -> COMPLETE
    
    return metadata
    
def get_api_host_by(serverType): 
    if serverType == 'prod':
        return PROD_API_HOST
    elif serverType == 'qa':
        return QA_API_HOST
    else:
        return DEV_API_HOST
        
def postRequest(host, data):
    url = host + API_PATH
    
    print('url: %s' % url)
    print('headers: %s' % headers)
    print('data: %s' % data)
    
    return requests.post(url, headers=headers, json=data)
    

def lambda_handler(event, context):
    params = conv_to_param(event) 
    print('parms: %s' % params)
    api_host = get_api_host_by(params['serverType'])
    
    resp = postRequest(host=api_host, data=params)
    print(resp)
    
    return {
        'statusCode': 200,
        'body':'업데이트 완료'
    }

MediaConvert에서 CloudFront를 통해서 Lambda Function에 event를 넘기면 기존에 설정해 놓았던 metadata를 받아올 수 있다.
그래서 metadata 정보 + MediaConvert status값을 합쳐서 WAS 서버에 지정된 API를 call 한다.

WAS 에 지정된 API는 각각 다를 것으로 예상됨으로 별도로 코드로 남기지는 않는다.

metadata 가 기억이 나지 않는 경우 : VOD Streaming Server 구축 4 (AWS)


WAS API 호출 확인

새로운 데이터를 올리게 되면 아래와 같이 API가 호출되는 것을 확인할 수 있다.

PROCESSING -> INPUT_INFORMATION -> COMPLETE

확인 완료

POST /update_by_media_convert_status, params: {"assetID":"f2ba19f0-071d-11ed-9cea-0a6161afe472","baseFolder":"vod","serverType":"dev","fileType":"mp4","memberSeq":"1","fileName":"Mountains-48873.mp4","outBucket":"sotwo-output","outputPath":"vod/dev/hls/f2ba19f0-071d-11ed-9cea-0a6161afe472/Mountains-48873","outputExtension":".m3u8","mediaConvertStatus":"PROGRESSING"}

POST /update_by_media_convert_status, params: {"assetID":"f2ba19f0-071d-11ed-9cea-0a6161afe472","baseFolder":"vod","serverType":"dev","fileType":"mp4","memberSeq":"1","fileName":"Mountains-48873.mp4","outBucket":"sotwo-output","outputPath":"vod/dev/hls/f2ba19f0-071d-11ed-9cea-0a6161afe472/Mountains-48873","outputExtension":".m3u8","mediaConvertStatus":"INPUT_INFORMATION"}

POST /update_by_media_convert_status, params: {"assetID":"f2ba19f0-071d-11ed-9cea-0a6161afe472","baseFolder":"vod","serverType":"dev","fileType":"mp4","memberSeq":"1","fileName":"Mountains-48873.mp4","outBucket":"sotwo-output","outputPath":"vod/dev/hls/f2ba19f0-071d-11ed-9cea-0a6161afe472/Mountains-48873","outputExtension":".m3u8","mediaConvertStatus":"COMPLETE"}

더 생각해 볼 내용

1) (입력 부분) Amazone S3에서 event방식으로 Lambda function 호출 -> SQS에서 Lambda function을 requst response 방식으로 호출 (에러 발생할 때 바로 예외 처리할 수 있음)

2) (출력 부분) CloudWatch에서 event방식으로 Lambda function 호출 -> CloudWatch 에서 SQS에 저장하고 SQS에서 Lambda function을 requst response 방식으로 호출 (WAS에서 API를 수신받지 못하는 경우 장애 대응이 쉬워진다.)

profile
36.9 It's good time to start something new

1개의 댓글

comment-user-thumbnail
2023년 11월 30일

안녕하세요 좋은 글 감사합니다. path-api 부분을 입력을 못하고 있어서 그런데 path-api 부분은 어디서 찾을수있나요?

답글 달기