동영상에서 유해성 콘텐츠 감지

유해성 콘텐츠 감지는 동영상에서 성인용 콘텐츠를 감지합니다. 성인용 콘텐츠는 일반적으로 18세 미만의 사용자에게 부적절하며, 과도한 노출, 성행위, 음란물 등을 포함합니다. 만화 또는 애니메이션에서도 이러한 콘텐츠가 식별됩니다.

응답에는 VERY_UNLIKELY부터 VERY_LIKELY까지 버킷화된 가능성 값이 포함됩니다.

유해성 콘텐츠 감지는 동영상을 평가할 때 프레임 단위로 평가하며, 시각적 콘텐츠만 고려합니다. 동영상의 오디오 구성요소는 유해성 콘텐츠 수준을 평가하는 데 사용되지 않습니다.

Cloud Storage에 있는 파일에 대해 유해성 콘텐츠 감지 기능의 동영상 분석을 수행하는 예시는 다음과 같습니다.

REST

동영상 주석 요청 전송

다음은 videos:annotate 메서드에 POST 요청을 보내는 방법을 보여줍니다. 이 예시에서는 Google Cloud CLI를 사용하여 액세스 토큰을 만듭니다. gcloud CLI 설치에 대한 안내는 Video Intelligence API 빠른 시작을 참조하세요.

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • INPUT_URI: 파일 이름을 포함하여 주석을 추가하고자 하는 파일을 포함한 Cloud Storage 버킷입니다. gs://로 시작해야 합니다.
    예를 들면 "inputUri": "gs://cloud-videointelligence-demo/assistant.mp4",입니다.
  • PROJECT_NUMBER: Google Cloud 프로젝트의 숫자 식별자

HTTP 메서드 및 URL:

POST https://videointelligence.googleapis.com/v1/videos:annotate

JSON 요청 본문:

{
  "inputUri": "INPUT_URI",
  "features": ["EXPLICIT_CONTENT_DETECTION"]
}

요청을 보내려면 다음 옵션 중 하나를 펼칩니다.

다음과 비슷한 JSON 응답이 표시됩니다.

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID"
}

응답이 성공하면 Video Intelligence API가 작업의 name을 반환합니다. 위 내용은 이러한 응답의 예시입니다. 각 항목의 의미는 다음과 같습니다.

  • PROJECT_NUMBER: 프로젝트 수입니다.
  • LOCATION_ID: 주석이 있어야 할 클라우드 리전입니다. 지원되는 클라우드 리전은 us-east1, us-west1, europe-west1, asia-east1입니다. 리전을 지정하지 않으면 동영상 파일 위치를 기준으로 리전이 결정됩니다.
  • OPERATION_ID: 작업을 시작할 때 요청으로 생성되고 응답으로 제공된 장기 실행 작업의 ID로 예를 들면 12345...입니다.

주석 결과 가져오기

작업 결과를 검색하려면 다음 예시에 표시된 것처럼 videos:annotate 호출로부터 반환된 작업 이름을 사용하여 GET 요청을 수행합니다.

요청 데이터를 사용하기 전에 다음을 바꿉니다.

  • OPERATION_NAME: Video Intelligence API로 반환되는 작업의 이름입니다. 작업 이름은 projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID 형식입니다.
  • PROJECT_NUMBER: Google Cloud 프로젝트의 숫자 식별자

HTTP 메서드 및 URL:

GET https://videointelligence.googleapis.com/v1/OPERATION_NAME

요청을 보내려면 다음 옵션 중 하나를 펼칩니다.

다음과 비슷한 JSON 응답이 표시됩니다.

{
  "name": "projects/PROJECT_NUMBER/locations/LOCATION_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoProgress",
    "annotationProgress": [
     {
      "inputUri": "/demomaker/gbikes_dinosaur.mp4",
      "progressPercent": 100,
      "startTime": "2020-03-26T00:16:35.112404Z",
      "updateTime": "2020-03-26T00:16:55.937889Z"
     }
    ]
   },
   "done": true,
   "response": {
    "@type": "type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse",
    "annotationResults": [
     {
      "inputUri": "/demomaker/gbikes_dinosaur.mp4",
      "explicitAnnotation": {
       "frames": [
        {
         "timeOffset": "0.056149s",
         "pornographyLikelihood": "VERY_UNLIKELY"
        },
        {
         "timeOffset": "1.166841s",
         "pornographyLikelihood": "VERY_UNLIKELY"
        },
            ...
        {
         "timeOffset": "41.678209s",
         "pornographyLikelihood": "VERY_UNLIKELY"
        },
        {
         "timeOffset": "42.596413s",
         "pornographyLikelihood": "VERY_UNLIKELY"
        }
       ]
      }
     }
    ]
   }
  }
장면 감지 주석은 shotAnnotations 목록으로 반환됩니다. 참고: done 필드는 값이 True일 경우에만 반환됩니다. 작업이 완료되지 않은 경우에는 응답에 이 필드가 포함되지 않습니다.

주석 결과 다운로드

소스에서 대상 버킷으로 주석을 복사합니다(파일 및 객체 복사 참조).

gcloud storage cp gcs_uri gs://my-bucket

참고: 사용자가 출력 gcs uri를 제공하면 주석이 해당 gcs uri에 저장됩니다.

