Carica video

Il YouTubeVideoUploadService ti consente di caricare i video direttamente su YouTube tramite l'API Google Ads. Questi video possono essere utilizzati per creare asset video in vari tipi di annunci, ad esempio campagne Performance Max o campagne Demand Gen.

Questo servizio semplifica il flusso di lavoro di creazione degli annunci video gestendo la procedura di caricamento su YouTube, assicurandosi che i video siano associati correttamente al tuo account.

Concetti fondamentali

Prima di iniziare, è importante capire come vengono gestiti i caricamenti dei video e i diversi stati che possono assumere.

Workflow end-to-end

Il caricamento di un file video e la sua pubblicazione in un annuncio richiedono quattro passaggi sequenziali:

Passaggio Servizio e metodo Riepilogo
1. Avvia e carica i byte del video CreateYouTubeVideoUpload su YouTubeVideoUploadService Carica i metadati e il file binario del video per creare una risorsa YouTubeVideoUpload (customers/{customer_id}/youTubeVideoUploads/{video_upload_id}).
2. Esegui il polling dello stato di elaborazione SearchStream su GoogleAdsService Esegui una query su you_tube_video_upload finché state = 'PROCESSED' e l'ID video di YouTube a 11 caratteri video_id non viene compilato.
3. Crea un asset video riutilizzabile MutateAssets su AssetService Crea un YoutubeVideoAsset (youtube_video_id = video_id) per ottenere un nome della risorsa asset (customers/{customer_id}/assets/{asset_id}).
4. Collega l'asset a campagne o annunci MutateAssetGroupAssets su AssetGroupAssetService o MutateAdGroupAds su AdGroupAdService Collega l'asset a un Performance Max AssetGroupAsset (field_type = YOUTUBE_VIDEO) o a un Demand Gen DemandGenVideoResponsiveAdInfo (videos[].asset).

Proprietà del canale

Quando carichi un video, puoi specificare il canale YouTube di destinazione utilizzando il campo channel_id nella risorsa YouTubeVideoUpload:

  • Canale di proprietà dell'inserzionista (brand): fornisci il channel_id di un canale YouTube esistente di proprietà dell'inserzionista. Questa opzione è supportata solo con il flusso di autenticazione dell'utente; non può essere utilizzata con i service account.
  • Canale gestito da Google: se channel_id viene omesso, il video viene caricato su un canale YouTube gestito da Google associato all'account Google Ads.

Stati di caricamento

Il ciclo di vita di un caricamento di video di YouTube viene monitorato dal campo state. L'YouTubeVideoUploadState enum definisce i seguenti stati:

Stato Descrizione
PENDING Il video è in fase di caricamento.
UPLOADED Il video è stato caricato correttamente ed è in fase di elaborazione da parte di YouTube.
PROCESSED Il video è stato elaborato correttamente ed è pronto per l'uso.
FAILED Il caricamento o l'elaborazione non è riuscito e non può essere completato.
REJECTED Il video è stato rifiutato per motivi di convalida o norme.
UNAVAILABLE Lo stato del video non è disponibile; potrebbe essere stato rimosso da YouTube.

Impostazioni privacy

Il campo video_privacy controlla chi può vedere il video caricato. L' YouTubeVideoPrivacy enum supporta:

  • PUBLIC: il video è disponibile per chiunque su YouTube. (Consentito solo per i canali del brand).
  • UNLISTED: il video non è ricercabile, ma può essere visualizzato da chiunque abbia il link. Questa è l'opzione predefinita e l'unica per i canali gestiti da Google.

Dichiarazione dei contenuti generativi

A partire dalla v26, ai sensi di normative come l'AI Act dell'Unione europea, gli inserzionisti possono dichiarare se i contenuti video caricati contengono contenuti generati dall'AI o media sintetici.

Il campo video_content_metadata in YouTubeVideoUpload contiene VideoContentMetadata. Imposta il campo nidificato generative_content_disclosure utilizzando l' YouTubeVideoUploadGenerativeContentDisclosure enum:

Valore Descrizione
NON_GENERATIVE_CONTENT L'inserzionista ha dichiarato che il video non è generato dall'AI.
GENERATIVE_CONTENT L'inserzionista ha dichiarato che il video è generato dall'AI.

Carica un video

Per caricare un video, devi utilizzare una richiesta in più parti al metodo CreateYouTubeVideoUpload. La richiesta contiene sia i metadati per il caricamento sia il file video stesso.

1. Avvia il caricamento

Crea un CreateYouTubeVideoUploadRequest con i seguenti campi:

