新しい参照のアップロード

注: YouTube Content ID API は、YouTube コンテンツ パートナーによる使用を目的とした API であり、すべてのデベロッパーまたはすべての YouTube ユーザーがアクセスすることはできません。Google API Console に YouTube Content ID API がサービスとして表示されない場合は、YouTube ヘルプセンターで YouTube パートナー プログラムの詳細をご覧ください。

次のコードサンプルは、YouTube Content ID API を使用して reference をアップロードする方法を示しています。reference をアップロードするには、まず asset を作成し、アセットの所有権一致ポリシーを設定する必要があります。この例では、これらのステップをすべて順を追って説明します。

この例は、コードの該当箇所に関連するステップとして示されます。スクリプト全体は、このページの最後にあります。このコードは Python で書かれています。その他の一般的なプログラミング言語用のクライアント ライブラリもご利用いただけます。

このサンプル スクリプトでは、エラー処理を行っていません。.

要件

このステップでは、OAuth 2.0 認証をスクリプトに組み込みます。これにより、スクリプトを実行するユーザーはスクリプトを承認して、このユーザーのアカウントにる API リクエストを実行できます。

client_secrets.json ファイルを作成する

YouTube Content ID API で認証を行うには、API Console から取得した情報を含む client_secrets.json ファイルが必要です。また、アプリケーションを登録する必要もあります。認証の仕組みについて詳しくは、認証ガイドをご覧ください。

 {
  "web": {
    "client_id": "INSERT CLIENT ID HERE",
    "client_secret": "INSERT CLIENT SECRET HERE",
    "redirect_uris": [],
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://accounts.google.com/o/oauth2/token"
  }
}

スクリプトに認証コードを追加する

ユーザー認証と認可を有効にするには、次の import ステートメントを追加する必要があります。

from oauth2client.file import Storage
from oauth2client.client import flow_from_clientsecrets
from oauth2client.tools import run

次に、手順 2a で構成したクライアント シークレットを使用して、FLOW オブジェクトを作成します。ユーザーが、アプリケーションでユーザーの代わりに API リクエストを送信することを承認した場合、生成された認証情報は後で使用できるように Storage オブジェクトに保存されます。認証情報が無効になった場合はアプリケーションの再承認が必要になります。

main 関数の末尾に次のコードを追加します。

  # Set up a Flow object to be used if we need to authenticate.
  FLOW = flow_from_clientsecrets('client_secrets.json',
      scope='https://www.googleapis.com/auth/youtubepartner',
      message='error message')

  # The Storage object stores the credentials. If it doesn't exist, or if
  # the credentials are invalid or expired, run through the native client flow.
  storage = Storage('yt_partner_api.dat')
  credentials = storage.get()
  
  if (credentials is None or credentials.invalid or
      credentials.token_expiry <= datetime.now()):
    credentials = run(FLOW, storage)

httplib2 オブジェクトを作成して認証情報を関連付ける

ユーザーがスクリプトを承認したら、API リクエストを処理する httplib2.Http オブジェクトを作成し、そのオブジェクトに認証情報を添付します。

次の import ステートメントを追加します。

  import httplib2

main 関数の末尾に次のコードを追加します。

  # Create httplib2.Http object to handle HTTP requests and
  # attach auth credentials.
  http = httplib2.Http()
  http = credentials.authorize(http)

サービスを取得する

認証がs行われた後で、コードは操作に必要なサービスを取得します。まず、すべての YouTube Content ID API サービスにアクセスできるようにする service オブジェクトを作成します。次に、service オブジェクトを使用して、呼び出すリソース固有の 4 つのサービスを取得します。

from apiclient.discovery import build

# ...

service = build("youtubePartner", "v1", http=http, static_discovery=False)
# ...
asset_service = service.assets()
# ...
ownership_service = service.ownership()
# ...
match_policy_service = service.assetMatchPolicy()
# ...
reference_service = service.references()

アセットを作成する

reference をアップロードする最初のステップは、asset の作成です。まず、アセットのタイトルのみを設定するシンプルな metadata オブジェクトを作成します。次に、そのオブジェクトを asset_body に追加します。これにより、アセットのタイプも識別されます。次に、asset_body オブジェクトは asset_service.insert() メソッドへの入力として使用されます。このメソッドがアセットを作成し、一意の ID を返します。

