# Descargador

El `youtube_download` la fuente entrega el contenido de audio/video de un video de YouTube de tu elección. Ten en cuenta que, debido al volumen de datos potencialmente grande, esta fuente solo está disponible a través de la integración asincrónica [**Push-Pull integration**](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/web-scraper-api/integration-methods/push-pull) y la [**Cloud Storage**](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/web-scraper-api/features/result-processing-and-storage/cloud-storage) función.

## Cómo funciona YouTube Downloader

1. Enviar vía API:
   * Uno o más IDs de videos de YouTube;
   * Detalles del almacenamiento en la nube.
2. Obtén la respuesta de la API con la confirmación de que tu solicitud para descargar un video ha sido aceptada con éxito.
3. Obtén los videos en la ubicación de almacenamiento en la nube especificada tan pronto como sean procesados por nuestro sistema.

{% hint style="success" %}
**Nota**:

* El descargador usa por defecto resolución de video 720p. Si 720p no está disponible, el descargador elegirá la mejor calidad disponible por debajo de 720p. Puedes anular este comportamiento usando el `context: video_quality`parámetro.
* Puedes descargar videos de hasta 12 horas de duración.
* El tiempo de descarga está limitado a 1 hora.
  {% endhint %}

## Valores de los parámetros de entrada

| Parámetro                                                   | Descripción                                                                                                                                                      | Valor por defecto  |
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ |
| `source`                                                    | Define el scraper.                                                                                                                                               | `youtube_download` |
| `query`                                                     | ID del video de YouTube.                                                                                                                                         | -                  |
| `storage_type`                                              | Tipo de almacenamiento del servicio en la nube (`gcs`, `s3` o `s3_compatible`)                                                                                   | -                  |
| `storage_url`                                               | El nombre del bucket (para AWS S3) o la URL (para otros almacenamientos compatibles con S3) de la ubicación en la nube a la que deseas que se suba el resultado. | -                  |
| `callback_url`                                              | La URL de tu endpoint de callback. [**Más info**](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/integration-methods/push-pull#callback)  | -                  |
| <p><code>context:</code><br><code>download\_type</code></p> | Especifica si descargar `audio`, `video`, o ambos - `audio_video`.                                                                                               | `audio_video`      |
| <p><code>context:</code><br><code>video\_quality</code></p> | Establece la calidad de video: `best`, `worst`, o una resolución -  `480`, `720`, `1080`, `1440`, `2160(4K)`.                                                    | `720`              |

## Envío de un solo trabajo

#### Endpoint

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

#### Entrada

Proporciona los parámetros del trabajo en una carga JSON como se muestra en el ejemplo a continuación:

{% 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 %}

## Trabajo por lotes

Puedes enviar hasta 5.000 IDs de videos dentro de una sola solicitud por lote.

#### Endpoint

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

{% hint style="warning" %}
**IMPORTANTE:** Con `/batch` endpoint, solo puedes enviar listas de `query`valores de parámetros. Todos los demás parámetros deben tener valores singulares.
{% endhint %}

#### Entrada

{% 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,
)

# Imprimir respuesta formateada.
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");
        
        // Cambia query a formato array como en el ejemplo de C#
        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 %}

La API responderá con un objeto JSON, que contiene la información del trabajo para cada trabajo creado. El estado del trabajo estará **`pending`** hasta que la descarga se complete.

## Comprobando el estado del trabajo

Si proporcionaste una [**callback URL**](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/integration-methods/push-pull#callback) al enviar tu trabajo, te notificaremos al completarlo enviando una `JSON` carga útil al URL de callback especificado.&#x20;

Sin embargo, si enviaste un trabajo sin usar [**callback service**](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/integration-methods/push-pull#callback), puedes verificar el estado del trabajo manualmente. Recupera la URL del `href` campo en la `rel:self` sección del mensaje de respuesta recibido después del envío del trabajo. La URL para comprobar el estado del trabajo se parecerá a la siguiente: `http://data.oxylabs.io/v1/queries/12345678900987654321`. Consultar esta URL devolverá la información del trabajo, incluido su `status`.

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

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

## Almacenamiento en la nube

Puedes recibir tus videos de YouTube entregados a [**Google Cloud Storage**](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/features/result-processing-and-storage/cloud-storage#google-cloud-storage), [**Amazon S3**](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/features/result-processing-and-storage/cloud-storage#amazon-s3), [**Alibaba OSS**](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/features/result-processing-and-storage/cloud-storage#alibaba-cloud-object-storage-service-oss), o [**otros almacenamientos compatibles con S3**](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/features/result-processing-and-storage/cloud-storage#other-s3-compatible-storage).

Los archivos de contenido aparecerán en tu ubicación de almacenamiento en la nube y serán nombrados según uno de los siguientes esquemas de nombres:

* `{video_id}_{job_id}.mp4` – para video
* `{video_id}_{job_id}.m4a` – para audio

### Parámetros de almacenamiento

<table><thead><tr><th width="170.03125">Parámetro</th><th width="263.372304199773">Descripción</th><th>Valores válidos</th></tr></thead><tbody><tr><td><code>storage_type</code></td><td>Tu tipo de almacenamiento en la nube.</td><td><p><code>gcs</code> (Google Cloud Storage);</p><p><code>s3</code> (AWS S3);<br><code>s3_compatible</code> (otras soluciones de almacenamiento compatibles con S3).</p></td></tr><tr><td><code>storage_url</code></td><td>La URL de tu almacenamiento en la nube</td><td><p>Cualquier <code>s3</code> o <code>gcs</code> nombre de bucket;</p><p>Cualquier <code>s3-compatible</code> URL de almacenamiento.</p></td></tr></tbody></table>

### **Configuración de Google Cloud Storage** <a href="#google-cloud-storage-setup" id="google-cloud-storage-setup"></a>

Para que los resultados de tu trabajo se suban a tu bucket de Google Cloud Storage, por favor **configura permisos especiales para nuestro servicio** como se muestra en nuestra [Google Cloud Storage documentation](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/features/result-processing-and-storage/cloud-storage#google-cloud-storage).

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

### Configuración de Amazon S3

Para que los resultados de tu trabajo se suban a tu bucket de Amazon S3, por favor configura permisos de acceso para nuestro servicio. Para ello, ve a [**https://s3.console.aws.amazon.com/**](https://s3.console.aws.amazon.com/) → **`S3`** → **`Storage`** → **`Nombre del bucket`**` ``(si no tienes uno, crea uno nuevo)` → **`Permisos`** → **`Política del bucket`**.

Usa la política del bucket a continuación (no olvides cambiar el nombre del bucket bajo `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/*"
        }
    ]
}
```

Esta política nos permite escribir en tu bucket, darte acceso a los archivos subidos y conocer la ubicación del bucket.

### Configuración de Alibaba Cloud OSS

Para guardar resultados en tu Alibaba Cloud Object Storage Service (OSS), debes crear el `ACCESS_KEY_ID` y `ACCESS_KEY_SECRET` y usarlos para formar la URL de almacenamiento. Sigue las instrucciones descritas en nuestra [Alibaba Cloud OSS documentation ](https://developers.oxylabs.io/documentation/es/soluciones-de-scraping/features/result-processing-and-storage/cloud-storage#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"
}
```

### Configuración de almacenamiento compatible con S3

Si deseas que tus resultados se entreguen a otra ubicación de almacenamiento compatible con S3, deberás incluir la `ACCESS_KEY:SECRET` cadena de autenticación en el `storage_url` valor en la carga:

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