Erstes Video herunterladen
Senden Sie eine Video-URL, fragen Sie das asynchrone Job-Ergebnis ab und speichern Sie die Datei lokal — vollständige End-to-End-Anleitung mit dem HuntAPI Video-Downloader.
Übersicht
HuntAPI verwendet ein asynchrones Job-Modell: Sie senden eine URL, erhalten eine job_id und fragen dann ab, bis das Video fertig ist. Dieses Playbook führt durch alle drei Schritte und lädt die fertige Datei auf die Festplatte.
Voraussetzungen
- Einen HuntAPI-Schlüssel — erhalten Sie einen auf app.huntapi.com
- Installieren Sie die Abhängigkeiten für Ihre Sprache:
pip install requestsKeine zusätzlichen Abhängigkeiten — verwendet die native fetch-API (Node 18+).
curl-Erweiterung aktiviert (standardmäßig).
Keine zusätzlichen Abhängigkeiten — verwendet net/http (Go 1.18+).
Keine zusätzlichen Abhängigkeiten — verwendet java.net.http (Java 11+).
Keine zusätzlichen Abhängigkeiten — verwendet System.Net.Http (.NET 6+).
# Cargo.toml
[dependencies]
reqwest = { version = "0.12", features = ["json", "stream"] }
tokio = { version = "1", features = ["full"] }
serde_json = "1"Schritte
Download-Job einreichen
Rufen Sie GET /v1/video/download mit dem Parameter url auf. Die Antwort gibt sofort eine job_id zurück.
import requests
API_KEY = "YOUR_API_KEY"
VIDEO_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
response = requests.get(
"https://api.huntapi.com/v1/video/download",
headers={"x-api-key": API_KEY},
params={"url": VIDEO_URL, "quality": "best"},
)
data = response.json()
job_id = data["job_id"]
print(f"Job eingereicht: {job_id}")const API_KEY = "YOUR_API_KEY";
const VIDEO_URL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ";
const params = new URLSearchParams({ url: VIDEO_URL, quality: "best" });
const response = await fetch(`https://api.huntapi.com/v1/video/download?${params}`, {
headers: { "x-api-key": API_KEY },
});
const data = await response.json();
const jobId = data.job_id;
console.log(`Job eingereicht: ${jobId}`);<?php
$apiKey = "YOUR_API_KEY";
$videoUrl = "https://www.youtube.com/watch?v=dQw4w9WgXcQ";
$params = http_build_query(["url" => $videoUrl, "quality" => "best"]);
$ch = curl_init("https://api.huntapi.com/v1/video/download?{$params}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-api-key: {$apiKey}"]);
$data = json_decode(curl_exec($ch), true);
curl_close($ch);
$jobId = $data["job_id"];
echo "Job eingereicht: {$jobId}\n";package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
const APIKey = "YOUR_API_KEY"
const VideoURL = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
func main() {
params := url.Values{"url": {VideoURL}, "quality": {"best"}}
req, _ := http.NewRequest("GET", "https://api.huntapi.com/v1/video/download?"+params.Encode(), nil)
req.Header.Set("x-api-key", APIKey)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var data map[string]any
json.Unmarshal(body, &data)
jobID := data["job_id"].(string)
fmt.Println("Job eingereicht:", jobID)
}import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import org.json.*;
var apiKey = "YOUR_API_KEY";
var videoUrl = URLEncoder.encode("https://www.youtube.com/watch?v=dQw4w9WgXcQ", StandardCharsets.UTF_8);
var url = "https://api.huntapi.com/v1/video/download?url=" + videoUrl + "&quality=best";
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder().uri(URI.create(url))
.header("x-api-key", apiKey).GET().build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
var jobId = new JSONObject(response.body()).getString("job_id");
System.out.println("Job eingereicht: " + jobId);using System.Net.Http;
using System.Text.Json;
var apiKey = "YOUR_API_KEY";
var videoUrl = Uri.EscapeDataString("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key", apiKey);
var body = await client.GetStringAsync($"https://api.huntapi.com/v1/video/download?url={videoUrl}&quality=best");
var jobId = JsonDocument.Parse(body).RootElement.GetProperty("job_id").GetString()!;
Console.WriteLine($"Job eingereicht: {jobId}");use reqwest::Client;
use serde_json::Value;
let client = Client::new();
let api_key = "YOUR_API_KEY";
let video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ";
let data = client.get("https://api.huntapi.com/v1/video/download")
.header("x-api-key", api_key)
.query(&[("url", video_url), ("quality", "best")])
.send().await?.json::<Value>().await?;
let job_id = data["job_id"].as_str().unwrap();
println!("Job eingereicht: {}", job_id);Auf das fertige Video warten (Polling)
Überprüfen Sie GET /v1/job/{job_id} alle paar Sekunden. Wenn status zu "done" wird, enthält das Feld download_url die Datei-URL.
import time
def wait_for_job(job_id: str, poll_interval: int = 5, timeout: int = 300) -> dict:
start = time.time()
while time.time() - start < timeout:
r = requests.get(f"https://api.huntapi.com/v1/job/{job_id}",
headers={"x-api-key": API_KEY})
result = r.json()
status = result.get("status")
print(f" Status: {status}")
if status == "done":
return result
if status == "error":
raise RuntimeError(f"Job fehlgeschlagen: {result.get('error')}")
time.sleep(poll_interval)
raise TimeoutError("Job wurde nicht innerhalb des Timeout abgeschlossen.")
result = wait_for_job(job_id)
download_url = result["download_url"]
print(f"Bereit! Download-URL: {download_url}")async function waitForJob(jobId: string, pollMs = 5000, timeoutMs = 300_000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const res = await fetch(`https://api.huntapi.com/v1/job/${jobId}`, {
headers: { "x-api-key": API_KEY },
});
const result = await res.json();
console.log(` Status: ${result.status}`);
if (result.status === "done") return result;
if (result.status === "error") throw new Error(`Job fehlgeschlagen: ${result.error}`);
await new Promise(r => setTimeout(r, pollMs));
}
throw new Error("Timeout");
}
const result = await waitForJob(jobId);
const downloadUrl = result.download_url;
console.log(`Bereit! Download-URL: ${downloadUrl}`);function waitForJob(string $apiKey, string $jobId, int $pollSec = 5, int $timeoutSec = 300): array {
$start = time();
while (time() - $start < $timeoutSec) {
$ch = curl_init("https://api.huntapi.com/v1/job/{$jobId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["x-api-key: {$apiKey}"]);
$result = json_decode(curl_exec($ch), true);
curl_close($ch);
$status = $result["status"] ?? "";
echo " Status: {$status}\n";
if ($status === "done") return $result;
if ($status === "error") throw new RuntimeException("Job fehlgeschlagen: " . ($result["error"] ?? ""));
sleep($pollSec);
}
throw new RuntimeException("Timeout");
}
$result = waitForJob($apiKey, $jobId);
$downloadUrl = $result["download_url"];
echo "Bereit! Download-URL: {$downloadUrl}\n";import "time"
func waitForJob(apiKey, jobID string) (map[string]any, error) {
deadline := time.Now().Add(5 * time.Minute)
for time.Now().Before(deadline) {
req, _ := http.NewRequest("GET", "https://api.huntapi.com/v1/job/"+jobID, nil)
req.Header.Set("x-api-key", apiKey)
resp, _ := http.DefaultClient.Do(req)
body, _ := io.ReadAll(resp.Body)
resp.Body.Close()
var result map[string]any
json.Unmarshal(body, &result)
status := result["status"].(string)
fmt.Println(" Status:", status)
if status == "done" { return result, nil }
if status == "error" { return nil, fmt.Errorf("Job fehlgeschlagen: %v", result["error"]) }
time.Sleep(5 * time.Second)
}
return nil, fmt.Errorf("Timeout")
}
result, err := waitForJob(APIKey, jobID)
if err != nil { panic(err) }
downloadURL := result["download_url"].(string)
fmt.Println("Bereit! Download-URL:", downloadURL)import java.time.*;
static JSONObject waitForJob(HttpClient client, String apiKey, String jobId) throws Exception {
var deadline = Instant.now().plusSeconds(300);
while (Instant.now().isBefore(deadline)) {
var req = HttpRequest.newBuilder()
.uri(URI.create("https://api.huntapi.com/v1/job/" + jobId))
.header("x-api-key", apiKey).GET().build();
var resp = client.send(req, HttpResponse.BodyHandlers.ofString());
var result = new JSONObject(resp.body());
var status = result.getString("status");
System.out.println(" Status: " + status);
if ("done".equals(status)) return result;
if ("error".equals(status)) throw new RuntimeException("Job fehlgeschlagen: " + result.optString("error"));
Thread.sleep(5000);
}
throw new RuntimeException("Timeout");
}
var result = waitForJob(client, apiKey, jobId);
var downloadUrl = result.getString("download_url");
System.out.println("Bereit! Download-URL: " + downloadUrl);async Task<JsonElement> WaitForJob(HttpClient client, string jobId)
{
var deadline = DateTime.UtcNow.AddMinutes(5);
while (DateTime.UtcNow < deadline)
{
var body = await client.GetStringAsync($"https://api.huntapi.com/v1/job/{jobId}");
var result = JsonDocument.Parse(body).RootElement;
var status = result.GetProperty("status").GetString();
Console.WriteLine($" Status: {status}");
if (status == "done") return result;
if (status == "error") throw new Exception($"Job fehlgeschlagen: {result.GetProperty("error")}");
await Task.Delay(5000);
}
throw new TimeoutException("Job nicht rechtzeitig abgeschlossen.");
}
var result = await WaitForJob(client, jobId);
var downloadUrl = result.GetProperty("download_url").GetString()!;
Console.WriteLine($"Bereit! Download-URL: {downloadUrl}");use tokio::time::{sleep, Duration};
use std::time::Instant;
async fn wait_for_job(client: &Client, api_key: &str, job_id: &str) -> Value {
let deadline = Instant::now() + Duration::from_secs(300);
loop {
assert!(Instant::now() < deadline, "Timeout");
let result = client.get(format!("https://api.huntapi.com/v1/job/{}", job_id))
.header("x-api-key", api_key)
.send().await.unwrap().json::<Value>().await.unwrap();
let status = result["status"].as_str().unwrap_or("");
println!(" Status: {}", status);
if status == "done" { return result; }
if status == "error" { panic!("Job fehlgeschlagen: {}", result["error"]); }
sleep(Duration::from_secs(5)).await;
}
}
let result = wait_for_job(&client, api_key, job_id).await;
let download_url = result["download_url"].as_str().unwrap();
println!("Bereit! Download-URL: {}", download_url);Videodatei auf die Festplatte herunterladen
Streamen Sie die Datei von der download_url und speichern Sie sie lokal.
filename = "video.mp4"
with requests.get(download_url, stream=True) as r:
r.raise_for_status()
with open(filename, "wb") as f:
for chunk in r.iter_content(chunk_size=8192):
f.write(chunk)
print(f"Gespeichert als {filename}")import { createWriteStream } from "fs";
import { Readable } from "stream";
const fileResponse = await fetch(downloadUrl);
const writer = createWriteStream("video.mp4");
Readable.fromWeb(fileResponse.body as any).pipe(writer);
await new Promise((resolve, reject) => { writer.on("finish", resolve); writer.on("error", reject); });
console.log("Gespeichert als video.mp4");$fp = fopen("video.mp4", "wb");
$ch = curl_init($downloadUrl);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
fclose($fp);
echo "Gespeichert als video.mp4\n";import "os"
resp, _ := http.Get(downloadURL)
defer resp.Body.Close()
file, _ := os.Create("video.mp4")
defer file.Close()
io.Copy(file, resp.Body)
fmt.Println("Gespeichert als video.mp4")import java.nio.file.*;
import java.net.URL;
var in = new URL(downloadUrl).openStream();
Files.copy(in, Path.of("video.mp4"), StandardCopyOption.REPLACE_EXISTING);
System.out.println("Gespeichert als video.mp4");using var fileStream = File.Create("video.mp4");
using var download = await new HttpClient().GetStreamAsync(downloadUrl);
await download.CopyToAsync(fileStream);
Console.WriteLine("Gespeichert als video.mp4");use std::io::Write;
use std::fs::File;
let bytes = reqwest::get(download_url).await?.bytes().await?;
let mut file = File::create("video.mp4").unwrap();
file.write_all(&bytes).unwrap();
println!("Gespeichert als video.mp4");Sie können quality: "best", "1080p", "720p" oder "audio" in der Anfrage übergeben, um das Ausgabeformat zu steuern, bevor der Job eingereicht wird.
Model Context Protocol
Verbinden Sie HuntAPI mit Claude Code, Cursor, Gemini CLI, OpenAI Developer Mode und anderen MCP-Clients über Ihren API-Schlüssel.
Audio aus einem Video extrahieren
Laden Sie nur die Audiospur einer beliebigen Video-URL als MP3-Datei mit HuntAPI herunter — ideal für Podcast-Archivierung, Transkriptions-Pipelines oder Content-Repurposing.