모든 사람이 모든 회의에 참석할 수 있는 것은 아닙니다. 예를 들어, 저는 지루한 회의에 참석하는 것이 어렵습니다. 저와 같은 사람들에게는 회의 녹화본이 게임 체인저입니다.
이 가이드는 아고라 비디오 통화용 백엔드를 구축하는 시리즈의 두 번째 부분입니다. 첫 번째 가이드는 토큰 생성기를 구축하는 것이었습니다. 이 가이드는 해당 토큰 생성기를 사용하고 비디오 통화에 클라우드 녹화 기능을 추가할 것입니다.
필수 조건
- NodeJS와 Astro가 설치되어 있어야 합니다.
- 아고라 개발자 계정.
- Astro로 구축된 토큰 생성기. 가이드를 여기에서 확인하세요.
- AWS S3 스토리지 버킷.
프로젝트 설정
이 가이드는 토큰 생성기 가이드를 기반으로 합니다. 토큰 생성기 가이드는 api/tokens.json
엔드포인트를 구축하는 과정을 설명합니다. 이 엔드포인트는 비디오 통화를 보호하는 데 사용되는 토큰을 반환합니다. 이 엔드포인트는 토큰 생성 논리를 처리하는 handleGenerateToken
함수를 사용합니다. 동일한 백엔드 서버에 있으므로 이 함수를 클라우드 녹화 엔드포인트 내에서 직접 사용할 것입니다.
이전 가이드에서 APP_ID
및 APP_CERTIFICATE
가 환경 변수에 설정되어 있어야 합니다. 이 가이드에서 추가 환경 변수를 추가할 예정이지만, 현재는 이 상태로 시작할 수 있습니다.
클라우드 레코딩 개요
클라우드 녹화는 아고라에서 제공하는 RESTful API로, 선택한 스토리지 제공업체에 비디오 통화를 녹화할 수 있습니다. 백엔드에서 이 녹화를 트리거해야 민감한 데이터가 애플리케이션과 직접 전송되지 않습니다.
성공적인 클라우드 녹화 세션의 흐름은 다음과 같습니다:
- 아고라 클라우드 녹화 리소스를 획득합니다.
- 맞춤형 저장소 구성으로 클라우드 녹화를 시작합니다. 이에는 저장소 제공업체에 파일을 작성하기 위해 필요한 키가 포함됩니다.
- 30초마다 클라우드 녹화 상태를 쿼리하여 정상적으로 실행 중인지 확인합니다.
- 클라우드 녹화를 중지합니다.

아고라 RESTful API 활성화
이 가이드 전체는 아고라 RESTful API와의 연결에 의존합니다. 연결하려면 고객 ID와 고객 비밀번호가 필요합니다. 이 값은 아고라 콘솔에 접속한 후 개발자 도구 키트 아래의 RESTful API 탭을 선택하고 “비밀번호 추가” 버튼을 클릭하여 찾을 수 있습니다. 그런 다음 이 값을 복사하여 CUSTOMER_ID
및 CUSTOMER_SECRET
환경 변수에 저장합니다.

AWS S3 버킷에 연결
아고라는 대부분의 인기 있는 저장 솔루션에 녹화를 지원합니다. 이 가이드에서는 AWS S3를 사용할 것입니다. AWS는 복잡한 백엔드 구성의 거대한 플랫폼입니다. 이 가이드에서는 아고라 구현에 집중하기 위해 탄탄한 AWS 인프라를 구축하는 대신 루트 사용자 액세스 키와 공개 버킷을 사용할 것입니다.
IAM으로 이동하여 “내 보안 자격 증명”을 클릭한 후 “액세스 키 생성” 버튼을 클릭하여 새로운 루트 사용자 액세스 키를 생성합니다. 이 정보를 ACCESS_KEY
및 SECRET_KEY
환경 변수에 저장합니다.

그런 다음 S3로 이동하여 새로운 버킷을 생성합니다. 이 버킷은 테스트 목적으로 구축 중이므로 “모든 공개 액세스 차단” 옵션을 해제합니다. 버킷 이름을 BUCKET_NAME
환경 변수에 저장합니다.

