Note: The YouTube Content ID API is intended for use by YouTube content partners and is not accessible to all developers or to all YouTube users. If you do not see the YouTube Content ID API as one of the services listed in the Google API Console, see the YouTube Help Center to learn more about the YouTube Partner Program.
This guide explains how YouTube content partners can migrate from XML content feeds to the YouTube Content ID API for ingesting content into YouTube's rights management system.
Overview
To take advantage of YouTube's Content ID rights management system, you need to provide YouTube with metadata, ownership information, policy settings, and reference material for your assets.
YouTube offers a variety of options for delivering your asset data. Partners who regularly deliver a lot of content often use a batch upload method, specifying their asset information using either the YouTube DDEX feed or a YouTube-provided spreadsheet template. Alternatively, the YouTube Content ID API provides finer-grained control over the upload process.
Using the API, you create assets and other resources one by one, in contrast to the batch processing of XML feeds and spreadsheets. The individual approach of the API can result in faster and more reliable uploads. You manage the upload process in a transactional manner, monitoring the success of individual actions and reacting immediately to any issues that arise. You can update your content management system with YouTube-generated IDs as they become available, rather than using a post-processing batch job.
This document describes how to use the YouTube Content ID API to define your assets in the YouTube rights management system. It assumes that you are currently defining your assets using the YouTube DDEX feed, and explains how to recreate the functionality of the XML content feed using the API. More specifically, it uses a sample XML content feed and identifies the API commands that achieve the same effect, using the Python client library.
Ways to deliver asset data to YouTube
The end result of using the XML content feed or the Content ID API is the same: you create (or update) YouTube rights management resources in your partner account. In some cases, you also create (or update) YouTube videos.
The XML content feed and the API approach the task differently. With the XML content feed, you create a single file that contains all of the information about the resources and the relationships between them. YouTube uses the feed as a blueprint to create the actual resources during the batch upload process. Using the API, you create resources one by one rather than in a batch. You can monitor the progress and success of each individual resource and API call.
When you create resources directly using API methods, you have to explicitly perform certain actions that the YouTube batch upload process handles behind the scenes. Most notably, you need to upload your media files and respond to issues (by retrying actions or reporting errors). You also need to perform actions in the correct order; for example, you can't claim a video until after you've created the video.
Each of the root-level elements in the YouTube XML content feed format corresponds to a resource (or resource property) that you create using the YouTube APIs.
XML elements and corresponding API resources | |
---|---|
<asset> |
asset |
<file> |
videos.fileDetails (from the YouTube Data API) orthumbnail (from the YouTube Data API) orreference |
<ownership> |
ownership |
<rights_admin> |
assetMatchPolicy (for match policies)claims.policy (for usage policies) |
<rights_policy> |
policy |
<video> |
videos (from the YouTube Data API) |
<video_breaks> |
videoAdvertisingOption.adbreaks[ ] |
<ad_policy> |
videoAdvertisingOption |
<claim> |
claim |
<playlist> |
playlist (from the YouTube Data API) |
<relationship> |
Various |
Note: The YouTube Content ID API does not currently support caption files, trailers, or album artwork files.
The treatment of <relationship>
elements nicely illustrates the difference between the XML feed and the API.
-
An XML
<relationship>
element states that a relationship exists between the<item>
and<related_item>
elements, but it is not explicit about the nature of that relationship. The YouTube upload process infers the proper relationship from the types of the items. For example, a relationship between an asset and a video indicates that YouTube should use the video file as a reference for the asset, while a relationship between an ad policy and a video sets the policy for the video. -
Using the YouTube Content ID API, you use specific API resources that explicitly set the proper relationship. To use a video as a reference for an asset, you create a
reference
resource. To set the ad policy for a video, you create avideoAdvertisingOptions
resource. The asset must exist before you can set its properties.
Upload asset data via a script
To upload asset data using the APIs, you need to write a script that can send API requests, upload files, and create YouTube rights management resources. This section provides a tutorial for writing the script.
The major steps are:
- Create a basic script that uses YouTube APIs.
- Add code that uploads media files.
- Add code that creates rights management resources.
- Operationalize your script to work with your content delivery system.
A code sample is provided at the end of the document (excluding step 4). Though the code is written in Python, client libraries for other popular programming languages are also available.
Step 1: Make API calls
The Sending a First Request tutorial explains how to write a basic script that sends YouTube Content API requests. The sample script from that tutorial authenticates the user, authorizes the use of API requests, and constructs resources for interacting with the YouTube Content ID API.
That script serves as the foundation of the script used in this example. However, as noted above, this example explains how to create and claim YouTube videos, and you need to use the YouTube Data API to upload YouTube videos. To enable the script from the tutorial to also access the YouTube Data API, make these two additions:
-
Authorize access to the upload functionality in the YouTube Data API by adding its URI to the
scope
parameter in theflow_from_clientsecrets
call (from step 2 in the tutorial).FLOW = flow_from_clientsecrets( 'client_secrets.json ', scope='https://www.googleapis.com/auth/youtubepartner https://www.googleapis.com/auth/youtube.upload', message= 'error message')
-
Construct a resource for interacting with the YouTube Data API (from Step 3 of the tutorial).
service = build("youtubePartner", "v1", http=http, static_discovery=False) dataApi = build("youtube", "v3", http=http)
Step 2: Upload video files
The next step is to add a function that uploads video files. For maximum reliability, you'll use a resumable upload protocol. This protocol lets you resume an upload operation after a network interruption or other transmission failure, saving time and bandwidth in the event of network failures.
The Uploading a Video guide in the YouTube Data API documentation provides a sample upload script, upload_video.py
. Update the basic script from step 1 by adding the resumable_upload
function from upload_video.py
. You also need to add the import
statements and variable definitions that the function depends on.
Step 3: Create YouTube rights management resources
With the basic framework in place, you're ready to add the code that creates YouTube assets, videos, and associated resources.
The order in which you create resources is important. For example, you need to create an asset and upload a video before you can claim the video for the asset.
The general order of operations for movie, TV, music video, and web video assets is:
- Create the asset resource (
assets.insert
) - Update the asset's ownership (
ownership.update
) and match policy (assetMatchPolicy.update
) - Create the video resource (
videos.insert
), setting its metadata and uploading the media file - Update the video's ad policy (
videoAdvertisingOptions.update
) - Claim the video on behalf of the asset (
claims.insert
) - Create a reference for the asset using the claimed video (
references.insert
)
The general order of operations for sound recordings or reference-only assets is the same, omitting steps 3 through 5:
- Create the asset resource (
assets.insert
) - Update the asset's ownership (
ownership.update
) and match policy (assetMatchPolicy.update
) - Create a reference for the asset (
references.insert
) and upload the media file
The rest of this section provides details about each of these steps, comparing the sample XML feed to the corresponding code in the sample script.
Step 3.1: Create an asset
The first call is to the API's assets.insert
method. It corresponds to this portion of the XML feed:
<asset type="web"> <title>Broadcast Yourself!: Using the YouTube Live APIs to stream to the world</title> <description>See a preview of the Google I/O presentation.</description> </asset>
To specify these values in an asset
resource, you would set the following property values:
{ "type": "web", "metadata": { "title": "Broadcast Yourself!: Using the YouTube Live APIs to stream to the world", "description": "See a preview of the Google I/O presentation." } }
Extract the id
property from the resource that the API returns. This property identifies the asset ID that YouTube assigned to uniquely identify the asset. This value is required in several ensuing API calls and is identified as the assetId
later in this documentation.
Step 3.2: Update the asset's ownership
Once you've created an asset, you set your ownership of the asset using the API's ownership.update
method. This step corresponds to this portion of the XML feed:
<ownership/> <relationship> <item path="/feed/asset[1]"/> <related_item path="/feed/ownership[1]"/> </relationship>
The XML uses an empty <ownership>
tag, which indicates that you have worldwide ownership of the content.
Your API request will set the assetId
request parameter to the assetId obtained in step 1. It will also specify an ownership
resource with the property values shown below:
assetId
(request parameter): Set to the assetId obtained in step 1.general[0].ratio
:100
general[0].owner
: 'your_content_owner_name
'general[0].type
: 'exclude
'general[0].territories
:[]
{ "general": [ "ratio": 100, "owner": "your_content_owner_name", "type": "exclude", "territories": [] ] }
These properties indicate that the specified content owner – you need to replace your_content_owner_name with your actual content owner name – owns 100% (general[0].ratio
) of the content everywhere. In fact, this ownership
resource indicates that the owner owns the content everywhere except (general[0].type
) the provided list of territories (general[0].territories
), but since that property's value is an empty list, no territories are actually excluded.
Step 3.3: Set the asset's match policy
The YouTube rights management system provides two ways to associate a match policy with an asset or a usage policy with a claimed video:
-
Use a previously saved policy. In this approach, you use the API to retrieve your saved policies, find the policy you want to use, and then specify that policy's unique ID when setting an asset's match policy or creating a claim.
-
Define a
policy
resource when creating the asset or claim. In this case, the policy resource is not saved and, therefore, cannot be applied to other assets or claims.
We recommend that you use the first approach, which relies on saved policies. An important benefit to this approach is that if you update a saved policy, your change automatically affects all of the assets and claims that use that policy.
However, the code samples in this document use the second approach to set the match policy for the new asset, using the API's assetMatchPolicy.update
method. (This document also uses the second approach to set the usage policy, which is defined when the video is claimed.) The document uses the second approach because the names of saved policies can vary between partners; this approach ensures that the same code will work for everyone.
This step corresponds to this portion of the XML feed:
<rights_policy> <name>Monetize developer videos</name> </rights_policy> <rights_admin owner="True" type="match"/> <relationship> <item path="/feed/rights_admin[1]"/> <item path="/feed/rights_policy[1]"/> <related_item path="/feed/asset[1]"/> </relationship>
Your API request sets the assetId
parameter to the assetId
obtained in step 1. It also sends an assetMatchPolicy
resource that sets the property values listed below:
{ "rules": [ { "action": "monetize", "conditions": { "requiredTerritories": { "type": "exclude", "territories": [] } } } ] }
The example below shows how the assetMatchPolicy
resource would be constructed if you were setting a saved policy to be an asset's match policy. Your code would need to replace the PolicyID
string with the ID that uniquely identifies your saved policy.
{ "policyId": "PolicyID" }
Note: The XML feed, like the YouTube Content Manager's Policies page, specifies policies by name. To retrieve the ID for a saved policy, use the policies.list
method. Policy IDs vary from partner to partner, even for the default policies.
Step 3.4: Create a video resource and upload the media file
You upload your video using the Data API's videos.insert
method. The Resumable Uploads guide identifies the HTTP calls that you would make to upload videos using a resumable uploading process, and several of our API client libraries also support resumable uploads. (The sample code below uses a resumable uploading process with the Google APIs Python client library.)
This step corresponds to this portion of the XML feed:
<video> <title>Broadcast Yourself!: Using the YouTube Live APIs to stream to the world</title> <description>See a preview of the Google I/O presentation.</description> <genre>Entertainment</genre> <keyword>”Google I/O” “YouTube Live APIs”</keyword> <public>True</public> </video> <file type="video"> <filename>GOOG_IO_Broadcast_Yourself.mov</filename> </file> <relationship> <item path="/feed/file[1]"/> <related_item path="/feed/video[1]"/> </relationship>
If you are writing custom code to make the API calls, you send an initial request that creates the video
resource and returns an upload URL, then send a second request to upload the video binary file data to that URL. If you are using the Python client library (as in the sample), you send the video
resource and the video binary file data in the same request.
To create the video described in the XML sample, your API request would set the part
parameter's value to snippet,status
, and the video
resource in the request body would set the following properties. The snippet.categoryId
value (24
) corresponds to the Entertainment
category, which is the category associated with the video in the XML feed. Video categories are discussed in more detail in the appendixes.
{ "snippet": { "title": "Broadcast Yourself!: Using the YouTube Live APIs to stream to the world", "description": "See a preview of the Google I/O presentation.", "tags": ["Google I/O", "YouTube Live APIs"], "categoryId": 24 }, "status": { "privacyStatus": "private" } }
Note: We recommend that you set a video's privacy status to private
when you upload the video, then update it to public
later in the process. If you would rather upload the video as a public video, set the status.privacyStatus
property to public
.
Extract the id
property from the resource that the API returns. This property identifies the video ID that YouTube assigned to uniquely identify the video. This value is required in several ensuing API calls and is identified as the videoId
later in this documentation.
Step 3.5: Poll the Data API to determine when the video has been processed
Certain actions, such as creating a reference, require that YouTube has finished processing your video. For that reason, the script's next step is to ensure that the video upload is complete.
To check on the upload status, call the Data API's videos.list
method and set the following request parameters:
The API returns a list of video
resources (containing exactly one resource), and you need to check the value of that resource's processingDetails.processingStatus
property to determine whether YouTube is still processing the video. The property's value will change to something other than processing
, such as succeeded
or failed
, when YouTube has finished processing the video.
The sample code calls the videos.list
method every 12 seconds to determine whether the video has finished processing. This status check does not directly correspond to any element from the XML; it represents an action that a batch upload handles implicitly when it processes the XML.
Step 3.6: Set ad policy
Once YouTube has processed the video, you can update the video
resource's ad settings. Call the Content ID API's videoAdvertisingOptions.update
method to set the ad policy for the video. This action corresponds to this portion of the XML feed:
<ad_policy> <instream standard="long" trueview="true"> <prerolls>Allow</prerolls> <postrolls>Allow</postrolls> <midrolls>Deny</midrolls> </instream> <overlay> <adsense_for_video>Allow</adsense_for_video> <invideo>Allow</invideo> </overlay> </ad_policy> <relationship> <item path="/feed/ad_policy[1]"/> <related_item path="/feed/video[1]"/> </relationship>
The policy shown in this sample enables YouTube to show TrueView in-stream ads or overlay ads, including "long" 30-second ads, at the beginning (preroll) or end (postroll) of the video.
To set the ad policy, send a request that sets the videoId
parameter to the videoId
obtained earlier. The body of the request is a videoAdvertisingOptions
resource that sets the properties shown below:
{ "breakPosition": ["preroll", "postroll"], "adFormats": ["long", "trueview_instream", "overlay"] }
Step 3.7: Claim the video
In this step, you claim the video that you uploaded – and set the usage policy for the video – by calling the Content ID API's claims.insert
method. This step corresponds to this part of the XML feed:
<rights_policy> <rule action="monetize"/> </rights_policy> <rights_admin owner="True" type="match"/> <claim type="audiovisual" asset="/feed/asset[1]" rights_admin="/feed/rights_admin[1]" rights_policy="/feed/rights_policy[1]" video="/feed/video[1]"/>
As with the asset match policy, the sample script defines a one-off policy rather than associating a saved policy with the video. However, as discussed earlier, you can and are encouraged to use saved policies when setting usage and match policies.
In the claim
resource that you send with your request, set the properties shown in the resource below. Note that the assetId
and videoId
strings need to be replaced with the values that the script obtained in previous steps.
{ "assetId": assetId, "videoId": videoId, "contentType": "audiovisual", "policy": { "rules": [ { "action": "monetize" } ] } }
Extract the id
property from the resource that the API returns. This property identifies the claim ID that YouTube assigned to uniquely identify the claim. This value is required in ensuing API calls and is identified as the claimId
later in this documentation.
Step 3.8: Create a reference
Use the Content ID API's references.insert
method to create a reference for the Content ID system. You can create a reference using a claimed video as the reference content, or you can upload a reference file as part of the API call. If you're creating a reference from a claimed video, as the sample script does, the claim must already exist.
In your API request, set the claimId
request parameter to the claimid
obtained in the previous step. Also send a reference
resource that sets the properties shown below:
{ "contentType": "audiovisual" }
To create a reference-only asset (with no claimed video), make the following changes to the request above:
- Omit the
claimId
request parameter - Add the
assetId
property to the uploadedreference
resource. - Upload the reference file as the
media_body
of the API request.
Step 3.9: Make the video public
If you followed best practices and set your video's privacy status to private
when you created it, you can change the privacy status to public
after the upload process is successful. Use the YouTube Data API's videos.list
and videos.update
methods to retrieve and then update the video
resource for your newly uploaded video.
First, call the Data API's videos.list
method with the following request parameters:
part=status
id=videoId
This method returns a list containing one resource, which describes the video with the specified videoId
. Change the value of that resource's status.privacyStatus
property to public
, then call the Data API's videos.update method. Set the following request parameter:
part=status
The body of the request is the modified video resource.
Step 4: Integrate with your content delivery system
The sample code in the appendixes includes the specific metadata for the resources directly in the script. In practice, you're likely to want to integrate the script with your content management system. For a more complete content delivery system, you might add steps such as:
- Poll your content management system to identify assets that need to be added or updated.
- Retrieve asset metadata from the content management system.
- Update the content management system with YouTube-provided IDs for the created assets, videos, references, and claims, and with timestamps to record when the assets were most recently updated.
Appendix
Sample XML Feed file
<?xml version="1.0" encoding="UTF-8"?> <feed xmlns="http://www.youtube.com/schemas/cms/2.0" notification_email="someone@example.com" channel="your_channel" content_owner="your_name"> <asset type="web"> <title>Broadcast Yourself!: Using the YouTube Live APIs to stream to the world</title> <description>See a preview of the Google I/O presentation.</description> </asset> <video> <title>Broadcast Yourself!: Using the YouTube Live APIs to stream to the world</title> <description>See a preview of the Google I/O presentation.</description> <genre>Entertainment</genre> <keyword>”Google I/O” “YouTube Live APIs”</keyword> <public>True</public> </video> <file type="video"> <filename>GOOG_IO_Broadcast_Yourself.mov</filename> </file> <relationship> <item path="/feed/file[1]"/> <related_item path="/feed/video[1]"/> </relationship> <content_rating system="youtube">L0 N0 S0 V0 D0 F0</content_rating> <relationship> <item path="/feed/content_rating[1]"/> <related_item path="/feed/video[1]"/> </relationship> <ownership/> <relationship> <item path="/feed/asset[1]"/> <related_item path="/feed/ownership[1]"/> </relationship> <rights_policy> <name>Monetize developer videos</name> </rights_policy> <rights_admin owner="True" type="match"/> <relationship> <item path="/feed/rights_admin[1]"/> <item path="/feed/rights_policy[1]"/> <related_item path="/feed/asset[1]"/> </relationship> <ad_policy> <instream standard="long" trueview="true"> <prerolls>Allow</prerolls> <postrolls>Allow</postrolls> <midrolls>Deny</midrolls> </instream> <overlay> <adsense_for_video>Allow</adsense_for_video> <invideo>Allow</invideo> </overlay> </ad_policy> <relationship> <item path="/feed/ad_policy[1]"/> <related_item path="/feed/video[1]"/> </relationship> <claim type="audiovisual" asset="/feed/asset[1]" rights_admin="/feed/rights_admin[1]" rights_policy="/feed/rights_policy[1]" video="/feed/video[1]"/> </feed>
Sample script
The sample code uses the Google APIs Python client library.
#!/usr/bin/python2.6 # -*- 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 Content ID API. Command-line application that retrieves the information about given content owner. Usage: $ python yt_partner_api.py --file="/path/to/reference/file" You can also get help on all the command-line flags the program understands by running: $ python yt_partner_api.py --help To get detailed log output run: $ python yt_partner_api.py --logging_level=DEBUG \ --file="/path/to/reference/file" """ import gflags import httplib import httplib2 import json import logging import sys import time 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 # Explicitly tell the underlying HTTP transport library not to retry, since # we are handling retry logic ourselves. httplib2.RETRIES = 1 # Maximum number of times to retry before giving up. MAX_RETRIES = 10 # Always retry when these exceptions are raised. RETRIABLE_EXCEPTIONS = (httplib2.HttpLib2Error, IOError, httplib.NotConnected, httplib.IncompleteRead, httplib.ImproperConnectionState, httplib.CannotSendRequest, httplib.CannotSendHeader, httplib.ResponseNotReady, httplib.BadStatusLine) # Always retry when an apiclient.errors.HttpError with one of these status # codes is raised. RETRIABLE_STATUS_CODES = [500, 502, 503, 504] #httplib2.debuglevel = 4 FLAGS = gflags.FLAGS # 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 # For more information about using OAuth2 to access Google APIs, please visit: # https://developers.google.com/accounts/docs/OAuth2 # For more information about the client_secrets.json file format, please visit: # https://developers.google.com/api-client-library/python/guide/aaa_client_secrets 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 will 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) # Flags definition # # The gflags module makes defining command-line options easy for # applications. Run this program with the '--help' argument to see # all the flags that it understands. gflags.DEFINE_enum('logging_level', 'ERROR', ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], 'Set the level of logging detail.') gflags.DEFINE_string('file', None, 'The video file to upload.') def resumable_upload(insert_request): response = None error = None retry = 0 while response is None: try: print "Uploading file..." status, response = insert_request.next_chunk() if 'id' in response: print "'video id: %s was successfully uploaded." % (response['id']) return response['id'] else: exit("The upload failed with an unexpected response: %s" % response) except HttpError, e: if e.resp.status in RETRIABLE_STATUS_CODES: error = "A retriable HTTP error %d occurred:\n%s" % (e.resp.status, e.content) else: raise except RETRIABLE_EXCEPTIONS, e: error = "A retriable error occurred: %s" % e if error is not None: print error retry += 1 if retry > MAX_RETRIES: exit("No longer attempting to retry.") max_sleep = 2 ** retry sleep_seconds = random.random() * max_sleep print "Sleeping %f seconds and then retrying..." % sleep_seconds time.sleep(sleep_seconds) return None def createRequest(service, resource, operation, **kwargs): request = getattr(service, resource)() request = getattr(request, operation)(**kwargs) return request def executeOperation(service, resource, operation, **kwargs): request = getattr(service, resource)() request = getattr(request, operation)(**kwargs) return_value = request.execute() print json.dumps(return_value) return return_value def main(argv): # Let the gflags module process the command-line arguments try: argv = FLAGS(argv) except gflags.FlagsError, e: print '%s\nUsage: %s ARGS\n%s' % (e, argv[0], FLAGS) sys.exit(1) # 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 https://www.googleapis.com/auth/youtube.upload', message=MISSING_CLIENT_SECRETS_MESSAGE) # Set the logging according to the command-line flag logging.getLogger().setLevel(getattr(logging, FLAGS.logging_level)) # If the Credentials don't exist or are invalid run through the native client # flow. The Storage object will ensure that if successful the good # Credentials will get 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) # Create service and retrieve content owner service. partnerApi = build("youtubePartner", "v1", http=http) dataApi = build("youtube", "v3", http=http) try: title = 'Top Ten Ridiculous test #u', monetize_policy = {'rules': [{'action': 'monetize'}]} # Create the asset kwargs = {} metadata = {'title': title, 'description': 'Wow this is a really long description'} kwargs['body'] = {'metadata': metadata, 'type': 'web'} insert_asset = executeOperation(partnerApi, 'assets', 'insert', **kwargs) asset_id = insert_asset['id'] print 'Asset ID is ' + asset_id # Set asset ownership kwargs = {'assetId': asset_id} ownership = {'ratio': 100, 'owner': 'psomusictest', 'type': 'exclude', 'territories': []} body = {'general': [ownership], 'id': asset_id} kwargs['body'] = body set_ownership = executeOperation(partnerApi, 'ownership', 'update', **kwargs) # Set match policy kwargs = {'assetId': asset_id, 'body': monetize_policy} set_match_policy = executeOperation(partnerApi, 'assetMatchPolicy', 'update', **kwargs) # Insert video using resumable upload snippet = {'title': title, 'description': 'Wow this is a really long description', 'tags': ['fizzle', 'sizzle', 'razzle dazzle'], 'categoryId': '24'} status = {'privacyStatus': 'private'} body = { 'snippet': snippet, 'status': status } kwargs = {'part': 'snippet,status', 'body': body, 'media_body': MediaFileUpload(FLAGS.file, chunksize=-1, resumable=True)} insert_video = createRequest(dataApi, 'videos', 'insert', **kwargs) video_id = resumable_upload(insert_video) if not video_id: print 'video upload failed, so the rest of this exercise is pointless' return # Poll to see when video is processed kwargs = {'id': video_id, 'part': 'processingDetails'} check_video_status = createRequest(dataApi, 'videos', 'list', **kwargs) video_processed = False sleep_seconds = 12 while not video_processed: status = check_video_status.execute() processingDetails = status['items'][0]['processingDetails'] if processingDetails['processingStatus'] != 'processing': print 'hooray, it ' + processingDetails['processingStatus'] video_processed = True elif not 'processingProgress' in processingDetails: time.sleep(sleep_seconds) else: print ('so far, we processed %d/%d parts' % ( processingDetails['processingProgress']['partsProcessed'], processingDetails['processingProgress']['partsTotal'])) time.sleep(sleep_seconds) # Claim the video body = {'assetId': asset_id, 'videoId': video_id, 'policy': monetize_policy, 'contentType': 'audiovisual'} kwargs = {'body': body} claim_video = executeOperation(partnerApi, 'claims', 'insert', **kwargs) claim_id = claim_video['id'] print 'claim ID is ' + claim_id # Create the reference body = {'assetId': asset_id, 'videoId': video_id, 'contentType': 'audiovisual'} kwargs = {'claimId': claim_id, 'body': body} create_reference = executeOperation(partnerApi, 'references', 'insert', **kwargs) # Set ad policy (update video advertising options) ads = {'breakPosition': ['preroll','postroll'], 'adFormats': ['standard_instream','trueview_instream','overlay']} kwargs = {'videoId': video_id, 'body': ads} ads = executeOperation(partnerApi, 'videoAdvertisingOptions', 'update', **kwargs) #9 Update video's privacy status to public kwargs = {'part': 'status', 'id': video_id} video = executeOperation(dataApi, 'videos', 'list', **kwargs) video['items'][0]['status']['privacyStatus'] = 'public' kwargs = {'part': 'status', 'body': video['items'][0]} video = executeOperation(dataApi, 'videos', 'update', **kwargs) except AccessTokenRefreshError: print ("The credentials have been revoked or expired, please re-run" " the application to re-authorize") if __name__ == '__main__': main(sys.argv)
Other API actions
Retrieve a list of video categories using the Data API
The sample code sets the snippet.categoryID
property's value to 24
, which corresponds to the "Entertainment" genre. If you want your script to look up the ID for a given genre (rather than hardcoding the category IDs), you would call the Data API's videoCategories.list
method and set the following request parameters:
part=snippet
regionCode=US
(you could setregionCode
to a different value to retrieve video categories for another country)
For each videoCategory
resource in the API response, you would check the value of the snippet.title
property to identify a category name, and extract the id
property from the category you want. Here's what the videoCategory
resource looks like for the "Entertainment" category:
{ "id": "24", "kind": "youtube#videoCategory", "etag": "\"idnvT0N6oxG_2o6LCWUdZsqtqtk/I5rstjIK5PCItZFyWV-uw\"", "snippet": { "channelId": "UCBR8-60-B28hp2BmDPdntcQ", "title": "Entertainment" } }