Загрузка видео

YouTubeVideoUploadService позволяет загружать видео непосредственно на YouTube через Google Ads API. Эти видео можно использовать для создания видеообъектов в объявлениях разных типов, например в кампаниях с максимальной эффективностью или кампаниях для создания спроса.

Этот сервис упрощает процесс создания видеообъявлений, поскольку позволяет загружать видео на YouTube и связывать их с вашим аккаунтом.

Основные понятия

Прежде чем начать, важно понять, как происходит управление загрузкой видео и какие статусы могут быть у видео.

Владелец канала

При загрузке видео вы можете указать целевой канал YouTube, используя поле channel_id в ресурсе YouTubeVideoUpload:

  • Канал, принадлежащий рекламодателю (бренду). Укажите channel_id существующего канала YouTube, принадлежащего рекламодателю. Эта функция поддерживается только при аутентификации пользователей и не может использоваться с сервисными аккаунтами.
  • Канал, управляемый Google. Если параметр channel_id не указан, видео загружается на канал YouTube, управляемый Google и связанный с аккаунтом Google Рекламы.

Статусы загрузки

Жизненный цикл загруженного на YouTube видео отслеживается с помощью поля state. Перечисление YouTubeVideoUploadState определяет следующие состояния:

Штат Описание
PENDING Видео загружается.
UPLOADED Видео загружено и обрабатывается YouTube.
PROCESSED Видео успешно обработано и готово к использованию.
FAILED Не удалось загрузить или обработать файл.
REJECTED Видео было отклонено из-за несоответствия требованиям или нарушения правил.
UNAVAILABLE Статус видео недоступен. Возможно, оно было удалено с YouTube.

Настройки конфиденциальности

Поле video_privacy определяет, кто может видеть загруженное видео. Перечисление YouTubeVideoPrivacy поддерживает следующие значения:

  • PUBLIC – видео доступно всем пользователям YouTube. (только для каналов брендов).
  • UNLISTED – видео не показывается в результатах поиска, но его может посмотреть любой пользователь, у которого есть ссылка. Это вариант по умолчанию и единственный вариант для каналов, управляемых Google.

Раскрытие информации о контенте, созданном с помощью генеративного ИИ

Начиная с версии 26, в соответствии с такими нормативными актами, как закон ЕС об ИИ, рекламодатели могут сообщать, содержит ли загруженный видеоконтент синтетические медиафайлы или материалы, созданные искусственным интеллектом.

Поле video_content_metadata в YouTubeVideoUpload содержит VideoContentMetadata. Задайте вложенное поле generative_content_disclosure, используя перечисление YouTubeVideoUploadGenerativeContentDisclosure:

Значение Описание
NON_GENERATIVE_CONTENT Рекламодатель указал, что видео не создано искусственным интеллектом.
GENERATIVE_CONTENT Рекламодатель указал, что видео создано искусственным интеллектом.

Как загрузить видео

Чтобы загрузить видео, необходимо отправить составной запрос к методу CreateYouTubeVideoUpload. Запрос содержит метаданные для загрузки и сам видеофайл.

1. Запустите загрузку

Создайте объект CreateYouTubeVideoUploadRequest, указав:

  • customer_id – идентификатор клиента Google Рекламы.
  • you_tube_video_upload – объект YouTubeVideoUpload со свойствами video_title, video_description и, при необходимости, channel_id, video_privacy, а начиная с версии 26 – video_content_metadata.

Если вы используете клиентскую библиотеку, вызовите метод CreateYouTubeVideoUpload, передав ему видеофайл. Загрузка видео будет выполнена автоматически.

Java

This example is not yet available in Java; you can take a look at the other languages.
    

C#

YouTubeVideoUploadServiceClient ytService = client.GetService(
    Services.V25.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

This example is not yet available in Ruby; you can take a look at the other languages.
    

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

Если вы используете REST, в следующем разделе описано, как управлять загрузкой видео.

2. Загрузите видео.

Когда вы отправляете REST-запрос методу CreateYouTubeVideoUpload, ответ содержит URL, который нужно использовать для загрузки байтов видео в заголовке HTTP-ответа x-goog-upload-url, а также другие метаданные, например ожидаемый размер каждого фрагмента для фрагментированных загрузок, в соответствии со стандартным протоколом возобновляемой загрузки Google.

Вы также можете указать размер видео, которое собираетесь загрузить, в заголовке HTTP-запроса x-goog-upload-header-content-length.

Полное описание заголовков HTTP, используемых в протоколе загрузки видео, приведено в следующем примере кода:

# 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. Как получить статус загрузки видео

После начала загрузки видео вы можете получить его статус, запросив ресурс you_tube_video_upload с помощью GAQL:

Java

This example is not yet available in Java; you can take a look at the other languages.
    

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.V25.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

This example is not yet available in Ruby; you can take a look at the other languages.
    

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
      

Управление загрузками

После загрузки видео его можно использовать в качестве видеообъекта.

Как использовать загруженное видео

Когда видео достигнет статуса PROCESSED, его идентификатор видео на YouTube можно будет найти в поле video_id ресурса YouTubeVideoUpload.

Используйте этот video_id, чтобы создать YoutubeVideoAsset с MutateAssets или связать его напрямую с типами объявлений, которые поддерживают видео YouTube, указав идентификатор видео.

Обновить метаданные

Чтобы изменить метаданные видео, загруженного через этот API, используйте метод UpdateYouTubeVideoUpload. Обновить можно только поля video_title, video_description и video_privacy.

Удалить загрузки

Если вам нужно удалить видео, загруженные с помощью Google Ads API, используйте метод RemoveYouTubeVideoUpload. Видео будет удалено из библиотеки объектов Google Рекламы и с YouTube.