העלאת קובץ עזר חדש

הערה: ממשק YouTube Content ID API מיועד לשימוש של שותפי תוכן של YouTube, והוא אינו נגיש לכל המפתחים או לכל משתמשי YouTube. אם אינכם רואים את YouTube Content ID API כאחד מהשירותים המפורטים בGoogle API Console, מומלץ לעיין במרכז העזרה של YouTube כדי לקבל מידע נוסף על תוכנית השותפים של YouTube.

דוגמת הקוד הזו מדגימה איך להעלות reference באמצעות YouTube Content ID API. כדי להעלות reference, צריך קודם ליצור asset ולהגדיר את הבעלות ואת מדיניות ההתאמה של הנכס. בדוגמה הזו מפורטים כל השלבים.

דוגמה זו מוצגת כסדרת השלבים שקשורה לצד הקטעים הרלוונטיים של הקוד. בסוף הדף הזה אפשר למצוא את הסקריפט המלא. הקוד כתוב ב-Python. זמינות גם ספריות לקוח לשפות תכנות פופולריות אחרות.

הסקריפט לדוגמה לא מטפל בשגיאות.

דרישות

בשלב הזה, נשלב בסקריפט הרשאת OAuth 2.0. כך המשתמש שמריץ את הסקריפט יכול לתת לסקריפט הרשאה לבצע בקשות API שמשויכות לחשבון המשתמש.

יצירת קובץ client_secrets.json

כדי לבצע אימות ב-YouTube Content ID API, נדרש קובץ client_secrets.json, שמכיל מידע מ-API Console. בנוסף, צריך לרשום את האפליקציה. להסבר מקיף יותר על אופן הפעולה של אימות, ניתן לעיין במדריך האימות.

 {
  "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

בשלב הבא ניצור אובייקט FLOW באמצעות סודות הלקוח שהוגדרו בשלב 2א'. אם המשתמש מאשר לאפליקציה שלנו לשלוח בקשות 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 וצירוף פרטי כניסה

אחרי שהמשתמש יאשר את הסקריפט שלנו, אנחנו יוצרים אובייקט httplib2.Http שמטפל בבקשות API, ומצרפים את פרטי הכניסה להרשאה לאובייקט הזה.

מוסיפים את הצהרת הייבוא הבאה:

  import httplib2

מוסיפים את הקוד הבא בסוף הפונקציה main:

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

קבלת שירותים

לאחר שהאימות בוצע בהצלחה, הקוד מקבל את השירותים הנחוצים לפעולות שהוא יבצע. תחילה היא יוצרת אובייקט service שמספק גישה לכל שירותי YouTube Content ID API. לאחר מכן, הקוד משתמש באובייקט service כדי לקבל את ארבעת השירותים הספציפיים למשאבים שהוא קורא.

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(). השיטה הזו יוצרת את הנכס ומחזירה את המזהה הייחודי שלו.

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)

העלאת קובץ העזר

לאחר ההוספה של asset, ownership ו-assetMatchPolicy, הסקריפט מעלה 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__ = 'mateuszz+pub@google.com (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)