Skip to main content
The Downloader class is an abstract base class that NewPipe Extractor uses to download resources from streaming services. Implementations must provide the HTTP client logic while the base class provides convenient methods for common request patterns.

Overview

The Downloader handles all HTTP communication with streaming services, supporting GET, HEAD, and POST requests with automatic localization header management. It works in conjunction with Request and Response objects to provide a clean API for HTTP operations.

Abstract Method

execute

request
Request
required
The request object containing URL, method, headers, and optional data
Response
Response
The response object containing status code, headers, and body
Executes a request using the specified Request object. Implementations must override this method to provide the actual HTTP client logic.
public abstract Response execute(@Nonnull Request request)
        throws IOException, ReCaptchaException;
Throws:
  • IOException - If a network error occurs
  • ReCaptchaException - If the service requires CAPTCHA verification

GET Requests

get(String url)

url
String
required
The URL pointing to the wanted resource
Response
Response
The result of the GET request
Performs a GET request using the default preferred localization. Only use this when the resource won’t be affected by localization.
Response response = downloader.get("https://example.com/api/data");

get(String url, Localization localization)

url
String
required
The URL pointing to the wanted resource
localization
Localization
required
Source of the Accept-Language header value
Response
Response
The result of the GET request
Performs a GET request with the specified localization. Sets the Accept-Language header automatically.
Localization locale = new Localization("en", "US");
Response response = downloader.get(url, locale);

get(String url, Map headers)

url
String
required
The URL pointing to the wanted resource
headers
Map<String, List<String>>
Headers to use in the request (overrides defaults)
Response
Response
The result of the GET request
Performs a GET request with custom headers using the default localization.
Map<String, List<String>> headers = new HashMap<>();
headers.put("User-Agent", Collections.singletonList("CustomAgent/1.0"));
Response response = downloader.get(url, headers);

get(String url, Map headers, Localization localization)

url
String
required
The URL pointing to the wanted resource
headers
Map<String, List<String>>
Headers to use in the request (overrides defaults)
localization
Localization
required
Source of the Accept-Language header value
Response
Response
The result of the GET request
Performs a GET request with custom headers and localization. This is the most flexible GET method.
Map<String, List<String>> headers = new HashMap<>();
headers.put("Authorization", Collections.singletonList("Bearer token"));
Localization locale = new Localization("fr", "FR");
Response response = downloader.get(url, headers, locale);

HEAD Requests

head(String url)

url
String
required
The URL pointing to the wanted resource
Response
Response
The result of the HEAD request
Performs a HEAD request to retrieve headers without downloading the body.
Response response = downloader.head(url);
String contentType = response.getHeader("Content-Type");

head(String url, Map headers)

url
String
required
The URL pointing to the wanted resource
headers
Map<String, List<String>>
Headers to use in the request (overrides defaults)
Response
Response
The result of the HEAD request
Performs a HEAD request with custom headers.
Map<String, List<String>> headers = new HashMap<>();
headers.put("Range", Collections.singletonList("bytes=0-1023"));
Response response = downloader.head(url, headers);

POST Requests

post(String url, Map headers, byte[] dataToSend)

url
String
required
The URL pointing to the wanted resource
headers
Map<String, List<String>>
Headers to use in the request (overrides defaults)
dataToSend
byte[]
Byte array to send in the request body
Response
Response
The result of the POST request
Performs a POST request with the default localization.
byte[] data = "{\"key\":\"value\"}".getBytes(StandardCharsets.UTF_8);
Response response = downloader.post(url, null, data);

post(String url, Map headers, byte[] dataToSend, Localization localization)

url
String
required
The URL pointing to the wanted resource
headers
Map<String, List<String>>
Headers to use in the request (overrides defaults)
dataToSend
byte[]
Byte array to send in the request body
localization
Localization
required
Source of the Accept-Language header value
Response
Response
The result of the POST request
Performs a POST request with custom localization and sets the Accept-Language header.

postWithContentType

url
String
required
The URL pointing to the wanted resource
headers
Map<String, List<String>>
Headers to use in the request (overrides defaults)
dataToSend
byte[]
Byte array to send in the request body
contentType
String
required
MIME type to set as the Content-Type header value
Response
Response
The result of the POST request
Convenient method to send a POST request with a specific Content-Type header. Automatically adds the Content-Type to the headers.
byte[] xmlData = "<root><item>value</item></root>".getBytes();
Response response = downloader.postWithContentType(
    url, null, xmlData, "application/xml"
);
With localization:
Localization locale = new Localization("de", "DE");
Response response = downloader.postWithContentType(
    url, null, data, locale, "application/xml"
);

