버전 비교

  • 이 줄이 추가되었습니다.
  • 이 줄이 삭제되었습니다.
  • 서식이 변경되었습니다.

...

리전을 서울(우측 상단)로 선택하고, 언어는 영어로 진행(좌측 하단)

Image Modified


2. DynamoDB 테이블 만들기

DynamoDB는 게시물 정보와 생성된 MP3의 URL 메타 정보를 저장합니다.

  1. DynamoDB 서비스로 이동합니다.
    Image Modified
  2. Create Table 버튼을 클릭합니다.
  3. DynamoDB 콘솔에서 NewsTable 라고 하는 단일 테이블을 만듭니다. 기본 키 id 는 문자열이고, PostNews Lambda 함수에 의해 새 레코드는 NewsTable 에 자동으로 추가 생성합니다.
    Image Modified
  4. NoSQL인 DynamoDB를 사용하므로 스키마를 사전에 정의하지는 않겠지만, 사용하게 될 어트리뷰트가 어떤 것이 있는지 살펴 보겠습니다.

    keyvalue
    id게시물 ID (UUID로 자동 생성)
    voice오디오 파일을 생성하는데 사용된 Amazon Polly 음성
    pollyStatus처리 상태에 따라서 PROCESSING 또는 UPDATED로 구분
    originText원문 텍스트
    RequestCharacters요청한 문자 개수
    mp3UrlPolly에 의해서 생성된 mp3 접근 URL
    updateDate수정된 시간
    timbre음색 (소리의 파형)
    pitch음조 (소리의 높낮이)

    5. 테이블 생성 확인

...

  1. 그렇기에 간단한 SNS 주제를 만들어 보겠습니다. SNS 서비스로 이동합니다.
  2. Create topic 메뉴를 눌러서 Topic을 생성합니다.
  3. 아래와 같이 NewsTopic 이라는 새로운 Topic을 생성합니다.
  4. 생성된 SNS는 Amazon Polly가 작업이 완료되면 알려주기 위해서 해당 Topic을 호출해야 합니다. 따라서 Topic에 대한 아마존 고유 리소스 이름을 알아야 합니다.

    정보

    아래와 같이 생성된 Topic을 클릭하여 Topic의 ARN을 복사하여 메모장에 기록해 둡니다. (사용자 별로 다르게 나옵니다. 본인의 ARN을 복사합니다.)
    Topic ARN 복사 하기: 

    Image Modified

4. mp3 저장을 위한 S3 버킷 만들기

응용 프로그램에서 생성한 모든 오디오 파일을 저장하는 S3 버킷을 만들어야합니다.

  1. 아래 그림처럼 S3 서비스로 이동합니다.
    Image Modified
  2. 기존에 만들어진 S3 버킷이 있다면, 해당 버킷을 볼 수 있습니다. 버킷을 새로 생성하기 위하여, Create bucket 버튼을 클릭합니다.


  3. 팝업창에서 Bucket name을 적습니다. 아래 예제에서는 polly-mp3.studydev.com 이라는 버킷 이름으로 작성하지만, 실습에서는 전 세계적으로 고유한 다른 이름으로 작성해야 합니다. 작성후 Next 버튼을 클릭 합니다.
  4. (옵션) Tags 정보에 Key에는 Name을 Value에는 NewsApp 을 추가합니다.
  5. 외부에서 퍼블릭하게 접속해서 mp3 재생이 되도록 체크 박스를 모두 해지 합니다. (기본은 체크되어 안전하게 막혀 있음)
  6. 모든 설정이 완료되면 Create Bucket 버튼을 클릭하고 S3 버킷을 생성합니다.

