Tải lên tham chiếu mới

Lưu ý: Content ID của YouTube dành cho các đối tác nội dung của YouTube và không phải nhà phát triển hoặc người dùng YouTube nào cũng có thể truy cập được. Nếu bạn không thấy YouTube Content ID API trong danh sách các dịch vụ trong Google API Console, hãy truy cập vào Trung tâm trợ giúp của YouTube để tìm hiểu thêm về Chương trình Đối tác YouTube.

Mã mẫu này minh hoạ cách tải reference lên bằng Content ID API của YouTube. Đ�� tải reference lên, trước tiên, bạn phải tạo asset rồi định cấu hình quyền sở hữu cũng như chính sách trùng khớp của tài sản. Ví dụ này trình bày tất cả các bước này.

Ví dụ này được trình bày dưới dạng một loạt các bước có liên quan cùng với các phần có liên quan của mã. Bạn có thể tìm thấy toàn bộ tập lệnh ở cuối trang này. Mã này được viết bằng Python. Ngoài ra còn có thư viện ứng dụng cho các ngôn ngữ lập trình phổ biến khác.

Tập lệnh mẫu không xử lý lỗi.

Yêu cầu

Trong bước này, chúng ta sẽ tích hợp việc uỷ quyền OAuth 2.0 vào tập lệnh. Điều này cho phép người dùng đang chạy tập lệnh cho phép tập lệnh thực hiện các yêu cầu API được phân bổ cho tài khoản của người dùng.

Tạo tệp client_secrets.json

API Content ID của YouTube yêu cầu tệp client_secrets.json chứa thông tin từ Bảng điều khiển API để thực hiện xác thực. Bạn cũng cần đăng ký ứng dụng của mình. Để xem giải thích đầy đủ hơn về cách hoạt động của tính năng xác thực, hãy xem hướng dẫn xác thực.

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

Thêm mã xác thực vào tập lệnh của bạn

Để bật tính năng xác thực và uỷ quyền người dùng, bạn cần thêm các câu lệnh import sau:

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

Tiếp theo, chúng ta sẽ tạo một đối tượng FLOW bằng mật khẩu ứng dụng khách được định cấu hình ở bước 2a. Nếu người dùng cho phép ứng dụng thay mặt người dùng gửi yêu cầu API, thì thông tin xác thực thu được sẽ được lưu trữ trong đối tượng Storage để sử dụng sau này. Người dùng sẽ phải uỷ quyền lại ứng dụng nếu thông tin đăng nhập hết hạn.

Thêm mã sau vào cuối hàm 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)

Tạo đối tượng httplib2 và đính kèm thông tin đăng nhập

Sau khi người dùng cho phép tập lệnh, chúng ta sẽ tạo một đối tượng httplib2.Http để xử lý các yêu cầu API và đính kèm thông tin xác thực uỷ quyền vào đối tượng đó.

Thêm câu lệnh nhập sau:

  import httplib2

Và thêm mã này vào cuối hàm main:

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

Yêu cầu dịch vụ

Sau khi uỷ quyền thành công, mã sẽ nhận được các dịch vụ cần thiết cho các thao tác mà mã sẽ thực hiện. Trước tiên, API này sẽ tạo một đối tượng service để cung cấp quyền truy cập vào tất cả dịch vụ API Content ID của YouTube. Sau đó, mã này sử dụng đối tượng service để lấy 4 dịch vụ dành riêng cho tài nguyên mà đối tượng này gọi.

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()

Tạo tài sản

Bước đầu tiên để tải reference lên là tạo asset. Trước tiên, chúng ta tạo một đối tượng metadata đơn giản chỉ đặt tiêu đề của tài sản. Sau đó, mã này sẽ thêm đối tượng đó vào asset_body, giúp xác định loại nội dung. Đổi lại, đối tượng asset_body được dùng làm dữ liệu đầu vào cho phương thức asset_service.insert(). Phương thức này sẽ tạo thành phần và trả về mã nhận dạng duy nhất của thành phần.

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

Cập nhật Quyền sở hữu

Sau khi tạo asset, tập lệnh sẽ định cấu hình ownership của thành phần. Ví dụ này cho biết rằng chủ sở hữu nội dung sở hữu 100% nội dung nhưng quyền sở hữu đó chỉ giới hạn ở Ba Lan (PL) và Vương quốc Anh (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)

Cập nhật chính sách trùng khớp của tài sản

Trước khi tạo tệp đối chiếu, đoạn mã này cũng phải định cấu hình chính sách trùng khớp của tài sản bằng cách cập nhật tài nguyên assetMatchPolicy có liên kết với tài sản đó. Chính sách trùng khớp của tài sản nêu rõ hành động mà YouTube sẽ thực hiện khi phát hiện thấy một video trên YouTube trùng khớp với bất kỳ tệp đối chiếu nào có liên kết với tài sản đó. Ví dụ này tạo một chính sách đơn giản để theo dõi mọi kết quả trùng khớp trên toàn thế giới dài hơn 10 giây.

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)

Tải tệp đối chiếu lên

Sau khi asset, ownershipassetMatchPolicy đã sẵn sàng, tập lệnh sẽ tải reference lên. Phương thức này sử dụng phương thức MediaFileUpload để có thể tận dụng quá trình tải lên tiếp nối. Hãy lưu ý rằng tham số reference_file chỉ định tên của tệp cục bộ sẽ được tải lên, và giá trị đó được chuyển đến tập lệnh bằng tuỳ chọn dòng lệnh 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)