Campo Requisito Descrizione e vincoli
customer_id Obbligatorio L'ID cliente Google Ads a 10 cifre (senza trattini).
you_tube_video_upload.video_title Obbligatorio (INPUT_ONLY, IMMUTABLE) Titolo del video caricato su YouTube (fino a 100 caratteri; non può contenere < o >).
you_tube_video_upload.video_description Facoltativo (INPUT_ONLY, IMMUTABLE) Descrizione del video su YouTube (fino a 5000 caratteri; non può contenere < o >).
you_tube_video_upload.channel_id Facoltativo (IMMUTABLE) ID canale YouTube di destinazione a 24 caratteri (che inizia con UC) per un canale del brand di proprietà dell'inserzionista. Se omesso, i caricamenti vengono eseguiti su un canale gestito da Google.
you_tube_video_upload.video_privacy Facoltativo (modificabile sui canali del brand) YouTubeVideoPrivacy impostazione (UNLISTED per impostazione predefinita o PUBLIC per i canali del brand di proprietà dell'inserzionista).
you_tube_video_upload.video_content_metadata Facoltativo (INPUT_ONLY, IMMUTABLE) Disponibile a partire dalla v26: VideoContentMetadata con generative_content_disclosure impostato su un valore YouTubeVideoUploadGenerativeContentDisclosure (NON_GENERATIVE_CONTENT o GENERATIVE_CONTENT).

Se utilizzi una libreria client, chiama il CreateYouTubeVideoUpload metodo, passando il file video, e il caricamento del video verrà gestito internamente.

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

Se utilizzi REST, la sezione seguente descrive come gestire il caricamento del video.

2. Carica il video

Quando esegui il caricamento con REST, CreateYouTubeVideoUpload utilizza un protocollo di caricamento ripristinabile in due passaggi :

  1. Avvia la sessione di caricamento: invia una richiesta POST iniziale all'endpoint di caricamento CreateYouTubeVideoUpload (/upload/v26/customers/{customer_id}/youTubeVideoUploads:create) con x-goog-upload-command: start (e, facoltativamente, x-goog-upload-header-content-length per dichiarare le dimensioni del file). La risposta restituisce l'URL della sessione di caricamento nell'intestazione della risposta HTTP x-goog-upload-url, insieme a metadati come le dimensioni previste del chunk.
  2. Trasmetti e finalizza i byte del video: invia il payload video binario all'endpoint x-goog-upload-url con x-goog-upload-command: upload, finalize. Al termine del caricamento, la risposta restituisce il resource_name creato (customers/{customer_id}/youTubeVideoUploads/{video_upload_id}).

Per una descrizione completa delle intestazioni HTTP utilizzate nel protocollo di caricamento dei video, consulta il seguente esempio di codice:

# 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. Recupera lo stato di caricamento del video

Dopo aver avviato il caricamento di un video, esegui il polling del relativo stato di elaborazione eseguendo una query sui campi selezionabili della risorsa you_tube_video_upload (resource_name, video_upload_id, channel_id, video_id, state, e video_privacy) con GAQL finché state = 'PROCESSED' (i campi INPUT_ONLY non possono essere selezionati in 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
      

Gestisci caricamenti

Una volta completato il caricamento di un video, puoi utilizzarlo come asset video.

Utilizza il video caricato

Una volta che un video raggiunge lo stato PROCESSED, puoi trovare il relativo ID video di YouTube a 11 caratteri nel campo video_id della risorsa YouTubeVideoUpload.

Utilizza questo video_id per creare un YoutubeVideoAsset con MutateAssets e collegare il nome della risorsa asset risultante (customers/{customer_id}/assets/{asset_id}) alle tue campagne o ai tuoi annunci:

  1. Crea il YoutubeVideoAsset passando youtube_video_id a AssetService.MutateAssets:

    POST https://googleads.googleapis.com/v26/customers/{customer_id}/assets:mutate
    {
      "operations": [
        {
          "create": {
            "name": "Product Launch Video",
            "youtubeVideoAsset": {
              "youtubeVideoId": "dQw4w9WgXcQ"
            }
          }
        }
      ]
    }
    
  2. Collega il Asset a un AssetGroup o AdGroupAd:

    • Performance Max: crea un AssetGroupAsset utilizzando AssetGroupAssetService.MutateAssetGroupAssets con field_type impostato su YOUTUBE_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: Fai riferimento a customers/{customer_id}/assets/{asset_id} in the videos list of a DemandGenVideoResponsiveAdInfo object when calling AdGroupAdService.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"
                  }
                }
              }
            }
          }
        ]
      }
      
  3. Esegui una query sugli asset YOUTUBE_VIDEO esistenti utilizzando GoogleAdsService.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}'
    

Aggiorna metadati

Puoi aggiornare l'impostazione della privacy di un video caricato tramite questa API utilizzando il UpdateYouTubeVideoUpload metodo con update_mask impostato su "video_privacy". Dopo la creazione, è possibile aggiornare solo il campo video_privacy (PUBLIC o UNLISTED, per i video caricati su un canale del brand di proprietà dell'inserzionista); video_title, video_description, channel_id e video_content_metadata sono immutabili.

Rimuovi caricamenti

Se devi eliminare i video caricati con l'API Google Ads, passa i relativi customers/{customer_id}/youTubeVideoUploads/{video_upload_id} nomi delle risorse nel campo resource_names del metodo RemoveYouTubeVideoUpload. In questo modo, il video viene rimosso sia dalla raccolta di asset di Google Ads sia da YouTube.