> For the complete documentation index, see [llms.txt](https://developers.oxylabs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.oxylabs.io/api-targets/cn/video-and-social-media/youtube/youtube-downloader.md).

# 下载器

通过视频 ID 下载 YouTube 音频和视频内容，可配置最高 8K 的视频质量，并直接交付至您的云存储。

该 `youtube_download` 该 source 提供您所选 YouTube 视频的音频/视频内容。请注意，由于数据量可能较大，此 source 仅可通过异步 [**Push-Pull 集成**](/products/cn/web-scraper-api/integration-methods/push-pull.md) 以及 [**云存储**](/products/cn/web-scraper-api/features/result-processing-and-storage/cloud-storage.md) 功能。

## YouTube Downloader 的工作原理

1. 通过 API 提交：
   * 一个或多个 YouTube 视频 ID；
   * 云存储详情。
2. 获取 API 响应，其中确认您的视频下载请求已成功接受。
3. 视频在我们的系统处理完成后，会立即上传到指定的云存储位置。

{% hint style="success" %}
**注意**:

* 下载器默认使用 720p 视频分辨率。如果 720p 不可用，下载器会选择低于 720p 的最佳可用画质。您可以使用以下内容覆盖此行为： `context: video_quality`参数一起使用时才有用。
* 您可以下载时长最长为 12 小时的视频。
* 下载时间限制为 1 小时。
  {% endhint %}

## 输入参数值

<table><thead><tr><th width="190">参数</th><th width="412">描述</th><th width="137">默认值</th></tr></thead><tbody><tr><td><mark style="background-color:green;"><strong><code>source</code></strong></mark></td><td>设置爬虫。使用 <code>youtube_download</code>.</td><td>–</td></tr><tr><td><mark style="background-color:green;"><strong><code>查询</code></strong></mark></td><td>YouTube 视频 ID。</td><td>–</td></tr><tr><td><mark style="background-color:green;"><strong><code>storage_type</code></strong></mark></td><td>云服务的存储类型（<code>gcs</code>, <code>s3</code> 或 <code>s3_compatible</code>)</td><td>–</td></tr><tr><td><mark style="background-color:green;"><strong><code>storage_url</code></strong></mark></td><td>您希望结果上传到的云存储位置的存储桶名称（用于 AWS S3）或 URL（用于其他兼容 S3 的存储）。</td><td>–</td></tr><tr><td><code>callback_url</code></td><td>您的回调端点 URL。 <a href="/products/cn/web-scraper-api/integration-methods/push-pull.md#callback"><strong>更多信息</strong></a></td><td>–</td></tr><tr><td><code>context:</code><br><code>download_type</code></td><td>指定是否下载 <code>audio</code>, <code>video</code>，或两者都下载 - <code>audio_video</code>.</td><td><code>audio_video</code></td></tr><tr><td><code>context:</code><br><code>video_quality</code></td><td>设置视频画质： <code>best</code>, <code>worst</code>，或指定分辨率： <code>144</code>, <code>360</code>, <code>480</code>, <code>720</code>, <code>1080</code>, <code>1440</code>, <code>2160</code>(4K)， <code>4320</code>(8K)。</td><td><code>720</code></td></tr><tr><td><code>context: audio_language</code></td><td>指定要下载的音轨。可接受 <code>default</code> 或 <code>original</code> （视频的原始音轨）。</td><td><code>default</code></td></tr><tr><td><code>context:</code><br><code>start_at</code></td><td>部分视频下载（剪辑）的起始时间戳，格式为 <code>hh:mm:ss</code> 格式。 <a href="#partial-download-trimming">了解更多</a>.</td><td>–</td></tr><tr><td><code>context:</code><br><code>end_at</code></td><td>部分视频下载（剪辑）的结束时间戳，格式为 <code>hh:mm:ss</code> 格式。必须晚于 <code>start_at</code>. <a href="#partial-download-trimming">了解更多</a>.</td><td>–</td></tr></tbody></table>

– 必填参数

## 提交单个任务

#### 端点

```
POST https://data.oxylabs.io/v1/queries
```

#### 输入

请按下方示例在 JSON 负载中提供任务参数：