Go


func explicitContentURI(w io.Writer, file string) error {
	ctx := context.Background()
	client, err := video.NewClient(ctx)
	if err != nil {
		return err
	}
	defer client.Close()

	op, err := client.AnnotateVideo(ctx, &videopb.AnnotateVideoRequest{
		Features: []videopb.Feature{
			videopb.Feature_EXPLICIT_CONTENT_DETECTION,
		},
		InputUri: file,
	})
	if err != nil {
		return err
	}
	resp, err := op.Wait(ctx)
	if err != nil {
		return err
	}

	// A single video was processed. Get the first result.
	result := resp.AnnotationResults[0].ExplicitAnnotation

	for _, frame := range result.Frames {
		offset, _ := ptypes.Duration(frame.TimeOffset)
		fmt.Fprintf(w, "%s - %s\n", offset, frame.PornographyLikelihood.String())
	}

	return nil
}

Java

Video Intelligence에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

// Instantiate a com.google.cloud.videointelligence.v1.VideoIntelligenceServiceClient
try (VideoIntelligenceServiceClient client = VideoIntelligenceServiceClient.create()) {
  // Create an operation that will contain the response when the operation completes.
  AnnotateVideoRequest request =
      AnnotateVideoRequest.newBuilder()
          .setInputUri(gcsUri)
          .addFeatures(Feature.EXPLICIT_CONTENT_DETECTION)
          .build();

  OperationFuture<AnnotateVideoResponse, AnnotateVideoProgress> response =
      client.annotateVideoAsync(request);

  System.out.println("Waiting for operation to complete...");
  // Print detected annotations and their positions in the analyzed video.
  for (VideoAnnotationResults result : response.get().getAnnotationResultsList()) {
    for (ExplicitContentFrame frame : result.getExplicitAnnotation().getFramesList()) {
      double frameTime =
          frame.getTimeOffset().getSeconds() + frame.getTimeOffset().getNanos() / 1e9;
      System.out.printf("Location: %.3fs\n", frameTime);
      System.out.println("Adult: " + frame.getPornographyLikelihood());
    }
  }

Node.js

Video Intelligence에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

// Imports the Google Cloud Video Intelligence library
const video = require('@google-cloud/video-intelligence').v1;

// Creates a client
const client = new video.VideoIntelligenceServiceClient();

/**
 * TODO(developer): Uncomment the following line before running the sample.
 */
// const gcsUri = 'GCS URI of video to analyze, e.g. gs://my-bucket/my-video.mp4';

const request = {
  inputUri: gcsUri,
  features: ['EXPLICIT_CONTENT_DETECTION'],
};

// Human-readable likelihoods
const likelihoods = [
  'UNKNOWN',
  'VERY_UNLIKELY',
  'UNLIKELY',
  'POSSIBLE',
  'LIKELY',
  'VERY_LIKELY',
];

// Detects unsafe content
const [operation] = await client.annotateVideo(request);
console.log('Waiting for operation to complete...');
const [operationResult] = await operation.promise();
// Gets unsafe content
const explicitContentResults =
  operationResult.annotationResults[0].explicitAnnotation;
console.log('Explicit annotation results:');
explicitContentResults.frames.forEach(result => {
  if (result.timeOffset === undefined) {
    result.timeOffset = {};
  }
  if (result.timeOffset.seconds === undefined) {
    result.timeOffset.seconds = 0;
  }
  if (result.timeOffset.nanos === undefined) {
    result.timeOffset.nanos = 0;
  }
  console.log(
    `\tTime: ${result.timeOffset.seconds}` +
      `.${(result.timeOffset.nanos / 1e6).toFixed(0)}s`
  );
  console.log(
    `\t\tPornography likelihood: ${likelihoods[result.pornographyLikelihood]}`
  );
});

Python

Python용 Cloud Video Intelligence API 클라이언트 라이브러리 설치 및 사용에 대한 자세한 내용은 Cloud Video Intelligence API 클라이언트 라이브러리를 참조하세요.
"""Detects explicit content from the GCS path to a video."""
video_client = videointelligence.VideoIntelligenceServiceClient()
features = [videointelligence.Feature.EXPLICIT_CONTENT_DETECTION]

operation = video_client.annotate_video(
    request={"features": features, "input_uri": path}
)
print("\nProcessing video for explicit content annotations:")

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

# Retrieve first result because a single video was processed
for frame in result.annotation_results[0].explicit_annotation.frames:
    likelihood = videointelligence.Likelihood(frame.pornography_likelihood)
    frame_time = frame.time_offset.seconds + frame.time_offset.microseconds / 1e6
    print("Time: {}s".format(frame_time))
    print("\tpornography: {}".format(likelihood.name))

추가 언어

C#: 클라이언트 라이브러리 페이지의 C# 설정 안내를 따른 다음 .NET용 Video Intelligence 참고 문서를 참조하세요.

PHP: 클라이언트 라이브러리 페이지의 PHP 설정 안내를 따른 다음 PHP용 Video Intelligence 참고 문서를 참조하세요.

Ruby: 클라이언트 라이브러리 페이지의 Ruby 설정 안내를 따른 다음 Ruby용 Video Intelligence 참고 문서를 참조하세요.