postWithContentTypeJson

url
String
required
The URL pointing to the wanted resource
headers
Map<String, List<String>>
Headers to use in the request (overrides defaults)
dataToSend
byte[]
Byte array to send in the request body
Response
Response
The result of the POST request
Convenient method to send a POST request with Content-Type: application/json. This is a specialized version of postWithContentType.
byte[] jsonData = "{\"query\":\"search term\"}".getBytes(StandardCharsets.UTF_8);
Response response = downloader.postWithContentTypeJson(url, null, jsonData);
With localization:
Localization locale = new Localization("ja", "JP");
Response response = downloader.postWithContentTypeJson(
    url, null, jsonData, locale
);

Request Object

The Request class encapsulates all request parameters. Use the builder pattern to create requests:
Request request = Request.newBuilder()
    .get(url)
    .localization(new Localization("en", "US"))
    .setHeader("Custom-Header", "value")
    .build();

Response response = downloader.execute(request);

Request Properties

httpMethod
String
HTTP method (GET, POST, HEAD)
url
String
Target URL for the request
headers
Map<String, List<String>>
Request headers (overrides defaults)
dataToSend
byte[]
Optional data to send in request body
localization
Localization
Localization for Accept-Language header

Request Builder Methods

Response Object

The Response class contains the results of an HTTP request:
Response response = downloader.get(url);
int status = response.responseCode();
String body = response.responseBody();
String contentType = response.getHeader("Content-Type");

Response Properties

responseCode
int
HTTP status code (e.g., 200, 404, 500)
responseMessage
String
HTTP status message (e.g., “OK”, “Not Found”)
responseHeaders
Map<String, List<String>>
All response headers
responseBody
String
Response body as a string (empty string if null)
latestUrl
String
The final URL after any redirects

Response Methods

Example Implementation

import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.downloader.Request;
import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;

import java.io.IOException;

public class CustomDownloader extends Downloader {
    private final HttpClient client;
    
    public CustomDownloader(HttpClient client) {
        this.client = client;
    }
    
    @Override
    public Response execute(@Nonnull Request request) 
            throws IOException, ReCaptchaException {
        // Build HTTP request from Request object
        HttpRequest httpRequest = HttpRequest.newBuilder()
            .uri(URI.create(request.url()))
            .method(request.httpMethod(), 
                   request.dataToSend() != null 
                       ? BodyPublishers.ofByteArray(request.dataToSend())
                       : BodyPublishers.noBody())
            .build();
            
        // Add headers
        request.headers().forEach((name, values) -> {
            values.forEach(value -> 
                httpRequest.headers().add(name, value));
        });
        
        // Execute request
        HttpResponse<String> httpResponse = 
            client.send(httpRequest, BodyHandlers.ofString());
            
        // Check for CAPTCHA
        if (httpResponse.statusCode() == 429) {
            throw new ReCaptchaException("CAPTCHA required", 
                                        request.url());
        }
        
        // Build Response object
        return new Response(
            httpResponse.statusCode(),
            httpResponse.headers().firstValue(":status")
                .orElse("Unknown"),
            httpResponse.headers().map(),
            httpResponse.body(),
            httpResponse.uri().toString()
        );
    }
}

Usage in Extractors

// In a service extractor
public class YouTubeExtractor {
    private final Downloader downloader;
    
    public String fetchChannelData(String channelId) 
            throws IOException, ExtractionException {
        String url = "https://youtube.com/channel/" + channelId;
        
        // Simple GET request
        Response response = downloader.get(url);
        
        // With localization
        Localization locale = new Localization("en", "US");
        response = downloader.get(url, locale);
        
        // POST with JSON
        String jsonBody = buildApiRequest(channelId);
        byte[] data = jsonBody.getBytes(StandardCharsets.UTF_8);
        response = downloader.postWithContentTypeJson(
            "https://youtube.com/youtubei/v1/browse",
            null,
            data
        );
        
        return response.responseBody();
    }
}
  • Localization - For setting language and country preferences
  • Exceptions - Error handling including ReCaptchaException

Build docs developers (and LLMs) love