การอัปโหลดข้อมูลอ้างอิงใหม่

หมายเหตุ: API สำหรับ Content ID ของ YouTube มีขึ้นเพื่อให้พาร์ทเนอร์เนื้อหาของ YouTube ใช้งาน และไม่สามารถเข้าถึงได้โดยนักพัฒนาแอปบางรายหรือผู้ใช้ YouTube บางราย หากคุณไม่เห็น API สำหรับ Content ID ของ YouTube เป็นหนึ่งในบริการที่แสดงอยู่ในคอนโซล Google API โปรดดูศูนย์ช่วยเหลือของ YouTube เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับโปรแกรมพาร์ทเนอร์ YouTube

โค้ดตัวอย่างนี้จะแสดงวิธีอัปโหลด reference โดยใช้ API สำหรับ Content ID ของ YouTube หากต้องการอัปโหลด reference คุณต้องสร้าง asset และกำหนดค่าการเป็นเจ้าของและนโยบายการจับคู่ของเนื้อหาก่อน ตัวอย่างนี้จะอธิบายขั้นตอนเหล่านี้ทั้งหมด

ตัวอย่างนี้จะแสดงเป็นชุดขั้นตอนที่เกี่ยวข้องพร้อมกับส่วนที่เกี่ยวข้องของโค้ด คุณดูสคริปต์ทั้งหมดได้ที่ส่วนท้ายของหน้านี้ โค้ดเขียนเป็นภาษา Python นอกจากนี้ยังมีไลบรารีของไคลเอ็นต์สำหรับภาษาโปรแกรมยอดนิยมอื่นๆ อีกด้วย

สคริปต์ตัวอย่างไม่ได้จัดการข้อผิดพลาดใดๆ

ข้อกำหนด

ในขั้นตอนนี้ เราจะรวมการให้สิทธิ์ OAuth 2.0 เข้ากับสคริปต์ วิธีนี้ช่วยให้ผู้ใช้ที่เรียกใช้สคริปต์สามารถให้สิทธิ์สคริปต์ในการส่งคำขอ API ที่มาจากบัญชีผู้ใช้ได้

สร้างไฟล์ client_secrets.json

API สำหรับ Content ID ของ YouTube ต้องใช้ไฟล์ client_secrets.json ซึ่งมีข้อมูลจากคอนโซล API เพื่อดำเนินการตรวจสอบสิทธิ์ คุณจะต้องลงทะเบียนแอปพลิเคชันด้วย หากต้องการดูคำอธิบายเพิ่มเติมเกี่ยวกับวิธีการทำงานของการตรวจสอบสิทธิ์ โปรดอ่านคู่มือการตรวจสอบสิทธิ์

 {
  "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 โดยใช้รหัสลับไคลเอ็นต์ที่กำหนดค่าไว้ในขั้นตอนที่ 2a หากผู้ใช้อนุญาตให้แอปพลิเคชันของเราส่งคำขอ 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 ที่ให้สิทธิ์เข้าถึงบริการ API สำหรับ Content ID ของ YouTube ทั้งหมดก่อน จากนั้นโค้ดจะใช้ออบเจ็กต์ 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() วิธีนี้จะสร้างเนื้อหาและแสดงผลรหัสที่ไม่ซ้ำกัน

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__ = '[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)