鏡頭轉換偵測教學課程

目標對象

本教學課程的設計在於讓您透過 Video Intelligence API 快速開始探索並開發應用程式。本教學課程的設計對象是熟悉基本程式設計的使用者,但即便您對程式設計只有粗淺的認識,也應能跟得上課程。完成本教學課程後,您應能使用參考資料說明文件建立自己的基本應用程式。

本教學課程採用 Python 程式碼逐步操作 Video Intelligence API 應用程式。本文目的並非提供 Python 用戶端程式庫的相關說明,而是解釋如何呼叫 Video Intelligence API。以 Java 和 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,以允許應用程式接受輸入檔案名稱做為引數。

為了使用 Video Intelligence API,我們還會匯入 google.cloud.videointelligence 程式庫,其中含有 API 呼叫和列舉常數的目錄。

執行應用程式

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 服務準備就緒後,即可建立要對這項服務發出的要求。系統會以 JSON 物件的形式將要求提供給 Video Intelligence API。如需這類要求的特定結構完整資訊,請參閱 Video Intelligence API 參考資料

這個程式碼片段會執行下列工作:

  1. 建立 POST 要求的 JSON 以傳送至 annotate_video() 方法。
  2. 將傳遞的影片檔案名稱所在的 Google Cloud Storage 位置插入要求中。
  3. 指出 annotate 方法應執行 SHOT_CHANGE_DETECTION

建構長時間執行的作業

首次對 Video Intelligence API 執行要求時,不會立即得到結果,而是會得到回應的 operation name,儲存在回應的 name 欄位中,稍後我們可以使用這個作業名稱來檢查結果。

將作業名稱 (一個數字字串) 傳遞至 Video Intelligence API 的「作業服務」operations 方法後,系統會傳回這項作業的當前狀態。回應範例如下所示:

{
   "response":{
      "@type":"type.googleapis.com/google.cloud.videointelligence.v1.AnnotateVideoResponse"
   },
   "name":"us-west1.17159971042783089144",
   "metadata":{
      "annotationProgress":[
         {
            "inputUri":"/video/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 清單,每個 annotationResults 代表要求中傳送的一部影片。因為我們在要求中只傳送了一部影片,所以會採取結果的第一個 shotAnnotations。接下來將逐步檢視影片的所有「片段」。

執行應用程式

如要執行我們的應用程式,只要將影片的 Cloud Storage URI 傳送給應用程式即可:

$ python shotchange.py gs://cloud-samples-data/video/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 完成了註解工作!