Le YouTubeVideoUploadService
vous permet de mettre en ligne des vidéos directement sur YouTube via l'API Google Ads. Ces
vidéos peuvent ensuite être utilisées pour créer des composants vidéo dans différents types d'annonces, comme
les campagnes Performance Max ou
les campagnes Demand Gen.
Ce service simplifie le workflow de création d'annonces vidéo en gérant le processus de mise en ligne sur YouTube et en s'assurant que les vidéos sont correctement associées à votre compte.
Concepts clés
Avant de commencer, il est important de comprendre comment les mises en ligne de vidéos sont gérées et les différents états qu'elles peuvent traverser.
Workflow de bout en bout
La mise en ligne d'un fichier vidéo et sa diffusion dans une annonce nécessitent quatre étapes séquentielles :
| Étape | Service et méthode | Résumé |
|---|---|---|
| 1. Lancer et mettre en ligne des octets vidéo | CreateYouTubeVideoUpload sur YouTubeVideoUploadService |
Mettez en ligne les métadonnées et le fichier binaire de la vidéo pour créer une ressource YouTubeVideoUpload (customers/{customer_id}/youTubeVideoUploads/{video_upload_id}). |
| 2. Interroger l'état de traitement | SearchStream sur GoogleAdsService |
Interrogez you_tube_video_upload jusqu'à ce que state = 'PROCESSED' et que l'ID YouTube video_id à 11 caractères soit renseigné. |
| 3. Créer un composant vidéo réutilisable | MutateAssets sur AssetService |
Créez un YoutubeVideoAsset (youtube_video_id = video_id) pour obtenir un nom de ressource de composant (customers/{customer_id}/assets/{asset_id}). |
| 4. Associer le composant à des campagnes ou des annonces | MutateAssetGroupAssets sur AssetGroupAssetService ou MutateAdGroupAds sur AdGroupAdService |
Associez le composant à un Performance Max AssetGroupAsset (field_type = YOUTUBE_VIDEO) ou à un Demand Gen DemandGenVideoResponsiveAdInfo (videos[].asset). |
Propriété de la chaîne
Lorsque vous mettez en ligne une vidéo, vous pouvez spécifier la chaîne YouTube de destination à l'aide de
le champ channel_id dans la ressource YouTubeVideoUpload
:
- Chaîne appartenant à l'annonceur (marque) : indiquez le
channel_idd'une chaîne YouTube existante appartenant à l'annonceur. Cette option n'est compatible qu'avec le flux d'authentification des utilisateurs . Elle ne peut pas être utilisée avec des comptes de service. - Chaîne gérée par Google : si
channel_idest omis, la vidéo est mise en ligne sur une chaîne YouTube gérée par Google et associée au compte Google Ads.
États de mise en ligne
Le cycle de vie d'une mise en ligne de vidéo YouTube est suivi par le champ state.
L'YouTubeVideoUploadState
enum définit les états suivants :
| État | Description |
|---|---|
PENDING |
La vidéo est en cours de mise en ligne. |
UPLOADED |
La vidéo a bien été mise en ligne et est en cours de traitement par YouTube. |
PROCESSED |
La vidéo a bien été traitée et est prête à être utilisée. |
FAILED |
La mise en ligne ou le traitement a échoué et ne peut pas être effectué. |
REJECTED |
La vidéo a été refusée pour des raisons de validation ou de non-respect des règles. |
UNAVAILABLE |
L'état de la vidéo n'est pas disponible. Elle a peut-être été supprimée de YouTube. |
Paramètres de confidentialité
Le champ video_privacy contrôle qui peut voir la vidéo mise en ligne. L'
YouTubeVideoPrivacy
enum est compatible avec les options suivantes :
PUBLIC: la vidéo est disponible pour tous les utilisateurs sur YouTube. (Autorisé uniquement pour les chaînes de marque).UNLISTED: la vidéo n'est pas visible dans les résultats de recherche, mais peut être visionnée par toute personne disposant du lien. Il s'agit de l'option par défaut et de la seule option disponible pour les chaînes gérées par Google.
Divulgation de contenu génératif
À partir de la version 26, en vertu de réglementations telles que le règlement européen sur l'IA, les annonceurs peuvent indiquer si le contenu vidéo mis en ligne contient des médias générés par l'IA ou synthétiques.
Le champ video_content_metadata dans YouTubeVideoUpload contient
VideoContentMetadata. Définissez son champ imbriqué
generative_content_disclosure à l'aide de l'
YouTubeVideoUploadGenerativeContentDisclosure
enum :
| Valeur | Description |
|---|---|
NON_GENERATIVE_CONTENT |
L'annonceur a indiqué que la vidéo n'était pas générée par l'IA. |
GENERATIVE_CONTENT |
L'annonceur a indiqué que la vidéo était générée par l'IA. |
Mettre en ligne une vidéo
Pour mettre en ligne une vidéo, vous devez utiliser une requête en plusieurs parties pour la méthode CreateYouTubeVideoUpload. La requête contient à la fois les métadonnées de la mise en ligne et le fichier vidéo lui-même.
1. Lancer la mise en ligne
Créez un CreateYouTubeVideoUploadRequest avec les champs suivants :
| Champ | Exigence | Description et contraintes |
|---|---|---|
customer_id |
Obligatoire | Numéro client Google Ads à 10 chiffres (sans tirets). |
you_tube_video_upload.video_title |
Obligatoire (INPUT_ONLY, IMMUTABLE) |
Titre de la vidéo mise en ligne sur YouTube (jusqu'à 100 caractères ; ne peut pas contenir < ni >). |
you_tube_video_upload.video_description |
Facultatif (INPUT_ONLY, IMMUTABLE) |
Description de la vidéo sur YouTube (jusqu'à 5 000 caractères ; ne peut pas contenir < ou >). |
you_tube_video_upload.channel_id |
Facultatif (IMMUTABLE) |
ID de la chaîne YouTube à 24 caractères (commençant par UC) pour une chaîne de marque appartenant à l'annonceur. Si elle est omise, la vidéo est mise en ligne sur une chaîne gérée par Google. |
you_tube_video_upload.video_privacy |
Facultatif (modifiable sur les chaînes de marque) | YouTubeVideoPrivacy setting (UNLISTED default, or PUBLIC for advertiser-owned brand channels). |
you_tube_video_upload.video_content_metadata |
Facultatif (INPUT_ONLY, IMMUTABLE) |
Disponible à partir de la version 26 : VideoContentMetadata avec generative_content_disclosure défini sur une valeur YouTubeVideoUploadGenerativeContentDisclosure (NON_GENERATIVE_CONTENT ou GENERATIVE_CONTENT). |
Si vous utilisez une bibliothèque cliente, appelez la
CreateYouTubeVideoUpload
méthode, en transmettant votre fichier vidéo. La mise en ligne de la vidéo sera gérée
en interne.
Java
String videoUploadResourceName; try (YouTubeVideoUploadServiceClient youTubeVideoUploadServiceClient = googleAdsClient.getLatestVersion().createYouTubeVideoUploadServiceClient()) { YouTubeVideoUpload youTubeVideoUpload = YouTubeVideoUpload.newBuilder() .setVideoTitle("Test Video") .setVideoDescription("Test Video Description") .setVideoPrivacy(YouTubeVideoPrivacy.UNLISTED) .build(); CreateYouTubeVideoUploadRequest createUploadRequest = CreateYouTubeVideoUploadRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setYouTubeVideoUpload(youTubeVideoUpload) .build(); CreateYouTubeVideoUploadResponse response = youTubeVideoUploadServiceClient.createYouTubeVideoUpload( createUploadRequest, () -> new FileInputStream(videoFile), null); videoUploadResourceName = response.getResourceName(); System.out.printf("Created YouTube video upload: %s%n", videoUploadResourceName); }
C#
YouTubeVideoUploadServiceClient ytService = client.GetService( Services.V26.YouTubeVideoUploadService); CreateYouTubeVideoUploadRequest createUploadRequest = new CreateYouTubeVideoUploadRequest() { CustomerId = customerId.ToString(), YouTubeVideoUpload = new YouTubeVideoUpload() { VideoTitle = "Test Video", VideoDescription = "Test Video Description", VideoPrivacy = YouTubeVideoPrivacy.Unlisted } }; string videoUploadResourceName; using (FileStream stream = File.OpenRead(videoFilePath)) { ResumableUploadSession<CreateYouTubeVideoUploadRequest, CreateYouTubeVideoUploadResponse> session = ytService.CreateYouTubeVideoUpload(); CreateYouTubeVideoUploadResponse response = session.BeginUploadAsync(createUploadRequest, stream).Result; videoUploadResourceName = response.ResourceName; Console.WriteLine($"Created YouTube video upload: {videoUploadResourceName}"); }
PHP
$youTubeVideoUploadServiceClient = $googleAdsClient->getYouTubeVideoUploadServiceClient(); $youTubeVideoUpload = new YouTubeVideoUpload([ 'video_title' => 'Test Video', 'video_description' => 'Test Video Description', 'video_privacy' => YouTubeVideoPrivacy::UNLISTED ]); $createYouTubeVideoUploadRequest = CreateYouTubeVideoUploadRequest::build( $customerId, $youTubeVideoUpload ); /** @var ResumableUpload $resumableUpload */ $resumableUpload = $youTubeVideoUploadServiceClient->createYouTubeVideoUpload( $createYouTubeVideoUploadRequest ); $stream = Utils::streamFor(fopen($videoFilePath, 'rb')); /** @var CreateYouTubeVideoUploadResponse $response */ $response = $resumableUpload->startUpload($stream); $videoUploadResourceName = $response->getResourceName(); printf("Created YouTube video upload: '%s'%s", $videoUploadResourceName, PHP_EOL);
Python
yt_service: YouTubeVideoUploadServiceClient = client.get_service( "YouTubeVideoUploadService" ) create_upload_request: CreateYouTubeVideoUploadRequest = ( youtube_video_upload_service.CreateYouTubeVideoUploadRequest() ) create_upload_request.customer_id = customer_id create_upload_request.you_tube_video_upload.video_title = "Test Video" create_upload_request.you_tube_video_upload.video_description = ( "Test Video Description" ) create_upload_request.you_tube_video_upload.video_privacy = ( client.enums.YouTubeVideoPrivacyEnum.UNLISTED ) video_upload_resource_name: str with open(video_file_path, "rb") as stream: response: CreateYouTubeVideoUploadResponse = ( yt_service.create_you_tube_video_upload( stream=stream, request=create_upload_request, retry=None, ) ) video_upload_resource_name = response.resource_name print(f"Created YouTube video upload: {video_upload_resource_name}")
Ruby
video_upload = client.resource.you_tube_video_upload do |v| v.video_title = "Test Video" v.video_description = "Test Video Description" v.video_privacy = :UNLISTED end upload = client.service.you_tube_video_upload.create_you_tube_video_upload( customer_id: customer_id, you_tube_video_upload: video_upload, ) video_upload_resource_name = nil File.open(video_file_path, "rb") do |stream| response = upload.start( stream: stream, content_type: "application/octet-stream", ) video_upload_resource_name = response.resource_name puts "Created YouTube video upload: #{video_upload_resource_name}" end
Perl
This example is not yet available in Perl; you can take a look at the other languages.
curl
# # Use the --i curl parameter to capture response headers in the $RESPONSE # variable. FILE_SIZE=$(wc -c < "${VIDEO_FILE_NAME}" | tr -d '\r') RESPONSE=$(curl -i -f -v -s --request POST \ "https://googleads.googleapis.com/resumable/upload/v${API_VERSION}/customers/${CUSTOMER_ID}/youTubeVideoUploads:create" \ --header "Content-Type: application/json" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --header "X-Goog-Upload-Protocol: resumable" \ --header "X-Goog-Upload-Command: start" \ --header "X-Goog-Upload-Header-Content-Length: ${FILE_SIZE}" \ --data @- <<EOF { "customer_id": "${CUSTOMER_ID}", "you_tube_video_upload": { "video_title": "${VIDEO_TITLE}", "video_description": "${VIDEO_DESCRIPTION}", "video_privacy": "UNLISTED" } } EOF ) # Extract the value of the "x-goog-upload-url" header from the HTTP response. UPLOAD_URL=$(echo "${RESPONSE}" \ | grep -i '^x-goog-upload-url' \ | awk '{print $2}' \ | tr -d '\r') CHUNK_SIZE=$(echo "${RESPONSE}" \ | grep -i '^x-goog-upload-chunk-granularity' \ | awk '{print $2}' \ | tr -d '\r')
Si vous utilisez REST, la section suivante décrit comment gérer la mise en ligne de la vidéo.
2. Mettre en ligne la vidéo
Lors de l'importation avec REST, CreateYouTubeVideoUpload utilise un
protocole d'importation avec reprise en deux étapes :
- Démarrer la session de mise en ligne : envoyez une requête
POSTinitiale auCreateYouTubeVideoUploadpoint de terminaison de mise en ligne (/upload/v26/customers/{customer_id}/youTubeVideoUploads:create) avecx-goog-upload-command: start(et éventuellementx-goog-upload-header-content-lengthpour déclarer la taille du fichier). La réponse renvoie l'URL de la session de mise en ligne dans l'en-tête de réponse HTTPx-goog-upload-url, ainsi que des métadonnées telles que la taille de bloc attendue. - Diffuser et finaliser les octets vidéo : envoyez la charge utile vidéo binaire au point de terminaison
x-goog-upload-urlavecx-goog-upload-command: upload, finalize. Une fois la mise en ligne terminée, la réponse renvoie leresource_namecréé (customers/{customer_id}/youTubeVideoUploads/{video_upload_id}).
Pour obtenir une description complète des en-têtes HTTP utilisés dans le protocole de mise en ligne de vidéos, consultez l'exemple de code suivant :
# Take the first ${CHUNK_SIZE} bytes of the video file and upload them. head -c ${CHUNK_SIZE} ${VIDEO_FILE_NAME} | curl -i -v -X PUT "${UPLOAD_URL}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --header "X-Goog-Upload-Offset: 0" \ --header "X-Goog-Upload-Command: upload" \ --header "Content-Length: ${CHUNK_SIZE}" \ --data-binary @- # Query the status of the upload. QUERY_RESPONSE=$(curl -i -s -X POST "${UPLOAD_URL}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --header "X-Goog-Upload-Command: query") # Extract the value of the "x-goog-upload-size-received" header from the HTTP # response. UPLOADED_BYTES=$(echo "${QUERY_RESPONSE}" \ | grep -i '^x-goog-upload-size-received' \ | awk '{print $2}' \ | tr -d '\r') echo "Uploaded ${UPLOADED_BYTES} bytes." REMAINING_BYTES=$((FILE_SIZE - UPLOADED_BYTES)) echo "${REMAINING_BYTES} bytes remaining to upload." FINALIZE_RESPONSE=$(tail -c ${REMAINING_BYTES} ${VIDEO_FILE_NAME} | curl -v -X PUT "${UPLOAD_URL}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --header "X-Goog-Upload-Offset: ${UPLOADED_BYTES}" \ --header "X-Goog-Upload-Command: upload, finalize" \ --data-binary @-) UPLOADED_VIDEO_RESOURCE_NAME=$(echo $FINALIZE_RESPONSE | jq -r '.resourceName')
3. Récupérer l'état de la mise en ligne de la vidéo
Après avoir lancé la mise en ligne d'une vidéo, interrogez son état de traitement en interrogeant les
champs sélectionnables de la you_tube_video_upload ressource
(resource_name, video_upload_id, channel_id, video_id, state, et
video_privacy) avec GAQL jusqu'à ce que state = 'PROCESSED' (les champs INPUT_ONLY ne
peuvent pas être sélectionnés dans GAQL) :
Java
// Retrieve the metadata of the newly uploaded video. String query = String.format( "SELECT " + "you_tube_video_upload.resource_name, " + "you_tube_video_upload.video_id, " + "you_tube_video_upload.state " + "FROM you_tube_video_upload " + "WHERE you_tube_video_upload.resource_name = '%s'", videoUploadResourceName); try (GoogleAdsServiceClient googleAdsServiceClient = googleAdsClient.getLatestVersion().createGoogleAdsServiceClient()) { SearchGoogleAdsStreamRequest request = SearchGoogleAdsStreamRequest.newBuilder() .setCustomerId(Long.toString(customerId)) .setQuery(query) .build(); ServerStream<SearchGoogleAdsStreamResponse> stream = googleAdsServiceClient.searchStreamCallable().call(request); for (SearchGoogleAdsStreamResponse response : stream) { for (GoogleAdsRow googleAdsRow : response.getResultsList()) { YouTubeVideoUpload video = googleAdsRow.getYouTubeVideoUpload(); System.out.printf( "Video with ID %s was found in state %s.%n", video.getVideoId(), video.getState()); } } }
C#
// Retrieve the metadata of the newly uploaded video. string query = $@" SELECT you_tube_video_upload.resource_name, you_tube_video_upload.video_id, you_tube_video_upload.state FROM you_tube_video_upload WHERE you_tube_video_upload.resource_name = '{videoUploadResourceName}'"; GoogleAdsServiceClient gaService = client.GetService( Services.V26.GoogleAdsService); gaService.SearchStream(customerId.ToString(), query, delegate (SearchGoogleAdsStreamResponse resp) { foreach (GoogleAdsRow row in resp.Results) { Console.WriteLine( $"Video with ID {row.YouTubeVideoUpload.VideoId} was found in " + $"state {row.YouTubeVideoUpload.State}."); } } );
PHP
// Retrieve the metadata of the newly uploaded video. $query = sprintf( "SELECT you_tube_video_upload.resource_name, " . "you_tube_video_upload.video_id, " . "you_tube_video_upload.state " . "FROM you_tube_video_upload " . "WHERE you_tube_video_upload.resource_name = '%s'", $videoUploadResourceName ); $googleAdsServiceClient = $googleAdsClient->getGoogleAdsServiceClient(); $stream = $googleAdsServiceClient->searchStream( SearchGoogleAdsStreamRequest::build($customerId, $query) ); foreach ($stream->iterateAllElements() as $googleAdsRow) { /** @var GoogleAdsRow $googleAdsRow */ printf( "Video with ID '%s' was found in state '%s'.%s", $googleAdsRow->getYouTubeVideoUpload()->getVideoId(), YouTubeVideoUploadState::name($googleAdsRow->getYouTubeVideoUpload()->getState()), PHP_EOL ); }
Python
# Retrieve the metadata of the newly uploaded video. query: str = f""" SELECT you_tube_video_upload.resource_name, you_tube_video_upload.video_id, you_tube_video_upload.state FROM you_tube_video_upload WHERE you_tube_video_upload.resource_name = '{video_upload_resource_name}'""" ga_service: GoogleAdsServiceClient = client.get_service("GoogleAdsService") stream: Iterator[SearchGoogleAdsStreamResponse] = ga_service.search_stream( customer_id=customer_id, query=query ) for row in itertools.chain.from_iterable(batch.results for batch in stream): video = row.you_tube_video_upload print( f"Video with ID {row.you_tube_video_upload.video_id} was found in state {row.you_tube_video_upload.state}." )
Ruby
# Retrieve the metadata of the newly uploaded video. query = <<~EOQ SELECT you_tube_video_upload.resource_name, you_tube_video_upload.video_id, you_tube_video_upload.state FROM you_tube_video_upload WHERE you_tube_video_upload.resource_name = '#{video_upload_resource_name}' EOQ responses = client.service.google_ads.search_stream( customer_id: customer_id, query: query, ) responses.each do |batch| batch.results.each do |row| puts "Video with ID #{row.you_tube_video_upload.video_id} was found in " \ "state #{row.you_tube_video_upload.state}." end end
Perl
This example is not yet available in Perl; you can take a look at the other languages.
curl
curl -i -v -X POST \ "https://qa-prod-googleads.sandbox.googleapis.com/v${API_VERSION}/customers/${CUSTOMER_ID}/googleAds:search" \ --header "Content-Type: application/json" \ --header "Developer-Token: ${DEVELOPER_TOKEN}" \ --header "login-customer-id: ${MANAGER_CUSTOMER_ID}" \ --header "Authorization: Bearer ${OAUTH2_ACCESS_TOKEN}" \ --data @- <<EOF { "query": "SELECT you_tube_video_upload.resource_name, you_tube_video_upload.video_id, you_tube_video_upload.state FROM you_tube_video_upload WHERE you_tube_video_upload.resource_name = '$UPLOADED_VIDEO_RESOURCE_NAME'" } EOF
Gérer les importations
Une fois la mise en ligne d'une vidéo terminée, vous pouvez l'utiliser comme composant vidéo.
Utiliser la vidéo mise en ligne
Une fois qu'une vidéo atteint l'état PROCESSED, vous pouvez trouver son ID vidéo YouTube à 11 caractères dans le champ video_id de la ressource YouTubeVideoUpload.
Utilisez ce video_id pour créer un YoutubeVideoAsset avec
MutateAssets et associer le nom de ressource de composant obtenu
(customers/{customer_id}/assets/{asset_id}) à vos campagnes ou annonces :
Créez le
YoutubeVideoAsseten transmettantyoutube_video_idàAssetService.MutateAssets:POST https://googleads.googleapis.com/v26/customers/{customer_id}/assets:mutate { "operations": [ { "create": { "name": "Product Launch Video", "youtubeVideoAsset": { "youtubeVideoId": "dQw4w9WgXcQ" } } } ] }Associez le
Assetà unAssetGroupouAdGroupAd:Performance Max : créez un
AssetGroupAssetà l'aide deAssetGroupAssetService.MutateAssetGroupAssetsavecfield_typedéfini surYOUTUBE_VIDEO:POST https://googleads.googleapis.com/v26/customers/{customer_id}/assetGroupAssets:mutate { "operations": [ { "create": { "assetGroup": "customers/{customer_id}/assetGroups/{asset_group_id}", "asset": "customers/{customer_id}/assets/{asset_id}", "fieldType": "YOUTUBE_VIDEO" } } ] }Demand Gen : référencez
customers/{customer_id}/assets/{asset_id}dans la listevideosd'un objetDemandGenVideoResponsiveAdInfolorsque vous appelezAdGroupAdService.MutateAdGroupAds:POST https://googleads.googleapis.com/v26/customers/{customer_id}/adGroupAds:mutate { "operations": [ { "create": { "adGroup": "customers/{customer_id}/adGroups/{ad_group_id}", "status": "PAUSED", "ad": { "name": "Demand Gen Video Ad", "finalUrls": ["https://www.example.com"], "demandGenVideoResponsiveAd": { "videos": [ { "asset": "customers/{customer_id}/assets/{asset_id}" } ], "logoImages": [ { "asset": "customers/{customer_id}/assets/{logo_asset_id}" } ], "headlines": [ { "text": "Example Headline" } ], "longHeadlines": [ { "text": "Example Long Headline" } ], "descriptions": [ { "text": "Example Description" } ], "businessName": { "text": "Example Business" } } } } } ] }
Interrogez les composants
YOUTUBE_VIDEOexistants à l'aide deGoogleAdsService.SearchStream:SELECT asset.id, asset.resource_name, asset.name, asset.type, asset.youtube_video_asset.youtube_video_id, asset.youtube_video_asset.youtube_video_title FROM asset WHERE asset.type = 'YOUTUBE_VIDEO' AND asset.youtube_video_asset.youtube_video_id = '{video_id}'
Mettre à jour les métadonnées
Vous pouvez modifier le paramètre de confidentialité d'une vidéo mise en ligne via cette API à l'aide de
la UpdateYouTubeVideoUpload méthode avec update_mask
défini sur "video_privacy". Seul le champ video_privacy (PUBLIC ou UNLISTED, pour les vidéos mises en ligne sur une chaîne de marque appartenant à l'annonceur) peut être modifié après sa création. video_title, video_description, channel_id et video_content_metadata sont immuables.
Supprimer les mises en ligne
Si vous devez supprimer des vidéos mises en ligne avec l'API Google Ads, transmettez leurs
customers/{customer_id}/youTubeVideoUploads/{video_upload_id} noms de ressource
dans le resource_names champ de la
RemoveYouTubeVideoUpload méthode. La vidéo est alors supprimée de la bibliothèque de composants Google Ads et de YouTube.