# YouTube Video Downloader - MP4 & MP3, Channels & Playlists (`mrdoe/youtube-video-downloader`) Actor

Download YouTube videos, Shorts, whole playlists and entire channels as MP4 (360p-4K) or MP3, with view, like and comment counts, duration, upload date and channel on every row.

- **URL**: https://apify.com/mrdoe/youtube-video-downloader.md
- **Developed by:** [MrDoe](https://apify.com/mrdoe) (community)
- **Categories:** Videos, Social media, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

![YouTube Video Downloader](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/youtube-video-downloader--hero.png)

## YouTube Video Downloader — MP4 & MP3, whole channels and playlists

**Give it a video, a Shorts link, a playlist, a whole channel, or just a search phrase — get back the video file as MP4 (360p up to 4K) or the audio as MP3, with view, like and comment counts, duration, upload date and channel on every row.** No account, no login.

This Actor is a **YouTube video downloader**, a **YouTube to MP3 converter**, a **playlist downloader** and a **channel downloader** in one.

***

### What does it do?

Paste one or more of:

- a **video URL** — `https://www.youtube.com/watch?v=…`
- a **Shorts URL** — `https://www.youtube.com/shorts/…`
- a **playlist URL** — every video in the playlist, up to your limit
- a **channel URL or `@handle`** — the channel's videos, newest first, up to your limit
- a **plain search phrase** — e.g. `lofi hip hop`, takes the top results

Each video comes back as one dataset row with its metadata, plus the downloaded `.mp4` or `.mp3` saved to the run's key-value store with a direct link on the row.

### Download a whole channel

Put a channel URL or `@handle` in the input, set **Max videos**, pick a quality, and press Start. The Actor walks the channel's video list and downloads each one — video **and** audio metadata (views, likes, comments, duration, upload date) on every row, and the media file in storage.

```json
{ "startUrls": ["https://www.youtube.com/@mkbhd"], "quality": "1080p", "maxItems": 50 }
```

### How it works

![How the YouTube Video Downloader works](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/youtube-video-downloader--how-it-works.png)

1. **Your input** — video / Shorts / playlist / channel URLs or search phrases, a quality, and a max count.
2. **The Actor collects and downloads** — it resolves playlists and channels to a video list, fetches each video's metadata, downloads the stream at the quality you asked for (or the next best available), and merges video + audio into a single MP4 (or extracts an MP3).
3. **Output** — one dataset row per video, plus the `.mp4` / `.mp3` files in the key-value store.

### What data you get

| Field                | Description                                                        |
| -------------------- | ---------------------------------------------------------------- |
| `videoId` / `url`    | Video ID and canonical watch URL                                |
| `title`              | Video title                                                     |
| `channel` / `channelUrl` / `channelId` | Uploading channel                             |
| `durationSeconds`    | Length in seconds                                               |
| `viewCount`          | View count at collection time                                   |
| `likeCount`          | Like count at collection time                                   |
| `commentCount`       | Comment count at collection time                                |
| `shareCount`         | Always `null` — YouTube does not publish share or dislike counts anywhere |
| `uploadDate`         | Upload date, `YYYYMMDD`                                         |
| `isShort`            | `true` for a Shorts URL                                         |
| `resolution`         | Resolution of the file actually downloaded, e.g. `1920x1080`    |
| `ext`                | `mp4` or `mp3`                                                  |
| `fileSizeMb`         | Size of the stored file                                         |
| `downloadUrl`        | Permanent key-value-store link to the file                      |
| `thumbnail`          | Thumbnail image URL                                             |
| `billedMinutes`      | Whole minutes of media delivered (rounded up, 1-minute minimum) |
| `status`             | `SUCCESS`, `FAILED`, or `SKIPPED_TOO_LARGE`                     |

### Where do the downloaded files go?

Into the run's **key-value store**, as `<videoId>.mp4` or `<videoId>.mp3`. Each dataset row carries the link in `downloadUrl`:

```text
https://api.apify.com/v2/key-value-stores/<storeId>/records/<videoId>.mp4
```

Those links are **permanent** for the life of the run's storage and need no auth for a public run. Browse every file under the run's **Storage → Key-value store** tab, or list them via the API.

### Input parameters

| Parameter            | Type    | Required | Default           | Description                                                                              |
| -------------------- | ------- | -------- | ----------------- | -------------------------------------------------------------------------------------- |
| `startUrls`          | Array   | Yes      | —                 | Video / Shorts / playlist / channel URLs, `@handle`s, or plain search phrases. One per line. |
| `quality`            | String  | No       | `720p`            | `360p`, `480p`, `720p`, `1080p`, `1440p`, `2160p`, or `audio` (MP3). Falls back to the next best if the exact resolution is missing. |
| `maxItems`           | Integer | No       | `10`              | Max videos to download in total across all inputs (applies to playlists, channels, searches). |
| `maxFileSizeMb`      | Integer | No       | `500`             | Skip any single file larger than this. Give the run at least 2× this in memory.       |
| `proxyConfiguration` | Object  | Yes      | Apify Residential | Required. YouTube blocks datacenter IPs — a residential proxy is strongly recommended. |

### Example output

```json
{
    "videoId": "dQw4w9WgXcQ",
    "title": "Rick Astley - Never Gonna Give You Up (Official Video)",
    "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "channel": "Rick Astley",
    "channelUrl": "https://www.youtube.com/channel/UCuAXFkgsw1L7xaCfnd5JJOw",
    "durationSeconds": 213,
    "viewCount": 1614038703,
    "likeCount": 18240000,
    "commentCount": 2300000,
    "shareCount": null,
    "uploadDate": "20091025",
    "isShort": false,
    "resolution": "1280x720",
    "ext": "mp4",
    "fileSizeMb": 17.35,
    "downloadUrl": "https://api.apify.com/v2/key-value-stores/abc123/records/dQw4w9WgXcQ.mp4",
    "thumbnail": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg",
    "billedMinutes": 4,
    "status": "SUCCESS"
}
```

Download the dataset as JSON, CSV, Excel or XML, or pull it from the Apify API.

### How to use

1. Open the Actor's **Input** tab.
2. Add one or more entries to **`startUrls`** — a video URL, a channel `@handle`, a playlist, or a search phrase.
3. Pick a **quality** (or `audio` for MP3).
4. Set **Max videos**.
5. Press **Start**. Rows appear in the **Dataset** tab; the media files land in the **Key-value store** tab.

### Usage examples

**One video in 1080p**

```json
{ "startUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"], "quality": "1080p" }
```

**A whole channel as MP3**

```json
{ "startUrls": ["https://www.youtube.com/@NASA"], "quality": "audio", "maxItems": 100 }
```

**A playlist in 4K**

```json
{ "startUrls": ["https://www.youtube.com/playlist?list=PLxxxx"], "quality": "2160p", "maxItems": 20 }
```

**Top search results**

```json
{ "startUrls": ["lofi hip hop", "deep focus"], "quality": "audio", "maxItems": 10 }
```

### Tips for best results

- **Residential proxy, always.** YouTube challenges datacenter IPs with "Sign in to confirm you're not a bot." A residential pool is the single biggest reliability factor.
- **Memory.** Files are held in memory while being stored. Give the run at least 2× your `maxFileSizeMb` (e.g. 2048 MB for files up to ~1 GB), or lower `maxFileSizeMb`.
- **Audio-only is much smaller and faster** — use `quality: "audio"` when you only need the sound.
- **`maxItems` is a total**, not per input.

### Limitations

- **Public videos only.** Private, members-only, deleted or region-locked videos return `FAILED`.
- Age-restricted videos may not be downloadable without a signed-in session, which this Actor does not use.
- A row is a snapshot at collection time; view / like / comment counts keep moving.
- `shareCount` and dislike count are always `null` — YouTube removed them platform-wide.
- Very long 4K videos can be multi-GB; use `maxFileSizeMb` to keep runs bounded.

### FAQ

**Can I download a whole YouTube channel?**
Yes. Put the channel URL or `@handle` in `startUrls`, set `maxItems`, and every video is downloaded with its stats.

**Can I convert YouTube to MP3?**
Yes. Set `quality` to `audio` — you get a 192 kbps MP3 per video in the key-value store.

**Does it download playlists?**
Yes. Paste the playlist URL; every video up to `maxItems` is downloaded.

**Do I need a YouTube account or cookies?**
No.

**Why did a video fail?**
Almost always a bot check (use a residential proxy), an age restriction, or a private / deleted / region-locked video. The row's `error` field and the run log say which.

**How fresh are the counts?**
Every run reads the live video page.

### Support

Found a bug or a field that changed shape? Open an issue on the Actor's **Issues** tab in the Apify Console.

### Legal / responsible use

Only download content you own, that is in the public domain or Creative Commons, or that you are otherwise authorized to download. Downloading may violate YouTube's Terms of Service. You are solely responsible for how you use this Actor and its output, including copyright in the videos and music you download and the data-protection laws that apply to you.

# Actor input Schema

## `startUrls` (type: `array`):

One entry per line. Accepts a video URL, a Shorts URL, a playlist URL, a channel URL or @handle (downloads the channel's videos), or a plain search phrase (e.g. "lofi hip hop"). For playlists, channels and searches the run stops at "Max videos".

## `quality` (type: `string`):

Video resolution to download, or "Audio only" for an MP3. If the requested resolution is not available, the next best one is used. Files are saved to the run's key-value store with a direct link on each dataset row.

## `maxItems` (type: `integer`):

Upper limit on how many videos to download in total across all inputs. Applies to playlists, channels and search terms; single video URLs are always downloaded.

## `maxFileSizeMb` (type: `integer`):

Skip any single file larger than this. Protects a run from a multi-hour 4K video. Raise the run's memory to at least twice this value.

## `proxyConfiguration` (type: `object`):

Required. YouTube blocks datacenter IPs with a "Sign in to confirm you're not a bot" challenge. A residential proxy is strongly recommended. The whole media stream is fetched through the proxy.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ],
  "quality": "720p",
  "maxItems": 10,
  "maxFileSizeMb": 500,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `files` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrdoe/youtube-video-downloader").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrls": ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"] }

# Run the Actor and wait for it to finish
run = client.actor("mrdoe/youtube-video-downloader").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
  ]
}' |
apify call mrdoe/youtube-video-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mrdoe/youtube-video-downloader"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/c76epxMCdVE08HSpS/builds/xP4gLCNscQBb18c5s/openapi.json
