YouTubeVideoUploadService
memungkinkan Anda mengupload video langsung ke YouTube melalui Google Ads API. Video ini
kemudian dapat digunakan untuk membuat aset video dalam berbagai jenis iklan, seperti
kampanye Performa Maksimal atau
kampanye Peningkat Permintaan.
Layanan ini menyederhanakan alur kerja pembuatan iklan video dengan menangani proses upload YouTube, sehingga memastikan video dikaitkan dengan benar ke akun Anda.
Konsep utama
Sebelum memulai, Anda harus memahami cara pengelolaan upload video dan berbagai status yang dapat dialami.
Alur kerja end-to-end
Mengupload file video dan menayangkannya dalam iklan memerlukan empat langkah berurutan:
| Langkah | Layanan dan metode | Ringkasan |
|---|---|---|
| 1. Memulai dan mengupload byte video | CreateYouTubeVideoUpload di YouTubeVideoUploadService |
Mengupload metadata video dan file biner untuk membuat resource YouTubeVideoUpload (customers/{customer_id}/youTubeVideoUploads/{video_upload_id}). |
| 2. Memeriksa status pemrosesan | SearchStream di GoogleAdsService |
Membuat kueri you_tube_video_upload hingga state = 'PROCESSED' dan video_id YouTube 11 karakter diisi. |
| 3. Membuat aset video yang dapat digunakan kembali | MutateAssets di AssetService |
Membuat YoutubeVideoAsset (youtube_video_id = video_id) untuk mendapatkan nama resource aset (customers/{customer_id}/assets/{asset_id}). |
| 4. Menautkan aset ke kampanye atau iklan | MutateAssetGroupAssets di AssetGroupAssetService, atau MutateAdGroupAds di AdGroupAdService |
Menautkan aset ke Performa Maksimal AssetGroupAsset (field_type = YOUTUBE_VIDEO) atau Peningkat Permintaan DemandGenVideoResponsiveAdInfo (videos[].asset). |
Kepemilikan channel
Saat mengupload video, Anda dapat menentukan channel YouTube tujuan menggunakan
kolom channel_id di YouTubeVideoUpload
resource:
- Channel milik pengiklan (merek): Berikan
channel_idchannel YouTube yang sudah ada dan dimiliki oleh pengiklan. Hal ini hanya didukung oleh alur autentikasi pengguna; tidak dapat digunakan dengan akun layanan. - Channel yang dikelola Google: Jika
channel_iddihilangkan, video akan diupload ke channel YouTube yang dikelola Google dan terkait dengan akun Google Ads.
Status upload
Siklus proses upload video YouTube dilacak oleh kolom state.
Enum YouTubeVideoUploadState
menentukan status berikut:
| Status | Deskripsi |
|---|---|
PENDING |
Video sedang diupload. |
UPLOADED |
Video berhasil diupload dan sedang diproses oleh YouTube. |
PROCESSED |
Video berhasil diproses dan siap digunakan. |
FAILED |
Upload atau pemrosesan gagal dan tidak dapat diselesaikan. |
REJECTED |
Video ditolak karena alasan validasi atau kebijakan. |
UNAVAILABLE |
Status video tidak tersedia; video mungkin telah dihapus dari YouTube. |
Setelan privasi
Kolom video_privacy mengontrol siapa yang dapat melihat video yang diupload. Enum
YouTubeVideoPrivacy
mendukung:
PUBLIC: Video tersedia untuk siapa saja di YouTube. (Hanya diizinkan untuk channel merek).UNLISTED: Video tidak dapat ditelusuri, tetapi dapat dilihat oleh siapa saja yang memiliki link. Ini adalah opsi default dan satu-satunya opsi untuk channel yang dikelola Google.
Pengungkapan konten generatif
Mulai v26, berdasarkan peraturan seperti EU AI Act, pengiklan dapat mengungkapkan apakah konten video yang diupload berisi media sintetis atau yang dibuat AI.
Kolom video_content_metadata di YouTubeVideoUpload berisi
VideoContentMetadata. Tetapkan kolom
generative_content_disclosure bertingkatnya menggunakan
YouTubeVideoUploadGenerativeContentDisclosure
enum:
| Nilai | Deskripsi |
|---|---|
NON_GENERATIVE_CONTENT |
Pengiklan mengungkapkan video tersebut sebagai video yang tidak dibuat oleh AI. |
GENERATIVE_CONTENT |
Pengiklan mengungkapkan video tersebut sebagai video yang dibuat oleh AI. |
Mengupload video
Untuk mengupload video, Anda harus menggunakan permintaan multibagian ke metode CreateYouTubeVideoUpload. Permintaan ini berisi metadata untuk upload dan file video itu sendiri.
1. Memulai upload
Buat CreateYouTubeVideoUploadRequest dengan kolom berikut:
| Kolom | Persyaratan | Deskripsi dan batasan |
|---|---|---|
customer_id |
Wajib | ID pelanggan Google Ads 10 digit (tanpa tanda hubung). |
you_tube_video_upload.video_title |
Wajib (INPUT_ONLY, IMMUTABLE) |
Judul video yang diupload di YouTube (maksimal 100 karakter; tidak boleh berisi < atau >). |
you_tube_video_upload.video_description |
Opsional (INPUT_ONLY, IMMUTABLE) |
Deskripsi video di YouTube (maksimal 5.000 karakter; tidak boleh berisi < atau >). |
you_tube_video_upload.channel_id |
Opsional (IMMUTABLE) |
ID channel YouTube 24 karakter tujuan (dimulai dengan UC) untuk channel korporat milik pengiklan. Jika dihilangkan, video akan diupload ke channel yang dikelola Google. |
you_tube_video_upload.video_privacy |
Opsional (dapat diubah di channel korporat) | YouTubeVideoPrivacy setelan (UNLISTED default, atau PUBLIC untuk channel korporat milik pengiklan). |
you_tube_video_upload.video_content_metadata |
Opsional (INPUT_ONLY, IMMUTABLE) |
Tersedia mulai v26: VideoContentMetadata dengan generative_content_disclosure yang ditetapkan ke nilai YouTubeVideoUploadGenerativeContentDisclosure (NON_GENERATIVE_CONTENT atau GENERATIVE_CONTENT). |
Jika Anda menggunakan library klien, panggil
CreateYouTubeVideoUpload
metode, teruskan file video Anda, dan upload video akan ditangani
secara internal.
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')
Jika Anda menggunakan REST, bagian berikut menjelaskan cara mengelola upload video.
2. Mengupload video
Saat mengupload dengan REST, CreateYouTubeVideoUpload menggunakan protokol upload yang dapat dilanjutkan dua langkah
:
- Memulai sesi upload: Kirim permintaan
POSTawal keCreateYouTubeVideoUploadendpoint upload (/upload/v26/customers/{customer_id}/youTubeVideoUploads:create) denganx-goog-upload-command: start(dan secara opsionalx-goog-upload-header-content-lengthuntuk mendeklarasikan ukuran file). Respons akan menampilkan URL sesi upload di header respons HTTPx-goog-upload-url, beserta metadata seperti ukuran bagian yang diharapkan. - Streaming dan menyelesaikan byte video: Kirim payload video biner ke endpoint
x-goog-upload-urldenganx-goog-upload-command: upload, finalize. Saat upload selesai, respons akan menampilkanresource_nameyang dibuat (customers/{customer_id}/youTubeVideoUploads/{video_upload_id}).
Untuk mengetahui deskripsi lengkap header HTTP yang digunakan dalam protokol upload video, lihat contoh kode berikut:
# 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. Mengambil status upload video
Setelah memulai upload video, periksa status pemrosesannya dengan membuat kueri kolom yang
dapat dipilih dari resource you_tube_video_upload
(resource_name, video_upload_id, channel_id, video_id, state, dan
video_privacy) dengan GAQL hingga state = 'PROCESSED' (kolom INPUT_ONLY
tidak dapat dipilih di 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
Mengelola upload
Setelah upload video selesai, Anda dapat menggunakannya sebagai aset video.
Menggunakan video yang diupload
Setelah video mencapai status PROCESSED, Anda dapat menemukan ID video YouTube 11 karakter di kolom video_id resource YouTubeVideoUpload.
Gunakan video_id ini untuk membuat YoutubeVideoAsset dengan
MutateAssets dan menautkan nama resource aset yang dihasilkan
(customers/{customer_id}/assets/{asset_id}) ke kampanye atau iklan Anda:
Buat
YoutubeVideoAssetdengan meneruskanyoutube_video_idkeAssetService.MutateAssets:POST https://googleads.googleapis.com/v26/customers/{customer_id}/assets:mutate { "operations": [ { "create": { "name": "Product Launch Video", "youtubeVideoAsset": { "youtubeVideoId": "dQw4w9WgXcQ" } } } ] }Tautkan
AssetkeAssetGroupatauAdGroupAd:Performa Maksimal: Buat
AssetGroupAssetmenggunakanAssetGroupAssetService.MutateAssetGroupAssetsdenganfield_typeditetapkan keYOUTUBE_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" } } ] }Peningkat Permintaan: Referensikan
customers/{customer_id}/assets/{asset_id}dalam daftarvideosobjekDemandGenVideoResponsiveAdInfosaat memanggilAdGroupAdService.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" } } } } } ] }
Buat kueri aset
YOUTUBE_VIDEOyang ada menggunakanGoogleAdsService.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}'
Update metadata
Anda dapat memperbarui setelan privasi video yang diupload melalui API ini menggunakan
metode UpdateYouTubeVideoUpload dengan update_mask
ditetapkan ke "video_privacy". Hanya kolom video_privacy (PUBLIC atau UNLISTED, untuk video yang diupload ke channel korporat milik pengiklan) yang dapat diperbarui setelah dibuat; video_title, video_description, channel_id, dan video_content_metadata tidak dapat diubah.
Menghapus upload
Jika Anda perlu menghapus video yang diupload dengan Google Ads API, teruskan nama resource
customers/{customer_id}/youTubeVideoUploads/{video_upload_id} mereka
di kolom resource_names metode
RemoveYouTubeVideoUpload. Tindakan ini akan menghapus video dari daftar aset Google Ads dan YouTube.