Files
sam-kd/voice_ai/구글클라우드스토리지설정방법.md
hskwon aca1767eb9 초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경
- DB 연결 하드코딩 → .env 기반으로 변경
- MySQL strict mode DATE 오류 수정
2025-12-10 20:14:31 +09:00

9.0 KiB

Google Cloud Storage (GCS) 설정 방법

개요

Google Speech-to-Text API에서 긴 오디오 파일(약 1분 이상)을 처리하려면 Google Cloud Storage에 파일을 업로드하고 GCS URI를 사용해야 합니다.


1. Google Cloud Storage 버킷 생성

1-1. Google Cloud Console 접속

  1. Google Cloud Console 접속
  2. 프로젝트 선택 (예: codebridge-chatbot)

1-2. Storage 버킷 생성

  1. 왼쪽 메뉴에서 Cloud Storage > 버킷 클릭
  2. 버킷 만들기 클릭
  3. 버킷 정보 입력:
    • 이름: speech-audio-files (또는 원하는 이름)
    • 위치 유형: 리전 선택
    • 위치: asia-northeast3 (서울) 또는 가까운 리전 선택
    • 스토리지 클래스: Standard (기본값)
    • 액세스 제어: 균일하게 적용 선택
  4. 만들기 클릭

2. 서비스 계정에 Storage 권한 부여

2-1. IAM 권한 추가

  1. IAM 및 관리자 > 서비스 계정 메뉴로 이동
  2. 사용 중인 서비스 계정 선택 (예: vertex-ai-client)
  3. 권한 탭 클릭
  4. 역할 부여 클릭
  5. 다음 역할 추가:
    • Storage 객체 관리자 (roles/storage.objectAdmin)
      • 또는 Storage 객체 생성자 (roles/storage.objectCreator) + Storage 객체 뷰어 (roles/storage.objectViewer)
  6. 저장 클릭

2-2. 버킷별 권한 설정 (선택사항)

  1. Cloud Storage > 버킷 메뉴로 이동
  2. 생성한 버킷 선택
  3. 권한 탭 클릭
  4. 주 구성원 추가 클릭
  5. 서비스 계정 이메일 입력 (예: vertex-ai-client@codebridge-chatbot.iam.gserviceaccount.com)
  6. 역할: Storage 객체 관리자 선택
  7. 저장 클릭

3. PHP 코드에 GCS 업로드 기능 추가

3-1. 방법 1: REST API 직접 사용 (추천 - 라이브러리 불필요)

서비스 계정을 사용하여 OAuth 2.0 토큰을 생성하고, Google Cloud Storage REST API를 직접 호출합니다.

장점:

  • 추가 라이브러리 불필요
  • 가볍고 빠름
  • 기존 코드와 일관성 유지

GCS 업로드 함수 (REST API 사용):

function uploadToGCS($file_path, $bucket_name, $object_name, $service_account_path) {
    // 1. OAuth 2.0 토큰 생성 (기존 코드 재사용)
    $serviceAccount = json_decode(file_get_contents($service_account_path), true);
    $now = time();
    
    $jwtHeader = base64_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
    $jwtClaim = base64_encode(json_encode([
        'iss' => $serviceAccount['client_email'],
        'scope' => 'https://www.googleapis.com/auth/devstorage.full_control',
        'aud' => 'https://oauth2.googleapis.com/token',
        'exp' => $now + 3600,
        'iat' => $now
    ]));
    
    $privateKey = openssl_pkey_get_private($serviceAccount['private_key']);
    openssl_sign($jwtHeader . '.' . $jwtClaim, $signature, $privateKey, OPENSSL_ALGO_SHA256);
    openssl_free_key($privateKey);
    
    $jwt = $jwtHeader . '.' . $jwtClaim . '.' . base64_encode($signature);
    
    // OAuth 토큰 요청
    $tokenCh = curl_init('https://oauth2.googleapis.com/token');
    curl_setopt($tokenCh, CURLOPT_POST, true);
    curl_setopt($tokenCh, CURLOPT_POSTFIELDS, http_build_query([
        'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
        'assertion' => $jwt
    ]));
    curl_setopt($tokenCh, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($tokenCh, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
    
    $tokenResponse = curl_exec($tokenCh);
    $tokenData = json_decode($tokenResponse, true);
    $accessToken = $tokenData['access_token'];
    curl_close($tokenCh);
    
    // 2. GCS에 파일 업로드
    $file_content = file_get_contents($file_path);
    $mime_type = mime_content_type($file_path) ?: 'audio/webm';
    
    $upload_url = 'https://storage.googleapis.com/upload/storage/v1/b/' . 
                  urlencode($bucket_name) . '/o?uploadType=media&name=' . 
                  urlencode($object_name);
    
    $ch = curl_init($upload_url);
    curl_setopt($ch, CURLOPT_PUT, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Authorization: Bearer ' . $accessToken,
        'Content-Type: ' . $mime_type,
        'Content-Length: ' . strlen($file_content)
    ]);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $file_content);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    
    $response = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($code === 200) {
        return 'gs://' . $bucket_name . '/' . $object_name;
    } else {
        error_log('GCS 업로드 실패: ' . $response);
        return false;
    }
}