{% tabs %}
{% tab title="cURL" %}

```sh
curl --user \"user:pass1\" \\
'https://data.oxylabs.io/v1/queries' \\
-H "Content-Type: application/json" \
-d '{
    \"source\": \"youtube_download\",
    \"query\": \"9cQBNYsCqQs\",
    \"storage_type\": \"s3\",
    \"storage_url\": \"s3://your-s3-bucket/your-folder/\"
}'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
from pprint import pprint

payload = {
    \"source\": \"youtube_download\",
    \"query\": \"9cQBNYsCqQs\",
    "context": [
        {
            \"key\": \"download_type\",
            \"value\": \"video\"
        },
        {
            \"key\": \"video_quality\",
            \"value\": \"1080\"
        }
    ],
    \"storage_type\": \"s3\",
    \"storage_url\": \"s3://your-s3-bucket/your-folder/\"
}

response = requests.request(
    'POST',
    'https://data.oxylabs.io/v1/queries',
    auth=('user', 'pass1'),
    json=payload,
)

pprint(response.json())
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$params = array(
    'source' => 'youtube_download',
    'query' => '9cQBNYsCqQs',
    \"context\" => [
        [
            \"key\" => \"download_type\",
            \"value\" => \"video\",
        ],
        [
            \"key\" => \"video_quality\",
            \"value\" => \"1080\",
        ]
    ],
    'storage_type' => 's3',
    'storage_url' => 's3://your-s3-bucket/your-folder/'
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "https://data.oxylabs.io/v1/queries");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, \"YOUR_USERNAME\" . \":\" . \"YOUR_PASSWORD\");

$headers = array();
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
echo $result;

if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
?>
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

namespace OxyApi
{
    class Program
    {
        static async Task Main()
        {
            const string Username = \"YOUR_USERNAME\";
            const string Password = \"YOUR_PASSWORD\";
            var payload = new Dictionary<string, object>()
            {
                { \"source\", \"youtube_download\" },
                { \"query\", \"9cQBNYsCqQs\" },
                { \"context\", new[] {
                    new { key = \"download_type\", value = \"video\" },
                    new { key = \"video_quality\", value = \"1080\" }
                }},
                { \"storage_type\", \"s3\" },
                { \"storage_url\", \"your-s3-bucket/your-folder/\" }
            };
            
            var client = new HttpClient();
            var requestMessage = new HttpRequestMessage(HttpMethod.Post, \"https://data.oxylabs.io/v1/queries/batch\");
            requestMessage.Content = JsonContent.Create(payload);
            
            var authenticationString = $"{Username}:{Password}";
            var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.UTF8.GetBytes(authenticationString));
            requestMessage.Headers.Add("Authorization", "Basic " + base64EncodedAuthenticationString);
            
            var response = await client.SendAsync(requestMessage);
            var contents = await response.Content.ReadAsStringAsync();
            Console.WriteLine(contents);
        }
    }
}
```

{% endtab %}

{% tab title="Golang" %}