def _create_asset(service, title, metadata_type):
  metadata = {'title': title}
  asset_body = {'metadata': metadata, 'type': metadata_type}
  # Retrieve asset service.
  asset_service = service.assets()

  # Create and execute insert request.
  request = asset_service.insert(body=asset_body)
  response = request.execute()
  logger.info('Asset has been created.\n%s', response)
  asset_id = response['id']
  return asset_id

所有権を更新

asset を作成したら、スクリプトはアセットの ownership を設定します。この例では、コンテンツ所有者がアセットの 100% を所有しているが、その所有権はポーランド(PL)と英国(GB)に限定されていることを示しています。

def _create_asset_ownership(service, asset_id, owner_name):
  ownership = {
      'owner': owner_name,
      'ratio' : 100,
      'type': 'include',
      'territories': ['PL', 'GB']}
  ownership_body = {'general': [ownership]}
  ownership_service = service.ownership()

  request = ownership_service.update(assetId=asset_id, body=ownership_body)
  response = request.execute()
  logger.info('Asset ownership has been created.\n%s', response)

アセットの一致ポリシーを更新する

参照を作成する前に、アセットに関連付けられた assetMatchPolicy リソースを更新して、アセットの一致ポリシーを構成する必要もあります。アセットの一致ポリシーは、YouTube 上の動画がそのアセットに関連付けられたリファレンスと一致することがわかった場合、YouTube が取るアクションを説明するものです。この例では、世界中の一致を 10 秒以上追跡する単純なポリシーを作成します。

def _create_match_policy(service, asset_id):
  match_policy_service = service.assetMatchPolicy()
  everywhere_policy_condition = {
      'requiredTerritories': {
          'type': 'exclude', 'territories': []},
      'requiredReferenceDuration': [{'low': 10}],
      'contentMatchType': 'video'}
  track_everywhere_rule = {
      'action': 'track',
      'condition': everywhere_policy_condition}
  request = match_policy_service.update(
      assetId=asset_id,
      body={
        'name': 'Track Everywhere 10s.',
        'description': 'Track Everywhere matches longer than 10s.',
        'rules': [track_everywhere_rule]})
  response = request.execute()
  logger.info('Asset match policy has been created.\n%s', response)

参照をアップロードする

assetownershipassetMatchPolicy が作成されたら、スクリプトは reference をアップロードします。再開可能なアップロードを利用するために、MediaFileUpload メソッドを使用します。reference_file パラメータでアップロードするローカル ファイルの名前を指定し、その値を reference_file コマンドライン オプションを使用してスクリプトに渡します。

def _create_reference(service, asset_id, reference_file):
  reference_service = service.reference()
  media = MediaFileUpload(reference_file, resumable=True)
  request = reference_service.insert(
      body={'assetId': asset_id, 'contentType': 'video'},
      media_body=media)
  status, response = request.next_chunk()
  while response is None:
    status, response = request.next_chunk()
    if status:
      logger.info("Uploaded %d%%.", int(status.progress() * 100))
  logger.info('Reference has been created.\n%s', response)
    

Full code sample

The complete working sample asset_reference_upload_example.py is listed below:

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2012 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Simple command-line sample for Youtube partner API.

Command-line application that creates asset, asset ownership, match policy
and reference.

Usage:
  $ python asset_reference_upload_example.py --reference_file=REFERENCE_FILE \
      --asset_title=ASSET_TITLE --owner=OWNER

You can also get help on all the command-line flags the program understands
by running:

  $ python asset_reference_upload_example.py --help
"""

__author__ = '[email protected] (Mateusz Zięba)'

import httplib2
import logging
import sys
import optparse
import os

from apiclient.discovery import build
from apiclient.errors import HttpError
from apiclient.http import MediaFileUpload
from oauth2client.file import Storage
from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import flow_from_clientsecrets
from oauth2client.tools import run

# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
# the OAuth 2.0 information for this application, including its client_id and
# client_secret. You can acquire an OAuth 2.0 client ID and client secret from
# the Google API Console at
# https://console.cloud.google.com/.
# See the "Registering your application" instructions for an explanation
# of how to find these values:
# https://developers.google.com/youtube/partner/guides/registering_an_application
CLIENT_SECRETS = 'client_secrets.json'

# Helpful message to display if the CLIENT_SECRETS file is missing.
MISSING_CLIENT_SECRETS_MESSAGE = """
WARNING: Please configure OAuth 2.0

