장면 변화 감지 가이드

대상

이 가이드는 Video Intelligence API를 빠르게 탐색하고 애플리케이션 개발을 시작하는 데 도움이 되도록 디자인되었습니다. 이 가이드를 따라하기 위해서는 프로그래밍 지식이 많지 않더라도 기본적인 프로그래밍에 익숙해야 합니다. 이 가이드를 마치면 참조 문서를 사용하여 기본적인 애플리케이션을 만들 수 있습니다.

이 가이드에서는 Python 코드를 사용하여 Video Intelligence API 애플리케이션을 설명합니다. 이 가이드의 목적은 Python 클라이언트 라이브러리를 설명하는 것이 아니라 Video Intelligence API를 호출하는 방법을 설명하는 것입니다. 자바 및 Node.js로 작성된 애플리케이션도 원리적으로 비슷합니다.

코드만 있는 예시 또는 다른 언어의 예시를 찾으려면 보조 자료인 안내 가이드를 참조하세요.

기본 요건

이 가이드에는 몇 가지 기본 요건이 있습니다.

장면 변화 감지를 사용하여 동영상에 주석 추가

이 가이드에서는 SHOT_CHANGE_DETECTION 요청을 사용하는 기본적인 Video API 애플리케이션에 대해 설명합니다. SHOT_CHANGE_DETECTION 요청은 주석 결과를 제공합니다.

  • 동영상 내에서 등장하는 모든 장면의 목록
  • 각 장면별로 장면의 시작 및 종료 시간 제공

우선 코드 전체를 보겠습니다. (간단한 설명을 위해 이 코드에서는 대부분의 주석이 삭제되어 있습니다. 코드를 진행함에 따라 더 자세한 주석이 제공됩니다.)

import argparse

from google.cloud import videointelligence

def analyze_shots(path):
    """ Detects camera shot changes. """
    video_client = videointelligence.VideoIntelligenceServiceClient()
    features = [videointelligence.Feature.SHOT_CHANGE_DETECTION]
    operation = video_client.annotate_video(
        request={"features": features, "input_uri": path}
    )
    print("\nProcessing video for shot change annotations:")

    result = operation.result(timeout=120)
    print("\nFinished processing.")

    for i, shot in enumerate(result.annotation_results[0].shot_annotations):
        start_time = (
            shot.start_time_offset.seconds + shot.start_time_offset.microseconds / 1e6
        )
        end_time = (
            shot.end_time_offset.seconds + shot.end_time_offset.microseconds / 1e6
        )
        print("\tShot {}: {} to {}".format(i, start_time, end_time))

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
    )
    parser.add_argument("path", help="GCS path for shot change detection.")
    args = parser.parse_args()

    analyze_shots(args.path)

이 간단한 애플리케이션은 다음과 같은 작업을 수행합니다.

  • 애플리케이션을 실행하는 데 필요한 라이브러리 가져오기
  • Cloud Storage URI에 저장된 동영상 파일을 인수로 사용해서 main() 함수에 전달합니다.
  • Video Intelligence API 서비스를 실행하는 데 필요한 사용자 인증 정보를 가져옵니다.
  • 동영상 서비스로 전송할 동영상 주석 요청을 만듭니다.
  • 요청을 전송하고 장기 실행 작업을 반환합니다.
  • 동영상이 처리될 때까지 장기 실행 작업을 반복 실행하고 사용 가능한 값을 반환합니다.
  • 서비스 응답을 파싱하고 응답을 사용자에게 표시합니다.

이 단계는 아래에서 자세히 살펴보겠습니다.

라이브러리 가져오기

import argparse

from google.cloud import videointelligence

argparse를 가져와 애플리케이션이 입력 파일 이름을 인수로 받을 수 있도록 합니다.

Cloud Video Intelligence API를 사용하기 위해서는 API 호출 디렉터리와 열거 상수를 저장하는 google.cloud.videointelligence 라이브러리도 가져와야 합니다.

애플리케이션 실행

