Back to Blog

Astro를 사용하여 클라우드 레코딩 백엔드 구축

모든 사람이 모든 회의에 참석할 수 있는 것은 아닙니다. 예를 들어, 저는 지루한 회의에 참석하는 것이 어렵습니다. 저와 같은 사람들에게는 회의 녹화본이 게임 체인저입니다.

이 가이드는 아고라 비디오 통화용 백엔드를 구축하는 시리즈의 두 번째 부분입니다. 첫 번째 가이드는 토큰 생성기를 구축하는 것이었습니다. 이 가이드는 해당 토큰 생성기를 사용하고 비디오 통화에 클라우드 녹화 기능을 추가할 것입니다.

필수 조건

  1. NodeJS와 Astro가 설치되어 있어야 합니다.
  2. 아고라 개발자 계정.
  3. Astro로 구축된 토큰 생성기. 가이드를 여기에서 확인하세요.
  4. AWS S3 스토리지 버킷.

프로젝트 설정

이 가이드는 토큰 생성기 가이드를 기반으로 합니다. 토큰 생성기 가이드는 api/tokens.json 엔드포인트를 구축하는 과정을 설명합니다. 이 엔드포인트는 비디오 통화를 보호하는 데 사용되는 토큰을 반환합니다. 이 엔드포인트는 토큰 생성 논리를 처리하는 handleGenerateToken 함수를 사용합니다. 동일한 백엔드 서버에 있으므로 이 함수를 클라우드 녹화 엔드포인트 내에서 직접 사용할 것입니다.

이전 가이드에서 APP_IDAPP_CERTIFICATE가 환경 변수에 설정되어 있어야 합니다. 이 가이드에서 추가 환경 변수를 추가할 예정이지만, 현재는 이 상태로 시작할 수 있습니다.

클라우드 레코딩 개요

클라우드 녹화는 아고라에서 제공하는 RESTful API로, 선택한 스토리지 제공업체에 비디오 통화를 녹화할 수 있습니다. 백엔드에서 이 녹화를 트리거해야 민감한 데이터가 애플리케이션과 직접 전송되지 않습니다.

성공적인 클라우드 녹화 세션의 흐름은 다음과 같습니다:

  1. 아고라 클라우드 녹화 리소스를 획득합니다.
  2. 맞춤형 저장소 구성으로 클라우드 녹화를 시작합니다. 이에는 저장소 제공업체에 파일을 작성하기 위해 필요한 키가 포함됩니다.
  3. 30초마다 클라우드 녹화 상태를 쿼리하여 정상적으로 실행 중인지 확인합니다.
  4. 클라우드 녹화를 중지합니다.

아고라 RESTful API 활성화

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

AWS S3 버킷에 연결

아고라는 대부분의 인기 있는 저장 솔루션에 녹화를 지원합니다. 이 가이드에서는 AWS S3를 사용할 것입니다. AWS는 복잡한 백엔드 구성의 거대한 플랫폼입니다. 이 가이드에서는 아고라 구현에 집중하기 위해 탄탄한 AWS 인프라를 구축하는 대신 루트 사용자 액세스 키와 공개 버킷을 사용할 것입니다.

IAM으로 이동하여 “내 보안 자격 증명”을 클릭한 후 “액세스 키 생성” 버튼을 클릭하여 새로운 루트 사용자 액세스 키를 생성합니다. 이 정보를 ACCESS_KEYSECRET_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.jsonsidresourceId
  • api/recording/stop.jsonchannel, sidresourceId

모든 것이 정상적으로 실행되면, 나중에 채울 데이터와 함께 헬퍼 함수를 사용하여 성공적인 응답을 전송합니다.

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를 받게 됩니다. sidresourceId는 녹화를 중지하거나 쿼리할 때 모두 필요하므로, 반드시 호출자에게 반환해야 합니다.

이 기능을 테스트하려면 백엔드를 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을 사용하고 시작 엔드포인트의 반환 값에서 sidresourceId를 전달할 수 있습니다.

참고: 이 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를 사용하여 비디오 통화 프론트엔드를 구축하는 방법에 대한 가이드를 참고하세요.

RTE Telehealth 2023
Join us for RTE Telehealth - a virtual webinar where we’ll explore how AI and AR/VR technologies are shaping the future of healthcare delivery.

Learn more about Agora's video and voice solutions

Ready to chat through your real-time video and voice needs? We're here to help! Current Twilio customers get up to 2 months FREE.

Complete the form, and one of our experts will be in touch.

Try Agora for Free

Sign up and start building! You don’t pay until you scale.
Try for Free