...

  1. AWS 관리 콘솔에서 Lambda 서비스로 이동합니다.
  2. Create a function 버튼을 클릭하여 Lambda 함수를 하나 만들겠습니다.
  3. 새로운 함수의 Name은 PostNews 라고 만듭니다. Runtime은 Python 2.7 을 선택합니다. Role은 Choose an existing role 을 선택하고, 위에서 생성한 IAM Role인 NewsRole 을 선택합니다. 그리고 우측 하단의 Create function 버튼을 클릭합니다.
  4. Lambda 함수가 정상적으로 만들어진 것을 확인할 수 있습니다. Lambda 함수 코드 편집기는 AWS Cloud9 IDE가 내장되어 있어서 코드 편집을 웹 브라우저에서도 쉽게 할 수 있는 환경을 제공합니다.

  5. 아래 코드를 이 Lambda 함수의 코드로 변경합니다. 해당 함수의 로직은 Polly에 TTS 작업을 요청하고, 요청 작업에 대한 ID 값을 DynamoDB에 등록합니다.

    코드 블럭
    # -*- coding: utf-8 -*-
    from __future__ import print_function
      
    import boto3
    import os
    import json
    import uuid
    import datetime
    import re
     
    def lambda_handler(event, context):
        if "body" in event:
            parmas = json.loads(event['body'])
         
        voice = parmas["voice"]
        originText = parmas["text"]
        timbre = parmas["timbre"]
        pitch = parmas["pitch"]
        updateDate = datetime.datetime.now().strftime("%Y%m%d")
      
        polly = boto3.client('polly')
        removeBrackets = re.sub(r'\([^)]*\)', '', originText)
        repTextBlock = re.sub('[·…]', '<break time="100ms"/>', removeBrackets)
        ssmlBlock = "<speak><amazon:effect vocal-tract-length=\"" + timbre + "\"><prosody pitch=\"" + pitch + "\">" + repTextBlock + "</prosody></amazon:effect></speak>"
        ssmlBlock = ssmlBlock.replace('철수', '<amazon:effect vocal-tract-length="+80%"><prosody pitch="-70%">안녕하세요? 저는 서연 친구 철수에요.</prosody></amazon:effect>')
        ssmlBlock = ssmlBlock.replace('귀신', '<amazon:effect name="whispered"><amazon:effect vocal-tract-length="-30%"><prosody volume="loud">나 꿍꼬또, 기싱꿍꼬또</prosody></amazon:effect></amazon:effect>')
        print (ssmlBlock)
          
        response = polly.start_speech_synthesis_task(
            OutputFormat= 'mp3',
            OutputS3BucketName= os.environ['BUCKET_NAME'],
            # OutputS3KeyPrefix='polly/',
            SampleRate='22050',
            SnsTopicArn=os.environ['SNS_TOPIC'],
            Text=ssmlBlock,
            TextType='ssml',
            VoiceId=voice
        )
        print (response)
        data = response['SynthesisTask']
          
        # Creating new record in DynamoDB table
        dynamodb = boto3.resource('dynamodb')
        table = dynamodb.Table(os.environ['DB_TABLE_NAME'])
        table.put_item(
            Item = {
                'id' : data['TaskId'],
                'updateDate': data['CreationTime'].strftime("%Y-%m-%d %H:%M:%S"),
                'voice' : voice,
                'originText': originText,
                'pollyStatus' : data['TaskStatus'],
                'timbre': timbre,
                'pitch': pitch,
                'mp3Url': data['OutputUri'],
                'RequestCharacters': data['RequestCharacters']
            }
        )
         
        result = {
            'statusCode': 200,
            'body': json.dumps({'recordId': data['TaskId']}),
            'headers': {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': '*'
            }
        }
          
        return result


  6. 아래와 같이 함수 코드를 변경하고 나면 우측 상단의 Save 버튼을 눌러서 환경을 저장합니다.
  7. PostNews Lambda 함수는 메타 데이터가 저장될 DynamoDB 테이블(DB_TABLE_NAME), Polly가 작업을 완료하면 다음 Lambda 함수를 트리거 시키기 위한 SNS Topic(SNS_TOPIC), Polly에 의해서 만들어지는 mp3가 저장될 S3의 버켓(BUCKET_NAME)의 이름을 알아야 합니다. 이 값을 환경 변수로 함수에 전달할 수 있는 기능을 사용하기 위하여 Environment variables를 사용할 수 있습니다. 아래와 같이 S3 버킷 이름(polly-mp3.studydev.com)과, NewsTopic의 ARN 값(, DynamoDB 테이블의 NewsTable 값을 아래와 같이 입력합니다.
    추가로 하단의 Basic settings에서 Lambda의 실행 시간을 지정할 수 있습니다. Timeout 값을 1 min 으로 수정합니다. Tags에는 Key 값으로 Name을 Value 값을 NewsApp 을 입력합니다.

...

  1. 정적 웹 호스팅을 위한 소스코드를 준비합니다.
    1. 클라이언트 PC에 패키지 파일을 다운로드 받고 압축을 해제합니다.
    2. 기존에 생성한 Amazon API Gateway의 URL을 연결하기 위해서 scripts.js  파일을 열어서 API를 배포하고 받은 URL로 수정합니다.
      API_ENDPOINT = "" 에 비어있는 부분을 아래와 같이 상단에서 API Gateway에서 배포된 URL로 넣어 줍니다.
  2. S3 정적 웹 호스팅용 버킷을 생성합니다. (S3 버킷 이름은 모든 리전에 유일해야 하므로 이름을 작성할 때 주의합니다.)
  3. Tags에 Name 이라는 Key 값과 NewsApp 이라는 Value 값을 입력합니다.
  4. 외부에서 퍼블릭하게 웹 호스팅 하는 파일에 접속할 수 있도록 체크 박스를 모두 해지 합니다. (기본은 체크되어 안전하게 막혀 있음)
  5. 모든 설정이 완료되면 Create Bucket 버튼을 클릭하고 S3 버킷을 생성합니다.
  6. S3 버킷 정적 웹 호스팅 기능 활성화를 위해서 정적 웹 호스팅을 제공할 버킷을 클릭합니다.
  7. 2번째 Properties 탭에서 Static Web Hosting 기능을 클릭합니다.
  8. 정적 웹 호스팅 기능이 비활성화 되어 있습니다.
  9. Static Website hosting 기능을 켜 주고, index와 error 문서를 지정하고 저장합니다.
  10. 정적 웹 호스팅 기능이 활성화 된 것을 볼 수 있습니다.
  11. 정적 웹 호스팅을 위해서 해당 버킷에 있는 객체(파일)에 대해서 접근할 수 있는 정책을 설정 할 수 있습니다. Permissions 탭을 선택하고 Bucket Policy를 클릭합니다.
  12. 아래의 정책에서 BUCKET_NAME 부분을 생성한 버킷 이름으로 변경한 후 복사합니다.

    코드 블럭
    titleS3 버켓에 대한 접근 권한 설정
    { 
      "Version":"2012-10-17",
      "Statement":[ 
        { 
          "Sid":"PublicReadGetObject",
          "Effect":"Allow",
          "Principal":"*",
          "Action":[ 
            "s3:GetObject"
          ],
          "Resource":[ 
            "arn:aws:s3:::BUCKET_NAME/*"
          ]
        }
      ]
    }
    


  13. 버켓 정책을 설정하고 우측 상단의 Save 버튼을 클릭하여 저장합니다.
  14. S3 Bucket이 Public 접근이 가능하다는 메시지가 화면에 표시됩니다.
  15. 해당 S3 버킷에 정적 웹 포스팅에 필요한 파일 4개를 업로드 하기 위해서, Overview 탭으로 이동하고 좌측 상단의 Upload 버튼을 클릭합니다.
  16. 팝업창이 나타나면 방금 수정한 파일을 포함한 4개 파일(index.html, favicon.ico, scripts.js, styles.css)을 지정하여 좌측 하단의 Upload 버튼을 클릭합니다.
  17. 다음과 같이 파일이 업로드 된 것을 확인할 수 있습니다.
    Image Modified
  18. Properties 탭을 선택하고, Static website hosting 메뉴를 선택하면 웹 페이지 접속을 위한 Endpoint를 확인할 수 있습니다. 해당 Endpoint URL을 클릭하면 새로운 탭에 웹 페이지가 표시 됩니다.
  19. 웹 페이지 URL을 접속해서 정상 동작되는지 여부를 확인 합니다.

...

  1. 먼저 음성으로 변환하고자 하는 목소리를 선택합니다. 한국어 지원이 되는 Seoyeon을 선택합니다. 그리고 텍스트를 입력합니다. 마지막으로 음성 변환 시작 버튼을 누릅니다.
    API Gateway를 통해서 POST 메서드로 등록 메시지가 전달 됩니다. Lambda 함수에서 바로 인식할 수 있도록 POST Data는 JSON 형태로 전송합니다.


  2. 게시물이 등록되면 게시물 등록 번호가 자동으로 생성됩니다. 처음에는 TTS Job이 등록되면 상태가 scheduled 상태지만 시간이 지나고 작업이 완료되면 COMPLETED 로 변경되는 것을 볼 수 있습니다. 음색과 음높이를 변경하면서 다양한 테스트를 해 보세요. 다양한 음성 효과를 주고자 할 경우 SSML을 이용할 수 있습니다.


리소스 삭제하기

해당 리소스들을 삭제하는 순서는 제작 순서의 역순과 같습니다삭제는 아래와 같이 진행할 수 있습니다. 각 서비스로 이동하고 해당 리소스를 선택하고 삭제하시면 됩니다.

  1. 정적 웹 호스팅 하는 S3 버킷과 MP3가 저장되는 버킷을 삭제합니다. 내부에 객체가 있을 때, 삭제가 안될 경우, 객체부터 삭제 합니다.
  2. API Gateway에 배포되어 있는 newsapi를 삭제합니다.
  3. Lambda 함수에 등록되어 있는 4개의 함수를 삭제 합니다.
  4. DynamoDB에 등록한 NewsTable을 삭제 합니다.
  5. SNS에 등록되어 있는 NewsTopic을 삭제 합니다.
  6. IAM에 등록되어 있는 NewsRole과 NewsPolicy를 삭제 합니다.
    1. Role 삭제
    2. Policy 삭제

...