To make this sample run you need to populate the client_secrets.json
file found at:

%s

with information from the API Console
<https://console.cloud.google.com/>.

""" % os.path.join(os.path.dirname(__file__), CLIENT_SECRETS)

# Set up a Flow object to be used if we need to authenticate.
FLOW = flow_from_clientsecrets(CLIENT_SECRETS,
           scope='https://www.googleapis.com/auth/youtubepartner',
           message=MISSING_CLIENT_SECRETS_MESSAGE)

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler())


def _create_asset(service, title, metadata_type):
  metadata = {'title': title}
  asset_body = {'metadata': metadata, 'type': metadata_type}
  # Retrieve asset service.
  asset_service = service.assets()

  # Create and execute insert request.
  request = asset_service.insert(body=asset_body)
  response = request.execute()
  logger.info('Asset has been created.\n%s', response)
  asset_id = response['id']
  return asset_id


def _create_asset_ownership(service, asset_id, owner_name):
  ownership = {
      'owner': owner_name,
      'ratio' : 100,
      'type': 'include',
      'territories': ['PL', 'GB']}
  ownership_body = {'general': [ownership]}
  ownership_service = service.ownership()

  request = ownership_service.update(assetId=asset_id, body=ownership_body)
  response = request.execute()
  logger.info('Asset ownership has been created.\n%s', response)


def _create_match_policy(service, asset_id):
  match_policy_service = service.assetMatchPolicy()
  everywhere_policy_condition = {
      'requiredTerritories': {
          'type': 'exclude', 'territories': []},
      'requiredReferenceDuration': [{'low': 10}],
      'contentMatchType': 'video'}
  track_everywhere_rule = {
      'action': 'track',
      'condition': everywhere_policy_condition}
  request = match_policy_service.update(
      assetId=asset_id,
      body={
        'name': 'Track Everywhere 10s.',
        'description': 'Track Everywhere matches longer than 10s.',
        'rules': [track_everywhere_rule]})
  response = request.execute()
  logger.info('Asset match policy has been created.\n%s', response)


def _create_reference(service, asset_id, reference_file):
  reference_service = service.references()
  media = MediaFileUpload(reference_file, resumable=True)
  request = reference_service.insert(
      body={'assetId': asset_id, 'contentType': 'video'},
      media_body=media)
  status, response = request.next_chunk()
  while response is None:
    status, response = request.next_chunk()
    if status:
      logger.info("Uploaded %d%%.", int(status.progress() * 100))
  logger.info('Reference has been created.\n%s', response)


def _parse_options():
  parser = optparse.OptionParser(
      description='Creates asset, asset ownership, match policy and reference.')
  parser.add_option('--version',
                    default='v1',
                    type=str, help='API version.')
  parser.add_option('--reference_file', type=str,
                    help='File containing reference to be uploaded. Required')
  parser.add_option('--asset_title',
                    type=str, help='Asset title. Required')
  parser.add_option('--owner',
                    type=str, help='Content owner name. Required')
  (options, args) = parser.parse_args()

  if not options.reference_file:
    parser.error("--reference_file is required")
  if not options.asset_title:
    parser.error("--asset_title is required")
  if not options.owner:
    parser.error("--owner is required")
  return options


def main(argv):
  options = _parse_options()
  # If the Credentials don't exist or are invalid run through the native client
  # flow. The Storage object ensures that if successful the good
  # Credentials are written back to a file.
  storage = Storage('yt_partner_api.dat')
  credentials = storage.get()
  if credentials is None or credentials.invalid:
    credentials = run(FLOW, storage)

  # Create an httplib2.Http object to handle our HTTP requests and authorize it
  # with our good Credentials.
  http = httplib2.Http()
  http = credentials.authorize(http)

  service = build("youtubePartner", options.version, http=http, static_discovery=False)

  try:
    asset_id = _create_asset(service, options.asset_title, 'web')
    _create_asset_ownership(service, asset_id, options.owner)
    _create_match_policy(service, asset_id)
    _create_reference(service, asset_id, options.reference_file)

  except AccessTokenRefreshError:
    logger.info("The credentials have been revoked or expired, please re-run"
      " the application to re-authorize")

if __name__ == '__main__':
  main(sys.argv)