1. 소개
콘텐츠 전송 네트워크 (CDN)는 자주 액세스하는 콘텐츠를 최종 사용자와 더 가까운 위치에 캐시하고, 클라이언트와 더 가까운 위치에서 연결을 종료하고, 출처에 대한 연결을 재사용하고, 최신 네트워킹 프로토콜 및 맞춤설정을 채택하여 사용자 성능을 개선합니다. 사용자와 Google 고객에게는 지연 시간이 단축되고 안정성이 향상되며 비용이 절감되어 판매, 웹 환경이 개선되고 사용자 환경이 전반적으로 향상됩니다. 요즘 CDN 없이 운영되는 현대적인 사이트와 동영상 스트리밍 플랫폼은 거의 없습니다.
학습할 내용
이 실습에서는 Media CDN (CDN) + Cloud Media Live Streaming API (라이브 동영상 트랜스코딩) + Cloud Storage (동영상 저장소) + 동영상 플레이어 (VLC, Google Shaka Player 등 - HLS + MPEG-DASH 지원 플레이어)를 사용하여 라이브 스트리밍 워크플로 환경을 배포하는 단계를 안내합니다.
Live Streaming API 구성요소인 입력, 채널을 설정하고 FFmpeg를 사용하여 입력/채널에 대한 라이브 피드를 시작합니다 (FFmpeg는 라이브 테스트 신호를 생성할 수 있음). Live Streaming API가 라이브 피드를 트랜스코딩합니다. 트랜스코딩된 동영상 매니페스트와 세그먼트는 Cloud Storage 버킷에 저장됩니다. 그런 다음 라이브 동영상 Cloud Storage 버킷을 출처로 사용하여 Media CDN을 설정합니다. 마지막으로 VLC 플레이어는 미디어 CDN을 통해 캐시된 라이브 콘텐츠를 재생하는 데 사용됩니다. 또한 Media CDN의 활동을 시각화할 Cloud Monitoring 대시보드를 설정합니다.
빌드할 항목
이 실습에서는 다음 아키텍처를 기반으로 환경을 설정합니다.
이 실습에서는 다음 구성요소를 설정하고 다음 작업을 실행합니다.
- 실시간으로 트랜스코딩된 동영상을 저장할 Google Cloud Storage (GCS) 버킷 만들기
- 동영상을 HLS + MPEG DASH, SD, HD 등 여러 형식으로 트랜스코딩하도록 Live Streaming API 구성
- 라이브 스트리밍 구성요소 설정: 입력/채널
- 라이브 스트림 채널 시작
- GCS 버킷을 출처로 Media CDN 설정
- 실시간 채널에 피드하도록 FFmpeg 설정
- 동영상 플레이어로 트랜스코딩된 라이브 피드 스트리밍
- Cloud Monitoring 대시보드를 설정하여 미디어 CDN 활동 (지연 시간, 캐시 적중, 캐시 부적중 등)을 모니터링합니다.
참고: 이 실습에서는 사용자가 Google Cloud 콘솔에 액세스할 수 있고 이미 프로젝트가 설정되어 있다고 가정합니다. 또한 사용자는 새 환경에서 시작하고 이 데모를 위해 설정된 항목이 없다고 가정합니다.
모든 구성 작업은 Cloud Shell의 명령줄을 통해 실행됩니다. 언제든지 콘솔에서 명령줄을 통해 구성된 구성요소를 확인할 수 있습니다. 실습 전반에서 Google Cloud 콘솔을 가리키는 포인터를 볼 수 있습니다.
2. 시작하기 전에
Media CDN 액세스가 제한됩니다. Media CDN에 액세스하려면 계정팀에 문의하세요. 해당 사용자가 나를 대신해 액세스 요청을 생성할 수 있습니다. Google 직원이고 Media CDN으로 라이브 스트리밍을 테스트하려면 Media CDN PM에 문의하여 Media CDN 액세스 권한을 요청하세요.
3. 설정 및 요구사항
Cloud Shell 시작
Google Cloud를 노트북에서 원격으로 실행할 수 있지만, 이 Codelab에서는 Cloud에서 실행되는 명령줄 환경인 Google Cloud Shell을 사용합니다.
Google Cloud Console의 오른쪽 상단 툴바에 있는 Cloud Shell 아이콘을 클릭합니다.
환경을 프로비저닝하고 연결하는 데 몇 분 정도 소요됩니다. 완료되면 다음과 같이 표시됩니다.
가상 머신에는 필요한 개발 도구가 모두 들어있습니다. 영구적인 5GB 홈 디렉터리를 제공하고 Google Cloud에서 실행되므로 네트워크 성능과 인증이 크게 개선됩니다. 이 Codelab의 모든 작업은 브라우저 내에서 수행할 수 있습니다. 아무것도 설치할 필요가 없습니다.
4. Google Cloud SDK 버전
이 글을 작성할 당시 408.0.0
이 최신 Google Cloud SDK 버전입니다. 이 실습의 모든 명령어는 최신 버전의 Google Cloud SDK를 사용하여 테스트되었습니다. 계속하기 전에 Cloud Shell에서 최신 버전의 SDK를 사용하고 있는지 확인하세요.
SDK 버전 확인하기
gcloud version
명령어를 사용하여 SDK 버전을 확인합니다.
명령어
gcloud version | grep "Google Cloud SDK"
출력 예시
Google Cloud SDK 408.0.0
다음 단계
- SDK 버전이
408.0.0
이상인 경우 다음 섹션으로 건너뜁니다. - SDK 버전이
408.0.0
보다 낮으면 아래 명령어를 실행하여 SDK를 업데이트합니다.
sudo apt-get update && sudo apt-get install google-cloud-sdk
5. 기본 요건
GCP 리소스 구성을 시작하기 전에 다음을 실행해야 합니다.
- 환경 변수 설정
- 필수 서비스 API 사용 설정
1. 환경 변수 설정
이 실습에서는 몇 가지 변수를 사용하여 gcloud
및 curl
명령어를 실행합니다. 다음 환경 변수를 구성해야 합니다.
- 프로젝트 ID
- 프로젝트 번호
- 사용자 이름
- 지역
- 입력 ID
- 채널 ID
프로젝트 ID 및 사용자 이름
이러한 환경 변수는 일반적으로 Cloudshell에서 사전 구성됩니다. env
명령어를 사용하여 확인합니다.
명령어
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME'
출력 예시
DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME>
env_variables
파일 만들기
cat
명령어를 사용하여 env_variables.txt
파일을 만듭니다. 아래 명령어는 사용자의 홈 디렉터리에 env_variables.txt
파일을 만듭니다.
명령어
cat > ~/env_variables.txt << EOF export PROJECT_NUMBER=$(gcloud projects describe $GOOGLE_CLOUD_PROJECT --format="value(projectNumber)") export LOCATION=us-west2 export INPUT_ID=lab-live-input export CHANNEL_ID=lab-live-channel EOF
환경 변수 설정
source
명령어를 사용하여 환경 변수를 설정합니다.
명령어
source ~/env_variables.txt
변수가 설정되어 있는지 확인
필요한 모든 환경 변수가 설정되었는지 확인해 보겠습니다. 출력에 총 6개의 환경 변수가 표시됩니다.
명령어
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME|PROJECT_NUMBER|LOCATION|INPUT_ID|CHANNEL_ID'
출력 예시
LOCATION=us-west2 DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME> PROJECT_NUMBER=<YOUR_PROJECT_NUMBER> INPUT_ID=lab-live-input CHANNEL_ID=lab-live-channel
2. 필수 서비스 API 사용 설정
프로젝트에서 다음 API가 사용 설정되어 있는지 확인해야 합니다.
- Network Services API
- Certificate Manager API
- Livestream API
- Media CDN Edge Cache API
Network Services API 사용 설정
Network Services API를 사용 설정하려면 다음 명령어를 실행합니다.
명령어
gcloud services enable networkservices.googleapis.com
Certificate Manager API 사용 설정
Certificate Manager API를 사용 설정하려면 다음 명령어를 실행합니다.
명령어
gcloud services enable certificatemanager.googleapis.com
Live Stream API 사용 설정
Live Stream API를 사용 설정하려면 다음 명령어를 실행합니다.
명령어
gcloud services enable livestream.googleapis.com
Media CDN Edge Cache API 사용 설정
Media CDN Edge Cache API를 사용 설정하려면 다음 명령어를 실행합니다.
명령어
gcloud services enable edgecache.googleapis.com
API가 사용 설정되어 있는지 확인
gcloud services list
명령어를 실행하여 사용 설정된 모든 API를 나열합니다. 출력에 API 4개가 표시됩니다.
명령어
gcloud services list | grep -E 'networkservices|certificatemanager|livestream|edgecache'
출력 예시
NAME: certificatemanager.googleapis.com NAME: livestream.googleapis.com NAME: networkservices.googleapis.com NAME: edgecache.googleapis.com
6. Cloud Storage 버킷 만들기
이 섹션에서는 다음을 수행합니다.
- Cloud Storage 버킷 만들기
- 버킷에 공개 액세스 설정
실습 후반부에서 이 버킷을 사용하여 트랜스코딩된 동영상 파일을 저장합니다. 이 버킷은 Media CDN 서비스의 출처 스토리지 역할도 합니다.
1. 버킷 만들기
gsutil mb
명령어를 사용하여 버킷을 만듭니다.
명령어
gsutil mb gs://live-streaming-storage-$LOGNAME
2. 버킷을 공개적으로 액세스 가능하도록 설정
gsutil
iam
명령어를 사용하여 파일을 공개적으로 사용 가능하도록 설정합니다.
명령어
gsutil iam ch allUsers:objectViewer gs://live-streaming-storage-$LOGNAME
7. Live Streaming API 환경 설정
Live Streaming API 체인의 구성요소는 다음과 같이 구성됩니다.
이전 섹션에서 Cloud Storage 버킷 live-streaming-storage-$LOGNAME
를 만들었습니다. 다음 두 섹션에서는 다음 리소스를 만듭니다.
- 라이브 스트리밍 입력: 입력 엔드포인트는 인코더가 입력 스트림을 전송하는 엔드포인트입니다. 입력 엔드포인트를 사용하여 입력 해상도, 입력 유형, 동영상 자르기와 같은 스트림 구성을 지정할 수 있습니다.
- 라이브 스트리밍 채널: 채널은 입력 엔드포인트를 통해 입력 스트림을 수집하고, 입력 스트림을 여러 버전으로 트랜스코딩하고, 지정된 위치의 특정 형식으로 출력 라이브 스트림을 게시하는 리소스입니다. 동일한 채널에 기본 입력 스트림과 백업 입력 스트림을 포함할 수 있습니다.
실습 후반부에서 다음 리소스를 만들겠습니다.
- 인코더: 인코더는 입력 스트림을 전송하는 데 사용되는 프로그램입니다. 이 실습에서는 FFmpeg를 사용합니다.
8. 입력 엔드포인트 만들기 및 구성
input.json 파일 만들기
라이브 스트림 신호 유형을 지정할 input.json
파일을 만듭니다. 이 실습에서는 RTMP 라이브 신호를 사용합니다.
명령어
cat > input.json << EOF { "type": "RTMP_PUSH" } EOF
입력 엔드포인트 만들기
이 실습 작성 시점에서 Live Stream API에 대한 gcloud 지원은 없습니다. curl
명령어를 사용하여 API를 호출합니다.
명령어
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d @input.json \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/inputs?inputId=$INPUT_ID"
출력 예시
{ "name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1661405972853-5e70a38d6f27f-79100d00-310671b4", "metadata": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata", "createTime": "2022-08-25T05:39:32.884030164Z", "target": "projects/PROJECT_NUMBER/locations/us-west2/inputs/lab-live-input", "verb": "create", "requestedCancellation": false, "apiVersion": "v1" }, "done": false }
출력에는 유용한 정보가 많이 있지만 지금은 두 필드에 집중해야 합니다.
- 작업 ID: 출력에서 작업 ID를 복사하여 적어 둡니다. 다음은 출력 예의 작업 ID입니다.
"name"
로 시작하는 출력 줄에서 확인할 수 있습니다."operation-1661405972853-5e70a38d6f27f-79100d00-310671b4"
- 상태: 상태가
"done": false
에서"done": true
으로 변경될 때까지 기다려야 합니다.
상태 확인
계속 진행하기 전에 입력 엔드포인트가 생성되고 준비되었는지 확인해야 합니다.
아래 명령어에서 <OPERATION>
를 위에서 가져온 작업의 ID로 바꿉니다. 이 예시에서는 "operation-1661405972853-5e70a38d6f27f-79100d00-310671b4"
입니다.
명령어
export OPERATION_ID_1=<OPERATION>
명령어
curl -X GET \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/operations/$OPERATION_ID_1"
출력 예시
{ "name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1661408816982-5e70ae25cea49-617844f0-8fdcb4a1", "metadata": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata", "createTime": "2022-08-25T06:26:57.001530499Z", "endTime": "2022-08-25T06:26:57.043623522Z", "target": "projects/PROJECT_NUMBER/locations/us-west2/inputs/lab-live-input", "verb": "create", "requestedCancellation": false, "apiVersion": "v1" }, "done": true, "response": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.Input", "name": "projects/PROJECT_ID/locations/us-west2/inputs/lab-live-input", "createTime": "2022-08-25T06:26:56.997623672Z", "updateTime": "2022-08-25T06:26:56.997623672Z", "type": "RTMP_PUSH", "uri": "rtmp://34.94.97.220/live/4b7846a1-4a67-44ed-bfd0-d98281b6464a", "tier": "HD" } }
입력 엔드포인트가 생성되고 준비되었음을 나타내는 "done:true"
가 표시될 때까지 명령어를 다시 실행합니다.
URI 저장
실습 후반부에서 이전 출력의 URI
를 사용합니다. 이제 URI
의 환경 변수를 설정해 보겠습니다.
명령어
export URI=<uri>
<uri>
를 위에서 기록한 URI로 바꿉니다. 원하는 경우 GET 메서드를 사용하여 URI를 검색할 수도 있습니다.
명령어
curl -s -X GET -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/inputs/$INPUT_ID" | jq .uri
9. 라이브 스트리밍 채널 만들기 및 구성하기
이전 섹션에서 만든 입력 엔드포인트와 연결된 라이브 스트리밍 채널을 만들어 보겠습니다. 다음 예시에서는 단일 고화질 (1280x720) 버전으로 구성된 HLS 라이브 스트림을 생성하는 채널을 만듭니다. 채널이 입력 엔드포인트 및 이전에 만든 스토리지 버킷과 연결됩니다.
channel.json 파일 만들기
Cloud Shell 터미널에서 다음 명령어를 입력하여 "channel.json"
파일을 만듭니다.
명령어
cat > channel.json << EOF { "inputAttachments": [ { "key": "my-input", "input": "projects/$PROJECT_NUMBER/locations/$LOCATION/inputs/$INPUT_ID" } ], "output": { "uri": "gs://live-streaming-storage-$LOGNAME" }, "elementaryStreams": [ { "key": "es_video", "videoStream": { "h264": { "profile": "high", "widthPixels": 1280, "heightPixels": 720, "bitrateBps": 3000000, "frameRate": 30 } } }, { "key": "es_audio", "audioStream": { "codec": "aac", "channelCount": 2, "bitrateBps": 160000 } } ], "muxStreams": [ { "key": "mux_video_ts", "container": "ts", "elementaryStreams": ["es_video", "es_audio"], "segmentSettings": { "segmentDuration": "2s" } } ], "manifests": [ { "fileName": "main.m3u8", "type": "HLS", "muxStreams": [ "mux_video_ts" ], "maxSegmentCount": 5 } ] } EOF
채널 만들기
다음 curl
명령어를 실행하여 채널을 만듭니다.
명령어
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d @channel.json \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels?channelId=$CHANNEL_ID"
출력 예시
{ "name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1661405972853-5e70a38d6f27f-79100d00-310671b4", "metadata": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata", "createTime": "2022-08-25T05:39:32.884030164Z", "target": "projects/PROJECT_NUMBER/locations/us-west2/channels/lab-live-channel", "verb": "create", "requestedCancellation": false, "apiVersion": "v1" }, "done": false }
작업 ID를 기록하고 복사합니다. 이 정보는 다음 단계 중 하나에서 필요합니다. "name"
로 시작하는 출력 줄에서 확인할 수 있습니다.
상태 확인
계속하기 전에 채널이 생성되고 준비되었는지 확인해야 합니다.
아래 명령어에서 <OPERATION>
를 위에서 가져온 작업의 ID로 바꿉니다. 이 예에서는 operation-1661405972853-5e70a38d6f27f-79100d00-310671b4
입니다.
명령어
export OPERATION_ID_2=<OPERATION>
명령어
curl -s -X GET \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/operations/$OPERATION_ID_2"
출력 예시
"name": "projects/PROJECT_NUMBER/locations/us-west2/operations/operation-1668666801461-5eda4c3f31852-a4d2229f-0efeef9e", "metadata": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata", "createTime": "2022-11-17T06:33:21.500841488Z", "endTime": "2022-11-17T06:33:21.529311112Z", "target": "projects/PROJECT_NUMBER/locations/us-west2/channels/lab-live-channel", "verb": "create", "requestedCancellation": false, "apiVersion": "v1" }, "done": true, "response": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.Channel", "name": "projects/PROJECT_NAME/locations/us-west2/channels/lab-live-channel", "createTime": "2022-11-17T06:33:21.497818033Z", "updateTime": "2022-11-17T06:33:21.497818033Z", "activeInput": "my-input", "output": { "uri": "gs://live-streaming-storage-LOGNAME" }, "elementaryStreams": [ { "videoStream": { "h264": { "widthPixels": 1280, "heightPixels": 720, "frameRate": 30, "bitrateBps": 3000000, "gopDuration": "2s", "vbvSizeBits": 3000000, "vbvFullnessBits": 2700000, "entropyCoder": "cabac", "profile": "high" } }, "key": "es_video" }, { "audioStream": { "codec": "aac", "bitrateBps": 160000, "channelCount": 2, "sampleRateHertz": 48000 }, "key": "es_audio" } ], "muxStreams": [ { "key": "mux_video_ts", "container": "ts", "elementaryStreams": [ "es_video", "es_audio" ], "segmentSettings": { "segmentDuration": "2s" } } ], "manifests": [ { "fileName": "main.m3u8", "type": "HLS", "muxStreams": [ "mux_video_ts" ], "maxSegmentCount": 5, "segmentKeepDuration": "60s" } ], "streamingState": "STOPPED", "inputAttachments": [ { "key": "my-input", "input": "projects/PROJECT_NUMBER/locations/us-west2/inputs/lab-live-input" } ], "logConfig": { "logSeverity": "OFF" } } }
입력 엔드포인트가 생성되고 준비되었음을 나타내는 "done:true"
가 표시될 때까지 명령어를 다시 실행합니다.
현재 "streamingState"
는 "STOPPED"
입니다. 다음 섹션에서 채널을 시작합니다.
10. 라이브 스트리밍 채널 시작
이제 라이브 스트림 채널을 만들었으므로 채널을 시작해 보겠습니다. 이 섹션에서는 다음을 수행합니다.
- 라이브 스트리밍 채널 시작
- 채널의 상태를 확인합니다.
streamingState
가"AWAITING INPUT"
인지 확인해야 합니다.
1. 채널 시작
Cloud Shell에서 다음 curl
명령어를 실행하여 채널을 시작합니다.
명령어
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d "" \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID:start"
출력 예시
{ "name": "projects/PROJECT_NUMBER/locations/LOCATION/operations/operation-1661405972853-5e70a38d6f27f-79100d00-310671b4", "metadata": { "@type": "type.googleapis.com/google.cloud.video.livestream.v1.OperationMetadata", "createTime": "2022-08-25T05:39:32.884030164Z", "target": "projects/PROJECT_NUMBER/locations/us-west2/channels/lab-live-channel", "verb": "start", "requestedCancellation": false, "apiVersion": "v1" }, "done": false }
2. 채널 상태 확인
다음 curl
명령어를 실행하여 채널 상태를 가져옵니다.
명령어
curl -s -X GET -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID" | grep "streamingState"
출력 예시
"streamingState": "AWAITING_INPUT",
채널이 실행 중이고 신호를 수신할 준비가 되었음을 나타내는 'AWAITING_INPUT
'가 표시될 때까지 명령어를 다시 실행합니다.
11. Media CDN 구성
이 섹션에서는 CDN 인프라인 Media CDN을 배포합니다. 다음 리소스가 생성됩니다.
- 에지 캐시 출처
- 에지 캐시 서비스
1. 에지 캐시 출처 만들기
Edge Cache Origin은 Cloud Storage 버킷, 서드 파티 스토리지 위치, 부하 분산기와 같은 콘텐츠 위치를 나타냅니다. CDN 용어로 출처(또는 출처 서버)는 배포하려는 콘텐츠의 소스(예: 모든 CSS, 자바스크립트, HTML, 이미지 등)가 있는 위치입니다. 이 실습에서는 실습 시작에 만들었던 Cloud Storage 버킷에 매핑되는 출처를 만듭니다. 에지 캐시 출처를 cme-origin
라고 하겠습니다. CDN의 출처는 모든 소스 콘텐츠가 에지 캐시 서버로 배포되기 전에 저장되는 위치입니다.
gcloud edge-cache origins create
명령어를 사용하여 원점을 만듭니다. 이 명령어는 완료하는 데 몇 분 정도 걸립니다.
명령어
gcloud edge-cache origins create cme-origin \ --origin-address="gs://live-streaming-storage-$LOGNAME"
예시 출력
Create request issued for: cme-origin Waiting for operation [projects/my-project/locations/global/operations/operation-1612121774168-5ba3759af1919- 3fdcd7b1-99f59223] to complete...done Created origin cme-origin
2. 에지 캐시 서비스 만들기
이제 에지 캐시 출처가 설정되었으므로 에지 캐시 서비스 자체를 만들 수 있습니다.
cme-demo.yaml
파일 만들기
에지 캐시 서비스 구성은 YAML
파일을 통해 이루어집니다. Cloud Shell에서 cme-demo.yaml
이라는 로컬 파일을 만듭니다. vi
, nano
또는 다른 편집기를 사용하여 다음 줄을 YAML 파일에 붙여넣습니다.
name: cme-demo routing: hostRules: - hosts: - demo.cme.com pathMatcher: routes pathMatchers: - name: routes routeRules: - headerAction: responseHeadersToAdd: - headerName: x-cache-status headerValue: "{cdn_cache_status}" matchRules: - prefixMatch: / origin: cme-origin priority: 100 routeAction: cdnPolicy: cacheKeyPolicy: {} cacheMode: FORCE_CACHE_ALL defaultTtl: 3600s signedRequestMode: DISABLED - headerAction: responseHeadersToAdd: - headerName: x-cache-status headerValue: "{cdn_cache_status}" matchRules: - pathTemplateMatch: /**.m3u8 origin: cme-origin priority: 25 routeAction: cdnPolicy: cacheKeyPolicy: {} cacheMode: FORCE_CACHE_ALL defaultTtl: 1s signedRequestMode: DISABLED - headerAction: {} matchRules: - pathTemplateMatch: /**.ts origin: cme-origin priority: 50 routeAction: cdnPolicy: cacheKeyPolicy: {} cacheMode: FORCE_CACHE_ALL defaultTtl: 2s signedRequestMode: DISABLED
모든 에지 캐시 서비스 구성은 기본값으로 두고 위 파일에는 사용자가 업데이트할 수 있는 필드 값이 3개 있습니다.
name
: Media CDN 인스턴스의 이름입니다(여기서는cme-demo
).hosts:
이 Media CDN 서비스에서 확인할 도메인 이름 목록입니다(여기:demo.cme.com
). 이 데모에서는 이를 사용합니다. Media CDN 인스턴스의 IP 주소를 사용합니다.Origin:
: 이전 단계에서 만든 에지 캐시 출처입니다.cme-origin
- Media CDN 출처의 이름으로 설정합니다.
YAML 파일에서 사용할 수 있는 다양한 변수에 관한 자세한 내용은 Edge Cache Service 구성 가이드를 참고하세요.
에지 캐시 서비스 만들기
에지 캐시 출처 cme-origin
에서 호스트 demo.cme.com
를 사용하여 cme-demo
라는 에지 캐시 서비스를 만듭니다. 서비스를 만들려면 Cloud Shell에서 다음 명령어를 실행합니다.
명령어
gcloud edge-cache services import cme-demo \ --source=cme-demo.yaml
Edge 캐시 서비스를 만드는 데 몇 분 정도 걸릴 수 있습니다.
출력 예시
Request issued for: [cme-demo] Waiting for operation [projects/PROJECT_ID/locations/global/operations/operation-1670476252264-5ef4a0f9f36ce-dd380af5-321be9a0] to complete...done. createTime: '2022-12-07T18:08:54.403446942Z' ipv4Addresses: - 34.104.35.152 ipv6Addresses: - '2600:1900:4110:d18::' name: projects/PROJECT_ID/locations/global/edgeCacheServices/cme-demo routing: hostRules: - hosts: - demo.cme.com - 34.104.35.152 pathMatcher: routes pathMatchers: - name: routes routeRules: - headerAction: responseHeadersToAdd: - headerName: x-cache-status headerValue: '{cdn_cache_status}' matchRules: - prefixMatch: / origin: projects/123456789/locations/global/edgeCacheOrigins/cme-origin priority: '100' routeAction: cdnPolicy: cacheKeyPolicy: {} cacheMode: FORCE_CACHE_ALL defaultTtl: 3600s signedRequestMode: DISABLED - headerAction: responseHeadersToAdd: - headerName: x-cache-status headerValue: '{cdn_cache_status}' matchRules: - pathTemplateMatch: /**.m3u8 origin: projects/123456789/locations/global/edgeCacheOrigins/cme-origin priority: '25' routeAction: cdnPolicy: cacheKeyPolicy: {} cacheMode: FORCE_CACHE_ALL defaultTtl: 1s signedRequestMode: DISABLED - headerAction: {} matchRules: - pathTemplateMatch: /**.ts origin: projects/123456789/locations/global/edgeCacheOrigins/cme-origin priority: '50' routeAction: cdnPolicy: cacheKeyPolicy: {} cacheMode: FORCE_CACHE_ALL defaultTtl: 2s signedRequestMode: DISABLED updateTime: '2022-12-08T05:11:31.598744308Z'
에지 캐시 서비스 인스턴스의 ipv4Addresses
(여기서는 34.104.36.157
)를 기록하고 복사합니다. 이 ID를 사용하여 cme-demo.yaml
파일을 업데이트하고 나중에 트랜스코딩된 동영상을 스트리밍합니다.
에지 캐시 서비스 업데이트
이 시점에서 나중에 서비스의 IP를 사용하여 동영상을 스트리밍할 수 있도록 에지 캐시 서비스 구성을 업데이트하는 것이 좋습니다. 에지 캐시 서비스 YAML 파일을 사용하면 에지 캐시 서비스에서 요청을 수락할 모든 호스트 이름/IP를 나열할 수 있습니다. 이 시점에서는 demo.cme.com
만 호스트로 지정했습니다. 이 도메인의 이름 변환을 제공하려면 DNS 영역을 구성하면 됩니다. 하지만 더 쉬운 방법은 yaml
파일의 호스트 목록에 IP 주소를 추가하는 것입니다. YAML 파일을 다시 수정하여 아래와 같이 표시되도록 합니다.
name: cme-demo routing: hostRules: - hosts: - demo.cme.com - IPADDRESS pathMatcher: routes pathMatchers: - name: routes routeRules: - headerAction: responseHeadersToAdd: - headerName: x-cache-status headerValue: "{cdn_cache_status}" matchRules: - prefixMatch: / origin: cme-origin priority: 100 routeAction: cdnPolicy: cacheKeyPolicy: {} cacheMode: FORCE_CACHE_ALL defaultTtl: 3600s signedRequestMode: DISABLED - headerAction: responseHeadersToAdd: - headerName: x-cache-status headerValue: "{cdn_cache_status}" matchRules: - pathTemplateMatch: /**.m3u8 origin: cme-origin priority: 25 routeAction: cdnPolicy: cacheKeyPolicy: {} cacheMode: FORCE_CACHE_ALL defaultTtl: 1s signedRequestMode: DISABLED - headerAction: {} matchRules: - pathTemplateMatch: /**.ts origin: cme-origin priority: 50 routeAction: cdnPolicy: cacheKeyPolicy: {} cacheMode: FORCE_CACHE_ALL defaultTtl: 2s signedRequestMode: DISABLED
변경사항을 반영하려면 YAML 파일을 다시 가져오기만 하면 됩니다. Cloud Shell 터미널에서 다음 명령어를 실행합니다.
명령어
gcloud edge-cache services import cme-demo \ --source=cme-demo.yaml
명령어의 출력을 확인하고 IP가 호스트 목록에 표시되는지 확인합니다.
이 시점에서 에지 캐시 서비스 인스턴스는 "demo.cme.com"
또는 IP 주소를 호스트로 사용하는 요청을 허용합니다.
12. 입력 신호 생성
이제 필요한 모든 서비스를 구성했으므로 라이브 스트림 입력 신호를 생성해 보겠습니다. 이 섹션에서는 다음을 수행합니다.
- 무료 오픈소스 소프트웨어인 FFmpeg 설치
- 입력/채널에 테스트 라이브 신호 전송
1. FFmpeg 설치
FFmpeg는 동영상, 오디오, 기타 멀티미디어 파일 및 스트림을 처리하기 위한 라이브러리 및 프로그램 모음으로 구성된 무료 오픈소스 소프트웨어 프로젝트입니다. Cloud Shell 터미널에서 다음 명령어를 사용하여 FFmpeg를 설치합니다.
명령어
sudo apt install ffmpeg -y
설치가 완료되면 버전을 확인하여 FFmpeg가 제대로 설치되었는지 확인합니다.
명령어
ffmpeg -version
출력 예시
ffmpeg version 4.3.4-0+deb11u1 Copyright (c) 2000-2021 the FFmpeg developers built with gcc 10 (Debian 10.2.1-6) ...
FFmpeg가 제대로 설치되었습니다.
2. 입력/채널에 대한 라이브 스트림 신호를 시작합니다.
이제 FFmpeg가 설치되었으므로 라이브 스트림을 생성하기 위해 테스트 입력 스트림을 입력 엔드포인트로 전송합니다.
Cloud Shell 터미널에서 '입력 엔드포인트 만들기 및 구성' 섹션에서 만든 URI 환경 변수를 사용하여 다음 명령어를 실행합니다.
명령어
ffmpeg -re -f lavfi -i "testsrc=size=1280x720 [out0]; sine=frequency=500 [out1]" \ -acodec aac -vcodec h264 -f flv $URI
FFmpeg가 테스트 실시간 신호를 전송하는 것을 볼 수 있습니다. 이 명령어는 프롬프트를 반환하지 않습니다. 중지할 때까지 신호가 생성됩니다. 나머지 실습에서는 새 Cloud Shell 창을 열어야 합니다.
13. 새 Cloud Shell 열기
이 시점에서 실습을 계속하려면 새 Cloud Shell 창을 열어야 합니다. FFmpeg는 명령어를 <CTRL+C>하여 중지하고 실시간 신호 생성을 중지할 때까지 영구적으로 실행되기 때문입니다.
현재 Cloud Shell 터미널 이름 옆에 있는 '+' 기호를 클릭합니다. Cloud Shell 창이 하나 더 열립니다.
새로 열린 Cloud Shell 창에서 나머지 실습을 실행합니다.
환경 변수 설정
새 CloudShell이므로 환경 변수를 다시 설정해야 합니다. source
명령어를 사용하여 환경 변수를 설정합니다.
명령어
source ~/env_variables.txt
변수가 설정되어 있는지 확인
필요한 모든 환경 변수가 설정되었는지 확인해 보겠습니다. 출력에 총 6개의 환경 변수가 표시됩니다.
명령어
env | grep -E 'DEVSHELL_PROJECT_ID=|LOGNAME|PROJECT_NUMBER|LOCATION|INPUT_ID|CHANNEL_ID'
출력 예시
LOCATION=us-west2 DEVSHELL_PROJECT_ID=<YOUR_PROJECT_ID> LOGNAME=<YOUR_USERNAME> PROJECT_NUMBER=<YOUR_PROJECT_NUMBER> INPUT_ID=lab-live-input CHANNEL_ID=lab-live-channel
14. 라이브 신호가 트랜스코딩되고 있는지 확인
curl
를 실행하여 채널을 설명합니다. 출력에서 streamingState가 "AWAITING_INPUT"
에서 "STREAMING"
으로 변경된 것을 확인할 수 있습니다.
명령어
curl -s -X GET -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID" | grep "streamingState"
출력 JSON 파일 응답에 "streamingState": "STREAMING"
이 표시되면 채널이 스트리밍되고 라이브 신호가 트랜스코딩되고 있음을 나타냅니다.
매니페스트 파일과 여러 TS 동영상 세그먼트가 표시되어야 하는 버킷의 콘텐츠도 확인해 보겠습니다. Cloud Shell에서 다음 명령어를 실행하여 실습 시작 부분에 만들고 Live Streaming API에서 트랜스코딩된 라이브 신호 매니페스트와 TS 동영상 세그먼트를 출력하는 데 사용한 버킷의 콘텐츠를 나열합니다.
명령어
gcloud storage ls --recursive gs://live-streaming-storage-$LOGNAME/**
출력 예시
gs://live-streaming-storage-$LOGNAME/ gs://live-streaming-storage-$LOGNAME/main.m3u8 gs://live-streaming-storage-$LOGNAME/mux_video_ts/index-1.m3u8 gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000016.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000017.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000018.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000019.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000020.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000021.ts gs://live-streaming-storage-$LOGNAME/mux_video_ts/segment-0000000022.ts ...
다음과 같이 표시됩니다.
- HLS 매니페스트 파일(
main.m3u8
) - 해당하는 TS 동영상 세그먼트: 번호가 매겨진 일련의 파일
segment-000000000X.ts
이제 다음 작업이 완료되었습니다.
- Live Streaming API: 라이브 신호가 생성되고 Live Streaming API를 통해 버킷으로 트랜스코딩됩니다.
- Media CDN: 라이브 스트리밍 저장소 버킷을 Media CDN의 출처로 사용하여 Media CDN을 구성했습니다.
다음 섹션에서는 에지 캐시 서비스를 확인한 후 미디어 CDN Anycast IP 주소를 사용하여 트랜스코딩된 동영상을 스트리밍합니다.
15. 에지 캐시 서비스 인스턴스가 작동하는지 확인
이 섹션에서는 Edge Cache Service 인스턴스가 예상대로 작동하는지 확인합니다. 이를 위해 에지 캐시 서비스 서비스의 IP 주소를 사용하여 에지 캐시 서비스 인스턴스에서 파일에 액세스하려고 시도합니다. 객체에 처음 액세스할 때는 아직 캐시되지 않습니다. 캐시 MISS
가 관찰됩니다. 첫 번째 요청의 경우 객체가 출처에서 읽혀 에지에서 캐시됩니다. 이제 객체가 에지에 캐시되므로 동일한 파일에 액세스하려는 후속 시도 모두 캐시 HIT
를 반환합니다. 이 동작을 확인해 보겠습니다.
Cloud Shell에서 다음 curl
명령어를 실행하여 Edge 캐시 출처에 저장된 트랜스코딩된 동영상 매니페스트 파일에 액세스합니다.
명령어
curl -svo /dev/null --resolve demo.cme.com:80:<Replace_With_Edge_Cache_IP> \ "http://demo.cme.com/main.m3u8"
에지 캐시 서비스 인스턴스의 IP 주소를 사용하여 이름을 확인하는 resolve를 확인합니다. IP가 방금 만든 에지 캐시 서비스 인스턴스의 IP인 demo.cme.com:<IP>
를 사용합니다.
출력에서 x-cache-status
헤더를 찾습니다.
출력 예시
Added demo.cme.com:80:34.104.35.152 to DNS cache * Hostname demo.cme.com was found in DNS cache * Trying 34.104.35.152:80... * Connected to demo.cme.com (34.104.35.152) port 80 (#0) > GET /main.m3u8 HTTP/1.1 > Host: demo.cme.com > User-Agent: curl/7.74.0 > Accept: */* > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < x-guploader-uploadid: ADPycdtKtflWt4Kha5YxXNNRwO-Eu6fGSPs-T-XY4HJmNMo46VJyWlD4EAk-8a6SegxjWq3o1gTPqZbpkU_sjW__HPAdDw < date: Wed, 07 Dec 2022 18:23:46 GMT < last-modified: Wed, 07 Dec 2022 18:23:45 GMT < etag: "6bff620ccca4a9849ba4e17fa7c521fb" < x-goog-generation: 1670437425805400 < x-goog-metageneration: 1 < x-goog-stored-content-encoding: identity < x-goog-stored-content-length: 193 < content-type: application/x-mpegURL < x-goog-hash: crc32c=sPO3zw== < x-goog-hash: md5=a/9iDMykqYSbpOF/p8Uh+w== < x-goog-storage-class: STANDARD < accept-ranges: bytes < content-length: 193 < server: Google-Edge-Cache < x-request-id: fd25285b-fc1a-4fd4-981a-c50ead2c85ed < x-xss-protection: 0 < x-frame-options: SAMEORIGIN < x-cache-status: den;miss < cache-control: public,max-age=3600 < { [193 bytes data] * Connection #0 to host demo.cme.com left intact
객체가 아직 캐시되지 않았고 출처에서 읽히므로 캐시 누락이 발생합니다.
이제 m3u8
파일을 여러 번 요청합니다. 모든 것이 올바르게 구성된 경우 Media CDN이 캐시에서 콘텐츠를 게재하기 시작합니다. 아래 명령어는 curl 요청을 10번 실행하고 x-cache-status
헤더만 출력합니다.
명령어
for i in {1..10};do curl -Is --resolve demo.cme.com:80:<Replace_With_Edge_Cache_IP> "http://demo.cme.com/main.m3u8" | grep x-cache-status;done
출력은 캐시 hit
와 miss
가 혼합되어야 합니다. 출력에 캐시 히트가 표시되면 Media CDN이 예상대로 작동하는 것입니다.
출력 예시
x-cache-status: den;miss x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit x-cache-status: den;hit
이제 객체가 에지에 캐시되므로 캐시 히트가 표시됩니다. Cloud Media Edge 서비스가 예상대로 작동하고 있습니다.
16. VLC로 트랜스코딩된 라이브 신호 동영상 스트리밍
이제 지금까지 진행한 모든 단계를 연결합니다.
- Live Streaming API로 HLS 콘텐츠로 트랜스코딩된 라이브 신호의 결과를 수신하는
live-streaming-storage-$LOGNAME
라는 버킷을 만들었습니다. - Live Streaming API를 설정했습니다.
- Live Streaming API 입력/채널에 피드하는 FFmpeg로 RTMP 라이브 신호를 시작했습니다.
- 라이브 신호가 채널에 전송되고 채널이
streaming
모드인지 확인했습니다. - 결과적으로 트랜스코딩된 파일 (매니페스트 + TS 세그먼트)이 생성되어 버킷
live-streaming-storage-$LOGNAME
에 저장되었음을 확인했습니다. cme-origin
라는 에지 캐시 출처가 GCS 버킷live-streaming-storage-$LOGNAME
를 출처로 설정되었습니다.cme-demo
라는 에지 캐시 인스턴스가cme-origin
를 출처로 설정되었습니다.- 에지 캐시 서비스 인스턴스의 동작 (캐시 미스, 캐시 적중)을 확인했습니다.
이제 동영상 플레이어를 사용하여 Media CDN 캐시를 통해 트랜스코딩된 라이브 신호를 스트리밍할 수 있습니다. 이를 위해 VLC 플레이어를 사용합니다. VLC 플레이어는 대부분의 멀티미디어 파일을 재생하는 무료 오픈소스 크로스 플랫폼 멀티미디어 플레이어 및 프레임워크입니다. 적응형 미디어 형식 (예: DASH 및 HLS)을 재생합니다. 가변 품질 스트리밍의 원리를 사용합니다. 네트워크 연결 품질과 사용 가능한 대역폭에 따라 플레이어에서 재생되는 동영상의 화질을 조정합니다. 방금 수행한 트랜스코딩 작업에서는 기본 사전 설정을 사용했으며 SD 및 HD의 두 가지 화질만 '생성'했습니다. 플레이어에서 동영상 재생을 시작하면 SD 형식으로 재생되다가 네트워크 연결이 충분히 양호하면 HD 형식으로 빠르게 전환되는 것을 볼 수 있습니다.
YouTube에서는 트랜스코딩된 라이브 신호를 HLS (널리 지원되는 Apple 동영상 형식)로 스트리밍합니다. 해당 파일은 HLS 매니페스트인 main.m3u8
입니다. 매니페스트는 TS 동영상 세그먼트를 가리킵니다.
VLC 플레이어를 사용하려면 https://www.videolan.org/vlc/로 이동하여 노트북 운영체제에 맞는 플레이어 버전을 다운로드하세요. VLC는 Windows, MacOSX, Linux, Android, iOS에서 사용할 수 있습니다.
노트북에 플레이어를 설치하고 실행합니다. 다음 몇 단계에서는 MacOSX 버전의 플레이어를 사용합니다.
동영상을 재생하려면 '파일' / '네트워크 열기'로 이동합니다.
다음을 사용하여 설정합니다.
- URL: http://<Replace_With_Edge_Cache_IP>/main.m3u8 스트리밍할 동영상의 URL입니다. 참고:
- Media CDN 인스턴스의 IP:
34.105.35.246
배포한 Cloud 미디어 서비스의 IP로 바꿉니다. - 매니페스트 동영상 파일의 경로: '
/
'.live-streaming-storage-$LOGNAME
버킷에서 트랜스코딩된 라이브 신호 파일을 저장하는 데 사용된 경로입니다. 경로는 여기서 루트 경로인 '/'입니다. - 매니페스트 동영상 파일의 이름: HLS 매니페스트 파일
main.m3u8
'열기'를 클릭합니다. 트랜스코딩된 라이브 동영상이 재생되기 시작합니다. 동영상은 아래 스크린샷과 같이 표시됩니다. 화면의 카운터가 1씩 증가하며 연속적인 비프음이 들립니다.
FFmpeg에서 생성되고 Live Streaming API로 HLS로 트랜스코딩되며 Media CDN 캐시를 통해 제공되는 기본 RTMP 테스트 라이브 신호입니다.
원하는 경우 다른 HLS 및 MPEG DASH 플레이어를 사용할 수 있습니다. 다음은 고려해 볼 만한 플레이어입니다.
- Quicktime 플레이어 - Mac에 기본적으로 설치되어 있습니다. 여기서도 마찬가지입니다. http://34.104.36.157/main.m3u8에 대한 네트워크 연결을 엽니다. IP 주소를 에지 캐시 서비스 인스턴스의 IP 주소로 바꿉니다.
17. Media CDN 모니터링
SME팀에서 Media CDN 대시보드 템플릿을 만들었습니다(https://gist.github.com/elithrar/1c511d00f5cd3736fb2a3897867209c1).
차트를 설치하려면 Cloud Shell 창에서 다음 명령어를 실행합니다.
YAML 파일을 다운로드합니다.
curl https://gist.githubusercontent.com/elithrar/1c511d00f5cd3736fb2a3897867209c1/raw/3cb70855304f29e5c06b8d63063196354db0dec3/media-edge-20210208-dashboard --output media-edge-20210208-dashboard.yaml
Cloud Monitoring 대시보드를 만듭니다.
gcloud monitoring dashboards create --config-from-file media-edge-20210208-dashboard.yaml
설정하는 데 몇 분 정도 걸릴 수 있습니다. Google Cloud 콘솔로 이동하여 막대 3개 > 작업 > 모니터링 > 대시보드를 클릭합니다. '미디어 에지 측정항목'이라는 대시보드가 표시됩니다. 클릭하면 측정항목이 표시됩니다.
18. 실습 환경 정리
실습을 완료하셨습니다. 이 섹션에서는 실습 과정에서 만든 모든 리소스를 삭제합니다.
FFmpeg 신호 중지:
FFmpeg가 실행 중인 Cloud Shell 터미널에서 <CTRL+C>
키를 누릅니다.
라이브 스트리밍 채널을 중지합니다.
명령어
curl -X POST \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ -H "Content-Type: application/json; charset=utf-8" \ -d "" \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID:stop"
라이브 스트리밍 채널을 삭제합니다.
명령어
curl -X DELETE -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/channels/$CHANNEL_ID"
라이브 스트리밍 입력 엔드포인트를 삭제합니다.
명령어
curl -X DELETE \ -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) \ "https://livestream.googleapis.com/v1/projects/$PROJECT_NUMBER/locations/$LOCATION/inputs/$INPUT_ID"
GCS 버킷 삭제:
명령어
gsutil rm -r gs://live-streaming-storage-$LOGNAME
에지 캐시 서비스 인스턴스 삭제:
명령어
gcloud edge-cache services delete cme-demo
메시지가 표시되면 'Y'를 입력하여 삭제를 확인합니다.
에지 캐시 출처 삭제:
명령어
gcloud edge-cache origins delete cme-origin
메시지가 표시되면 'Y'를 입력하여 삭제를 확인합니다.
맞춤 대시보드 삭제하기
명령어
gcloud monitoring dashboards delete $(gcloud monitoring dashboards list --filter="displayName:Media Edge Metrics" --format="value(name)")