엔드포인트 정의
우리는 세 개의 엔드포인트를 가집니다: api/recording/start.json
, api/recording/query.json
, 및 api/recording/stop.json
. 엔드포인트가 입력 정보를 필요로 하기 때문에, 우리는 입력 정보를 요청 본문에 전달하기 위해 POST
요청을 사용할 것입니다.
이 입력 값이 빈 값이 아닌지 확인합니다. 빈 값인 경우, utils/sendResponse.ts
에 정의된 헬퍼 함수를 사용하여 Bad Request 응답을 반환합니다.
엔드포인트는 요청 본문에 다음과 같은 정보를 필요로 합니다:
api/recording/start.jsonchannel
api/recording/query.jsonsid
및resourceId
api/recording/stop.jsonchannel
,sid
및resourceId
모든 것이 정상적으로 실행되면, 나중에 채울 데이터와 함께 헬퍼 함수를 사용하여 성공적인 응답을 전송합니다.
import type { APIContext } from "astro";
export async function POST({ request }: APIContext) {
const { channel } = await request.json()
if (!channel) {
return sendBadRequest("channel is required")
}
return sendSuccessfulResponse("<return data>")
}
요청 헬퍼 함수 만들기
이 가이드의 나머지 부분은 아고라 API 호출을 포함하는 Cloud Recording 구현에 초점을 맞출 것입니다. 코드를 간소화하고 일관된 요청 구조를 유지하기 위해 utils/makeRequest.ts
에 헬퍼 함수를 설정할 것입니다.
makeRequest
함수는 모든 헤더를 정의하고 요청을 실행한 후 응답을 반환합니다.
입력 매개변수는 method
(GET과 POST를 사용할 것입니다), url
, body
, 및 credential
입니다.
export const makeRequest = async (method: string, url: string, credential: string, body?: string) => {
const headers = new Headers({
"Authorization": "basic " + credential,
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": `${method}, OPTIONS`,
});
const res = await fetch(url, {
method: method,
headers: headers,
body: body
})
if (!res.ok) {
console.log(await res.text())
throw new Error("Failed to make request")
}
return res
}
Another helper function in utils/generateCredential.ts
will generate this credential. It is a base-64 encoded credential using the Customer ID and Customer Secret.
export const generateCredential = () => {
const credential = import.meta.env.CUSTOMER_ID + ":" + import.meta.env.CUSTOMER_SECRET
const base64_credential = btoa(credential)
return base64_credential
}
리소스 생성
비디오 통화를 녹화하기 위한 첫 번째 단계는 녹화를 위한 리소스를 생성하는 것입니다. 이 과정에서는 배경에서 비디오 통화를 녹화할 수 있는 Agora 백엔드 서비스가 실행됩니다.
경고: 클라우드 녹화는 5분 이내에 시작해야 하며, 그렇지 않으면 리소스가 종료됩니다.
이 리소스를 생성하려면 Agora 서비스에 첫 번째 요청을 전송합니다. 이 요청은 acquire
함수를 사용합니다. 채널 이름과 리소스의 uid를 반드시 전달해야 합니다.
이 함수를 위해 엔드포인트를 생성할 필요는 없습니다. 이 함수는 동일한 백엔드 서버 내에서 클라우드 녹화 세션을 시작할 때만 사용되기 때문입니다. 이 때문에 이 함수는 코드를 정리하기 위해 utils/generateResource.ts
파일에 정의합니다.
import { makeRequest } from "./makeRequest"
export const generateCloudRecordingResource = async (channel: string, credential: string, uid: string, appId: string) => {
const body = {
"cname": channel,
"uid": uid,
"clientRequest": {}
}
const url = `https://api.agora.io/v1/apps/${appId}/cloud_recording/acquire`
const res = await makeRequest("POST", url, credential, JSON.stringify(body))
const data = await res.json()
const resourceId = data["resourceId"]
return resourceId
}
클라우드 녹화 시작
이전 섹션을 결합하여 api/recording/start.json.ts
파일의 POST 함수 내에서 녹화를 시작할 수 있습니다. 먼저 자격 증명을 생성한 후 해당 자격 증명을 사용하여 리소스를 생성하고 토큰을 생성합니다.
그 다음, 아고라 start
엔드포인트 URL로 요청을 전송하고 요청 본문을 전달합니다. 이 본문에는 아고라 클라우드 녹화 서비스가 필요한 모든 정보가 정의됩니다.
요청 본문 속성의 전체 목록은 아고라 문서에서 확인할 수 있습니다. 이 데모에서는 AWS를 공급업체로, US_EAST_2를 지역으로 정의합니다. 그 다음 해당 스토리지 버킷에 액세스하기 위해 필요한 모든 정보를 제공하며, 마지막으로 파일 경로와 파일 출력 유형을 정의합니다.
const recordingUid = "1"
const credential = generateCredential()
const resourceId = await generateCloudRecordingResource(channel, credential, recordingUid, APP_ID)
const token = await handleGenerateToken({ channel: channel, role: 1, uid: recordingUid, expireTime: 3600 })
const url = `https://api.agora.io/v1/apps/${APP_ID}/cloud_recording/resourceid/${resourceId}/mode/mix/start`
const body = {
"cname": channel,
"uid": recordingUid,
"clientRequest": {
"token": token,
"storageConfig": {
"secretKey": SECRET_KEY,
"vendor": 1,
"region": 1,
"bucket": BUCKET_NAME,
"accessKey": ACCESS_KEY,
"fileNamePrefix": [
"recording",
Date.now().toString()
]
},
"recordingFileConfig": {
"avFileType": [
"hls",
"mp4"
]
},
},
}
const res = await makeRequest("POST", url, credential, JSON.stringify(body))
const data = await res.json()
const sid = data.sid
return sendSuccessfulResponse({
resourceId: resourceId,
sid: sid
})
성공적인 응답이 돌아오면 sid
를 받게 됩니다. sid
와 resourceId
는 녹화를 중지하거나 쿼리할 때 모두 필요하므로, 반드시 호출자에게 반환해야 합니다.
이 기능을 테스트하려면 백엔드를 npm run dev
로 실행하세요. 터미널에서 cURL을 사용하여 POST
요청을 보내고, 요청 본문에 channel
를 포함시켜 테스트할 수 있습니다.
curl -X POST http://localhost:4321/api/recording/start.json \
-H "Content-Type: application/json" \
-d '{
"channel": "test"
}'
POST
요청에 정보가 누락된 경우, 누락된 내용을 알려주는 Bad Request 응답을 받게 됩니다. 요청이 올바른 경우, 다음과 같은 성공 응답을 받게 됩니다:
{"resourceId":"<long string>","sid":"<another long string>"}
클라우드 녹화 쿼리
클라우드 녹화가 실행 중일 때, 모든 것이 정상적으로 실행되고 있는지 확인하기 위해 주기적으로 쿼리를 실행합니다.
아고라 query
URL을 사용하고 GET 메서드로 호출합니다.
const credential = generateCredential()
const url = `https://api.agora.io/v1/apps/${APP_ID}/cloud_recording/resourceid/${resourceId}/sid/${sid}/mode/mix/query`
const res = await makeRequest("GET", url, credential)
const data = await res.json()
return sendSuccessfulResponse(data)
이를 테스트하려면 cURL을 사용하고 시작 엔드포인트의 반환 값에서 sid
및 resourceId
를 전달할 수 있습니다.
참고: 이 App ID 및 채널과 연결된 비디오 통화 상태여야 합니다. Agora 백엔드는 기록할 내용이 없을 경우 녹화를 시작하지 않습니다.
curl -X POST http://localhost:4321/api/recording/query.json \
-H "Content-Type: application/json" \
-d '{
"sid": "<from start command return>",
"resourceId": "<from start command return>"
}'
클라우드 녹화 중지
마지막으로 클라우드 녹화를 중지해야 합니다. 이 명령은 시작 또는 쿼리 명령과 매우 유사하지만 Agora stop
URL을 사용합니다.
const recordingUid = "1"
const credential = generateCredential()
const url = `https://api.agora.io/v1/apps/${APP_ID}/cloud_recording/resourceid/${resourceId}/sid/${sid}/mode/mix/stop`
const body = {
"cname": channel,
"uid": recordingUid,
"clientRequest": {
}
}
const res = await makeRequest("POST", url, credential, JSON.stringify(body))
const data = await res.json()
return sendSuccessfulResponse(data)
다시 한 번, 이 기능을 cURL을 사용하여 테스트해 볼 수 있습니다.
curl -X POST http://localhost:4321/api/recording/stop.json \
-H "Content-Type: application/json" \
-d '{
"channel": "test"
"sid": "<from start command return>",
"resourceId": "<from start command return>"
}'
이제 Astro를 사용하여 완전히 작동하는 클라우드 녹화 백엔드를 갖추게 되었으며, 더 이상 모든 회의에 참여해야 하는 번거로움을 걱정하지 않아도 됩니다.
Astro에 토큰 생성기와 클라우드 녹화 백엔드가 구축되었기 때문에, 프론트엔드를 추가하여 단일 코드베이스에서 모든 기능을 포함한 안전한 비디오 통화를 구현할 수 있습니다. Astro를 사용하여 비디오 통화 프론트엔드를 구축하는 방법에 대한 가이드를 참고하세요.