parser = argparse.ArgumentParser(
    description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("path", help="GCS path for shot change detection.")
args = parser.parse_args()

analyze_shots(args.path)

여기에서는 동영상 파일 이름의 Google Cloud Storage URI에 대해 전달된 인수를 파싱하고 main() 함수로 전달합니다.

API 인증

Video Intelligence API 서비스와 통신하려면 우선 이전에 획득한 사용자 인증 정보를 사용하여 서비스를 인증해야 합니다. 애플리케이션 내에서 사용자 인증 정보를 얻는 가장 간단한 방법은 애플리케이션 기본 사용자 인증 정보(ADC)를 사용하는 것입니다. 기본적으로 ADC는 GOOGLE_APPLICATION_CREDENTIALS 환경 파일에서 사용자 인증 정보를 얻으려고 시도합니다. 환경 파일은 서비스 계정의 JSON 키 파일을 가리키도록 설정해야 합니다. 빠른 시작에서 ADC를 사용하려면 서비스 계정 및 환경을 설정한 상태여야 합니다. 자세한 내용은 서비스 계정 설정을 참조하세요.

요청 생성

video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.SHOT_CHANGE_DETECTION]
operation = video_client.annotate_video(
    request={"features": features, "input_uri": path}
)

이제 Video Intelligence API 서비스가 준비되었으므로 서비스에 대한 요청을 생성할 수 있습니다. Video Intelligence API에 대한 요청은 JSON 객체로 제공됩니다. 이러한 요청의 자세한 구조 정보는 Video Intelligence API 참조를 참조하세요.

이 코드 스니펫은 다음 작업을 수행합니다.

  1. annotate_video() 메서드에 대한 POST 요청을 위해 JSON을 생성합니다.
  2. 전달된 동영상 파일 이름의 Google Cloud Storage 위치를 요청에 삽입합니다.
  3. annotate 메서드가 SHOT_CHANGE_DETECTION을 수행해야 함을 나타냅니다.

장기 실행 작업 생성

Video Intelligence API에 대한 요청을 처음 실행하면 즉각적인 결과를 얻지 못합니다. 대신 응답의 name 필드에 저장된 작업 이름을 얻습니다. 나중에 이를 사용하여 결과를 확인할 수 있습니다.

작업의 이름(숫자 문자열)을 Video Intelligence API의 Operations Service operations 메서드에 전달하면 작업의 현재 상태가 반환됩니다. 샘플 응답은 아래와 같습니다.

{
   "response":{
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse"
   },
   "name":"us-west1.17159971042783089144",
   "metadata":{
      "annotationProgress":[
         {
            "inputUri":"/demomaker/gbikes_dinosaur.mp4",
            "updateTime":"2017-01-27T19:45:54.297807Z",
            "startTime":"2017-01-27T19:45:54.275023Z"
         }
      ],
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress"
   }
}

이제 response 필드에 @type 필드만 포함되어, 응답 유형을 나타냅니다. 결과를 실제로 볼 수 있게 되면 응답 필드에 해당 유형의 결과가 포함됩니다.

작업 확인

result = operation.result(timeout=120)
print("\nFinished processing.")

기존 작업에 대한 기존 작업 요청을 사용하여 주기적으로 해당 작업의 상태를 확인하는 while 루프를 만듭니다. 작업 상태가 done으로 표시되면 루프를 해제하고 응답을 파싱할 수 있습니다.

응답 파싱

for i, shot in enumerate(result.annotation_results[0].shot_annotations):
    start_time = (
        shot.start_time_offset.seconds + shot.start_time_offset.microseconds / 1e6
    )
    end_time = (
        shot.end_time_offset.seconds + shot.end_time_offset.microseconds / 1e6
    )
    print("\tShot {}: {} to {}".format(i, start_time, end_time))

작업이 완료된 다음에는 응답에 AnnotateVideoResponse가 포함됩니다. 이 응답은 요청으로 전송된 각 동영상에 대해 하나씩 annotationResults 목록으로 구성됩니다. 요청에 동영상을 하나만 전송했기 때문에 결과의 첫 번째 shotAnnotations를 사용합니다. 동영상의 모든 '세그먼트'를 살펴보세요.

애플리케이션 실행

애플리케이션을 실행하려면 단순히 여기에 동영상의 Cloud Storage URI를 전달합니다.

$ python shotchange.py gs://demomaker/gbikes_dinosaur.mp4
operationId=us-west1.12468772851081463748
Operation us-west1.12468772851081463748 started: 2017-01-30T01:53:45.981043Z
Processing video for shot change annotations:
Finished processing.
  Shot 0: 0.0 to 5.166666
  Shot 1: 5.233333 to 10.066666
  Shot 2: 10.1 to 28.133333
  Shot 3: 28.166666 to 42.766666

수고하셨습니다. Video Intelligence API를 사용하여 주석 작업을 수행했습니다!