3-2. 방법 2: PHP 클라이언트 라이브러리 사용

Google Cloud Storage PHP 클라이언트 라이브러리가 필요한 경우:

composer require google/cloud-storage

GCS 업로드 함수 (라이브러리 사용):

function uploadToGCS($file_path, $bucket_name, $object_name, $service_account_path) {
    require_once __DIR__ . '/vendor/autoload.php';
    
    // 서비스 계정 인증
    $client = new \Google\Cloud\Storage\StorageClient([
        'keyFilePath' => $service_account_path
    ]);
    
    $bucket = $client->bucket($bucket_name);
    $object = $bucket->upload(
        fopen($file_path, 'r'),
        ['name' => $object_name]
    );
    
    // GCS URI 생성
    $gcs_uri = 'gs://' . $bucket_name . '/' . $object_name;
    
    return $gcs_uri;
}

4. process_meeting.php에 GCS 통합

4-1. 설정 파일 생성

/apikey/gcs_config.txt 파일 생성:

bucket_name=speech-audio-files
project_id=codebridge-chatbot

4-2. 코드 수정

큰 파일(10MB 이상 또는 1분 이상)인 경우:

  1. 파일을 GCS에 업로드
  2. GCS URI (gs://bucket-name/object-name) 생성
  3. Speech-to-Text API에 GCS URI 전달

5. GCS URI 형식

5-1. GCS URI 형식

gs://[BUCKET_NAME]/[OBJECT_NAME]

예시:

gs://speech-audio-files/meetings/20241201_143022_abc123.webm

5-2. 공개 URL vs GCS URI

  • GCS URI: gs://bucket/object (Google API에서 직접 접근)
  • 공개 URL: https://storage.googleapis.com/bucket/object (웹 브라우저 접근)

참고: Speech-to-Text API는 GCS URI만 지원합니다. 공개 URL은 작동하지 않습니다.


6. 비용 고려사항

6-1. Storage 비용

  • Standard 스토리지: 약 $0.020/GB/월
  • 네트워크 전송: 약 $0.12/GB (아시아 리전 간)

6-2. 최적화 방법

  1. 수명 주기 규칙 설정: 7일 후 자동 삭제
  2. Nearline 또는 Coldline 스토리지: 장기 보관 시 사용
  3. 자동 삭제: STT 처리 후 즉시 삭제

7. 자동 삭제 설정 (수명 주기 규칙)

7-1. 수명 주기 규칙 생성

  1. Cloud Storage > 버킷 메뉴로 이동
  2. 버킷 선택
  3. 수명 주기 탭 클릭
  4. 규칙 추가 클릭
  5. 규칙 설정:
    • 조건: 객체가 7일 이상 되었을 때
    • 작업: 삭제 선택
  6. 만들기 클릭

7-2. 코드에서 삭제

STT 처리 완료 후 PHP 코드에서 삭제:

$object->delete();

8. 테스트 방법

8-1. 수동 테스트

  1. Google Cloud Console에서 버킷에 파일 업로드
  2. GCS URI 확인: gs://bucket-name/file-name
  3. Speech-to-Text API에 GCS URI 전달하여 테스트

8-2. 코드 테스트

  1. 작은 파일(30초 이하)로 먼저 테스트
  2. 큰 파일(1분 이상)로 GCS 업로드 테스트
  3. 오류 로그 확인

9. 문제 해결

9-1. 권한 오류

  • 증상: "Permission denied" 오류
  • 해결: 서비스 계정에 Storage 권한 확인

9-2. 버킷을 찾을 수 없음

  • 증상: "Bucket not found" 오류
  • 해결: 버킷 이름과 프로젝트 ID 확인

9-3. 파일 업로드 실패

  • 증상: 업로드 중 오류
  • 해결:
    • 파일 크기 확인
    • 네트워크 연결 확인
    • 서비스 계정 권한 확인

10. 보안 고려사항

10-1. 버킷 액세스 제어

  • 공개 버킷: 모든 사용자가 읽기 가능 (비추천)
  • 비공개 버킷: 서비스 계정만 접근 (권장)

10-2. 서명된 URL (선택사항)

임시 접근 URL 생성 (1시간 유효):

$url = $object->signedUrl(new \DateTime('+1 hour'));

11. 요약 체크리스트

  • Google Cloud Storage 버킷 생성
  • 서비스 계정에 Storage 권한 부여
  • 버킷 이름과 프로젝트 ID 확인
  • PHP 코드에 GCS 업로드 기능 추가
  • 수명 주기 규칙 설정 (자동 삭제)
  • 테스트 실행 및 확인

12. 참고 자료


작성일: 2024년 프로젝트: 5130 (voice_ai 시스템)