```go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	const Username = \"YOUR_USERNAME\"
	const Password = \"YOUR_PASSWORD\"

	// Define the context structure
	type ContextItem struct {
		Key   string `json:\"key:\"`
		Value string `json:\"value:\"`
	}

	// Create payload with the same structure as the C# example
	payload := map[string]interface{}{
		\"source\": \"youtube_download\",
		\"query\":  []string{\"9cQBNYsCqQs\", \"KGOsWPF4Wfs\"},
		\"context\": []ContextItem{
			{Key: \"download_type\", Value: \"video\"},
			{Key: \"video_quality\", Value: \"1080\"},
		},
		\"storage_type\": \"s3\",
		\"storage_url\":  \"your-s3-bucket/your-folder/\",
	}

	jsonValue, _ := json.Marshal(payload)
	client := &http.Client{}
	request, _ := http.NewRequest("POST",
		\"https://data.oxylabs.io/v1/queries/batch\",
		bytes.NewBuffer(jsonValue),
	)
	request.Header.Add(\"Content-type\", \"application/json\")
	request.SetBasicAuth(Username, Password)
	response, _ := client.Do(request)
	responseText, _ := ioutil.ReadAll(response.Body)
	fmt.Println(string(responseText))
}
```

{% endtab %}

{% tab title="Java" %}

```java
package org.example;
import okhttp3.*;
import org.json.JSONArray;
import org.json.JSONObject;
public class Main implements Runnable {
    private static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String USERNAME = \"YOUR_USERNAME\";
    public static final String PASSWORD = \"YOUR_PASSWORD\";
    public void run() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(\"source\", \"youtube_download\");
        jsonObject.put(\"query\", \"9cQBNYsCqQs\");
        
        // Add context structure
        JSONArray contextArray = new JSONArray();
        
        JSONObject downloadTypeContext = new JSONObject();
        downloadTypeContext.put(\"key\", \"download_type\");
        downloadTypeContext.put(\"value\", \"video\");
        contextArray.put(downloadTypeContext);
        
        JSONObject videoQualityContext = new JSONObject();
        videoQualityContext.put(\"key\", \"video_quality\");
        videoQualityContext.put(\"value\", \"1080\");
        contextArray.put(videoQualityContext);
        
        jsonObject.put("context", contextArray);
        
        jsonObject.put(\"storage_type\", \"s3\");
        jsonObject.put(\"storage_url\", \"your-s3-bucket/your-folder/\");
        
        Authenticator authenticator = (route, response) => {
            String credential = Credentials.basic(USERNAME, PASSWORD);
            return response
                    .request()
                    .newBuilder()
                    .header(AUTHORIZATION_HEADER, credential)
                    .build();
        };
        var client = new OkHttpClient.Builder()
                .authenticator(authenticator)
                .build();
        var mediaType = MediaType.parse("application/json; charset=utf-8");
        var body = RequestBody.create(jsonObject.toString(), mediaType);
        var request = new Request.Builder()
                .url(\"https://data.oxylabs.io/v1/queries/batch\")
                .post(body)
                .build();
        try (var response = client.newCall(request).execute()) {
            assert response.body() != null;
            System.out.println(response.body().string());
        } catch (Exception exception) {
            System.out.println("Error: " + exception.getMessage());
        }
        System.exit(0);
    }
    public static void main(String[] args) {
        new Thread(new Main()).start();
    }
}
```

{% endtab %}

{% tab title="Node.js" %}

```sh
import fetch from 'node-fetch';

const username = 'YOUR_USERNAME';
const password = 'YOUR_PASSWORD';
const body = {
  source: 'youtube_download',
  query: '9cQBNYsCqQs',
  context: [
    { key: "download_type", value: "video" },
    { key: "video_quality", value: "1080"},
  ],
  storage_type: 's3',
  storage_url: 's3://your-s3-bucket/your-folder/'
};
const response = await fetch('https://data.oxylabs.io/v1/queries', {
  method: 'post',
  body: JSON.stringify(body),
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + Buffer.from(`${username}:${password}`).toString('base64'),
  }
});

console.log(await response.json());
```

{% endtab %}
{% endtabs %}

## 批量任务

您可以在单个批量请求中提交最多 5,000 个视频 ID。

#### 端点

```
POST https://data.oxylabs.io/v1/queries/batch
```

{% hint style="warning" %}
**重要：** 使用 `/batch` 在 /batch 端点，您只能提交以下内容的列表： `查询`参数值。其他所有参数应使用单个值。
{% endhint %}

#### 输入

{% tabs %}
{% tab title="cURL" %}

```sh
curl --user \"user:pass1\" \\
'https://data.oxylabs.io/v1/queries/batch' \\
-H 'Content-Type: application/json' \\
-d '{
    \"source\": \"youtube_download\",
    \"query\": [\"9cQBNYsCqQs\", \"KGOsWPF4Wfs\"],
        "context": [
        {
            \"key\": \"download_type\",
            \"value\": \"video\"
        },
        {
            \"key\": \"video_quality\",
            \"value\": \"1080\"
        }
    ],
    \"storage_type\": \"s3\",
    \"storage_url\": \"your-s3-bucket/your-folder/\"
}'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import json
from pprint import pprint

payload = {
    \"source\": \"youtube_download\",
    \"query\": [\"9cQBNYsCqQs\", \"KGOsWPF4Wfs\"],
    "context": [
        {
            \"key\": \"download_type\",
            \"value\": \"video\"
        },
        {
            \"key\": \"video_quality\",
            \"value\": \"1080\"
        }
    ],
    \"storage_type\": \"s3\",
    \"storage_url\": \"your-s3-bucket/your-folder/\"
}

response = requests.request(
    'POST',
    'https://data.oxylabs.io/v1/queries/batch',
    auth=('user', 'pass1'),
    json=payload,
)

# Print prettified response.
pprint(response.json())
```

{% endtab %}

{% tab title="PHP" %}

```php
<?php

$payload = array(
    \"source\" => \"youtube_download\",
    \"query\" => array(\"9cQBNYsCqQs\", \"KGOsWPF4Wfs\"),
    \"context\" => [
        [
            \"key\" => \"download_type\",
            \"value\" => \"video\",
        ],
        [
            \"key\" => \"video_quality\",
            \"value\" => \"1080\",
        ]
    ],
    \"storage_type\" => \"s3\",
    \"storage_url\" => \"your-s3-bucket/your-folder/\"
);

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, \"https://data.oxylabs.io/v1/queries/batch\");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_USERPWD, "user" . ":" . "pass1");

$headers = array();
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
echo $result;

if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
?>
```

{% endtab %}

{% tab title="C#" %}

```csharp
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;

namespace OxyApi
{
    class Program
    {
        static async Task Main()
        {
            const string Username = \"YOUR_USERNAME\";
            const string Password = \"YOUR_PASSWORD\";
            var payload = new Dictionary<string, object>()
            {
                { \"source\", \"youtube_download\" },
                { \"query\", new[] { \"9cQBNYsCqQs\", \"KGOsWPF4Wfs\" } },
                { \"context\", new[] {
                    new { key = \"download_type\", value = \"video\" },
                    new { key = \"video_quality\", value = \"1080\" }
                }},
                { \"storage_type\", \"s3\" },
                { \"storage_url\", \"your-s3-bucket/your-folder/\" }
            };
            
            var client = new HttpClient();
            var requestMessage = new HttpRequestMessage(HttpMethod.Post, \"https://data.oxylabs.io/v1/queries/batch\");
            requestMessage.Content = JsonContent.Create(payload);
            
            var authenticationString = $"{Username}:{Password}";
            var base64EncodedAuthenticationString = Convert.ToBase64String(System.Text.ASCIIEncoding.UTF8.GetBytes(authenticationString));
            requestMessage.Headers.Add("Authorization", "Basic " + base64EncodedAuthenticationString);
            
            var response = await client.SendAsync(requestMessage);
            var contents = await response.Content.ReadAsStringAsync();
            Console.WriteLine(contents);
        }
    }
}
```

{% endtab %}

{% tab title="Golang" %}

```go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	const Username = \"YOUR_USERNAME\"
	const Password = \"YOUR_PASSWORD\"

	// Define the context structure
	type ContextItem struct {
		Key   string `json:\"key:\"`
		Value string `json:\"value:\"`
	}

	// Create payload with the same structure as the C# example
	payload := map[string]interface{}{
		\"source\": \"youtube_download\",
		\"query\":  \"9cQBNYsCqQs\",
		\"context\": []ContextItem{
			{Key: \"download_type\", Value: \"video\"},
			{Key: \"video_quality\", Value: \"1080\"},
		},
		\"storage_type\": \"s3\",
		\"storage_url\":  \"your-s3-bucket/your-folder/\",
	}

	jsonValue, _ := json.Marshal(payload)
	client := &http.Client{}
	request, _ := http.NewRequest("POST",
		\"https://data.oxylabs.io/v1/queries/batch\",
		bytes.NewBuffer(jsonValue),
	)
	request.Header.Add(\"Content-type\", \"application/json\")
	request.SetBasicAuth(Username, Password)
	response, _ := client.Do(request)
	responseText, _ := ioutil.ReadAll(response.Body)
	fmt.Println(string(responseText))
}
```

{% endtab %}

{% tab title="Java" %}

```java
package org.example;
import okhttp3.*;
import org.json.JSONArray;
import org.json.JSONObject;
public class Main implements Runnable {
    private static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String USERNAME = \"YOUR_USERNAME\";
    public static final String PASSWORD = \"YOUR_PASSWORD\";
    public void run() {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(\"source\", \"youtube_download\");
        
        // Change query to array format like in C# example
        JSONArray queryArray = new JSONArray();
        queryArray.put(\"9cQBNYsCqQs\");
        queryArray.put(\"KGOsWPF4Wfs\");
        jsonObject.put(\"query\", queryArray);
        
        // Add context structure
        JSONArray contextArray = new JSONArray();
        
        JSONObject downloadTypeContext = new JSONObject();
        downloadTypeContext.put(\"key\", \"download_type\");
        downloadTypeContext.put(\"value\", \"video\");
        contextArray.put(downloadTypeContext);
        
        JSONObject videoQualityContext = new JSONObject();
        videoQualityContext.put(\"key\", \"video_quality\");
        videoQualityContext.put(\"value\", \"1080\");
        contextArray.put(videoQualityContext);
        
        jsonObject.put("context", contextArray);
        
        jsonObject.put(\"storage_type\", \"s3\");
        jsonObject.put(\"storage_url\", \"your-s3-bucket/your-folder/\");
        
        Authenticator authenticator = (route, response) => {
            String credential = Credentials.basic(USERNAME, PASSWORD);
            return response
                    .request()
                    .newBuilder()
                    .header(AUTHORIZATION_HEADER, credential)
                    .build();
        };
        var client = new OkHttpClient.Builder()
                .authenticator(authenticator)
                .build();
        var mediaType = MediaType.parse("application/json; charset=utf-8");
        var body = RequestBody.create(jsonObject.toString(), mediaType);
        var request = new Request.Builder()
                .url(\"https://data.oxylabs.io/v1/queries/batch\")
                .post(body)
                .build();
        try (var response = client.newCall(request).execute()) {
            assert response.body() != null;
            System.out.println(response.body().string());
        } catch (Exception exception) {
            System.out.println("Error: " + exception.getMessage());
        }
        System.exit(0);
    }
    public static void main(String[] args) {
        new Thread(new Main()).start();
    }
}
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
import fetch from 'node-fetch';

const username = 'YOUR_USERNAME';
const password = 'YOUR_PASSWORD';

const payload = {
    source: 'youtube_download',
    query: ['9cQBNYsCqQs', 'KGOsWPF4Wfs'],
      context: [
        { key: "download_type", value: "video" },
        { key: "video_quality", value: "1080"},
      ]
    storage_type: 's3',
    storage_url: 'your-s3-bucket/your-folder/'
};

const response = await fetch('https://data.oxylabs.io/v1/queries/batch', {
    method: 'post',
    body: JSON.stringify(payload),
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Basic ' + Buffer.from(`${username}:${password}`).toString('base64'),
    }
});

console.log(await response.json());
```

{% endtab %}
{% endtabs %}

API 将返回一个 JSON 对象，其中包含每个已创建任务的任务信息。任务状态将为 **`pending`** 直至下载完成。

## 检查任务状态

如果您提供了有效的 [**回调 URL**](/products/cn/web-scraper-api/integration-methods/push-pull.md#callback) 在提交任务时，我们会在完成后通过发送 `JSON` 负载到指定的回调 URL 来通知您。

不过，如果您提交任务时未使用 [**回调服务**](/products/cn/web-scraper-api/integration-methods/push-pull.md#callback)，您可以手动检查任务状态。请从响应中的 `href` 字段中获取 `rel:self` 任务提交后收到的响应消息部分获取。用于检查任务状态的 URL 将类似于以下内容： `http://data.oxylabs.io/v1/queries/12345678900987654321`. 查询此 URL 将返回任务信息，包括其当前 `status`.

### 端点 <a href="#endpoint-1" id="endpoint-1"></a>

```
GET https://data.oxylabs.io/v1/queries/{id}
```

## 部分下载（裁剪）

若要下载特定片段或剪辑，而不是完整视频，请在您的 `context` 数组中添加 2 个额外参数：

* `start_at` — 裁剪片段的起始时间戳，格式为 `hh:mm:ss` 格式。
* `end_at` — 裁剪片段的结束时间戳，格式为 `hh:mm:ss` 格式。

{% hint style="warning" %}
`end_at` 时间戳值必须晚于 `start_at`。仅支持 `hh:mm:ss` 格式。
{% endhint %}

```json
{
    \"source\": \"youtube_download\",
    \"query\": \"0xFXmJgVgzc\",
    "context": [
        {
            \"key\": \"start_at\",
            \"value\": \"00:01:30\"
        },
        {
            \"key\": \"end_at\",
            \"value\": \"00:05:45\"
        }
    ],
    \"storage_type\": \"s3\",
    \"storage_url\": \"s3://your-s3-bucket/your-folder/\"
}
```

{% hint style="info" %}
如果省略这两个参数，请求将按标准完整视频下载处理。
{% endhint %}

如果 `start_at` 或 `end_at` 未通过验证，则会返回 HTTP `400` 错误，并带有 `message` 字段。

<table><thead><tr><th width="271">条件</th><th>错误信息</th></tr></thead><tbody><tr><td><code>start_at</code> 不在 <code>hh:mm:ss</code> 格式中</td><td><code>context 中的 start_at 值无效。支持的格式：hh:mm:ss。</code></td></tr><tr><td><code>end_at</code> 不在 <code>hh:mm:ss</code> 格式中</td><td><code>context 中的 end_at 值无效。支持的格式：hh:mm:ss。</code></td></tr><tr><td><code>end_at</code> 不晚于 <code>start_at</code></td><td><code>context 中的 end_at 值无效。必须晚于 start_at。</code></td></tr></tbody></table>

## 云存储

您可以将 YouTube 视频交付到 [**Google Cloud Storage**](#google-cloud-storage-setup), [**Amazon S3**](#amazon-s3-setup), [**Alibaba Cloud OSS**](#alibaba-cloud-oss-setup)，或 [**其他兼容 S3 的云存储**](#s3-compatible-storage-setup).

内容文件将出现在您的云存储位置，并将按以下命名方案之一命名：

* `{video_id}_{job_id}.mp4` — 用于视频
* `{video_id}_{job_id}.m4a` — 用于音频

### 存储参数

<table><thead><tr><th width="170.03125">参数</th><th width="263.372304199773">描述</th><th>有效值</th></tr></thead><tbody><tr><td><code>storage_type</code></td><td>您的云存储类型。</td><td><p><code>gcs</code> (Google Cloud Storage);</p><p><code>s3</code> (AWS S3);<br><code>s3_compatible</code> （其他兼容 S3 的存储方案）。</p></td></tr><tr><td><code>storage_url</code></td><td>您的云存储 URL</td><td><p>任意 <code>s3</code> 或 <code>gcs</code> 存储桶名称；</p><p>任意 <code>兼容 S3 的</code> 存储 URL。</p></td></tr></tbody></table>

### **Google Cloud Storage 设置** <a href="#google-cloud-storage-setup" id="google-cloud-storage-setup"></a>

要将任务结果上传到您的 Google Cloud Storage 存储桶，请 **为我们的服务设置特殊权限** ，如我们的 [Google Cloud Storage documentation](/products/cn/web-scraper-api/features/result-processing-and-storage/cloud-storage.md#google-cloud-storage).

```json
{
    \"source\": \"youtube_download\",
    \"query\": \"9cQBNYsCqQs\",
    "storage_type": "gcs",
    "storage_url": "bucket_name/path"
}
```

### Amazon S3 设置

要将任务结果上传到您的 Amazon S3 存储桶，请为我们的服务设置访问权限。为此，请转到 [**https://s3.console.aws.amazon.com/**](https://s3.console.aws.amazon.com/) → **`S3`** → **`存储`** → **`存储桶名称`**` `` ``（如果你没有，请创建一个新的） ` → **`权限`** → **`存储桶策略`**。您可以在我们的 [Amazon S3 cloud documentation](/products/cn/web-scraper-api/features/result-processing-and-storage/cloud-storage.md#amazon-s3).

请使用下面的存储桶策略（别忘了将下方的存储桶名称替换为 `YOUR_BUCKET_NAME`):

```json
{
    "Version": "2012-10-17",
    "Id": "Policy1577442634787",
    "Statement": [
        {
            "Sid": "Stmt1577442633719",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::324311890426:user/oxylabs.s3.uploader"
            },
            "Action": "s3:GetBucketLocation",
            "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME"
        },
        {
            "Sid": "Stmt1577442633719",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::324311890426:user/oxylabs.s3.uploader"
            },
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::YOUR_BUCKET_NAME/*"
        }
    ]
}
```

此策略允许我们向您的存储桶写入、让您访问已上传的文件，并识别存储桶位置。

### Alibaba Cloud OSS 设置

要将结果保存到您的 Alibaba Cloud Object Storage Service (OSS)，您必须创建 `ACCESS_KEY_ID` 和 `ACCESS_KEY_SECRET` 并使用它们来构建存储 URL。请按照我们的 [Alibaba Cloud OSS documentation ](/products/cn/web-scraper-api/features/result-processing-and-storage/cloud-storage.md#alibaba-cloud-object-storage-service-oss).

```json
{
    \"source\": \"youtube_download\",
    \"query\": \"9cQBNYsCqQs\",
    "storage_type": "s3_compatible",
    "storage_url": "https://ACCESS_KEY_ID:ACCESS_KEY_SECRET@BUCKET_NAME.oss-REGION.aliyuncs.com/FOLDER_NAME"
}
```

### 兼容 S3 的存储设置

如果您希望将结果交付到 [其他兼容 S3 的存储](/products/cn/web-scraper-api/features/result-processing-and-storage/cloud-storage.md#other-s3-compatible-storage) 位置，您需要包含存储桶的 `ACCESS_KEY:SECRET` 认证字符串到 `storage_url` 负载中的值中：

```json
{
    \"source\": \"youtube_download\",
    \"query\": \"9cQBNYsCqQs\",
    "storage_type": "s3_compatible",
    "storage_url": "https://ACCESS_KEY:SECRET@s3.oxylabs.io/my-videos"
}
```

## 错误代码

<table><thead><tr><th width="170.03125">代码</th><th width="263.372304199773">状态</th><th>描述</th></tr></thead><tbody><tr><td><code>11201</code></td><td><code>VIDEO_DELETED</code></td><td>视频已删除。</td></tr><tr><td><code>11202</code></td><td><code>VIDEO_UNAVAILABLE</code></td><td>视频不可用。</td></tr><tr><td><code>11203</code></td><td><code>VIDEO_PRIVATE</code></td><td>视频已由上传者设为私有，只有上传者和被明确邀请的人可以查看。</td></tr><tr><td><code>11204</code></td><td><code>VIDEO_GEO_RESTRICTED</code></td><td>视频受地区限制。</td></tr><tr><td><code>11205</code></td><td><code>VIDEO_LIVE</code></td><td>视频正在直播。</td></tr><tr><td><code>11206</code></td><td><code>VIDEO_AGE_RESTRICTED</code></td><td>视频有年龄限制。</td></tr><tr><td><code>11207</code></td><td><code>VIDEO_MEMBER_ONLY</code></td><td>视频仅限频道会员观看，观看者需要支付每月订阅费。</td></tr><tr><td><code>11208</code></td><td><code>VIDEO_PREMIUM_ONLY</code></td><td>视频需要 YouTube Premium 订阅。</td></tr><tr><td><code>11209</code></td><td><code>VIDEO_LIVE_OR_TOO_LONG</code></td><td>视频正在直播，或时长过长，无法下载。</td></tr><tr><td><code>11210</code></td><td><code>VIDEO_TOO_LONG</code></td><td>视频过长，无法下载。</td></tr><tr><td><code>11211</code></td><td><code>VIDEO_SIGN_IN_REQUIRED</code></td><td>需要登录。</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://developers.oxylabs.io/api-targets/cn/video-and-social-media/youtube/youtube-downloader.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
