npm package: @mks2508/yt-dl
Description: YouTube music metadata and download library for Bun
Latest version: 1.0.30

# @mks2508/yt-dl

> YouTube music metadata and download library for Bun

[![Bun](https://img.shields.io/badge/Bun-%3E%3D1.0.0-black?logo=bun)](https://bun.sh)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue)](https://www.typescriptlang.org/)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

A comprehensive TypeScript library for fetching YouTube metadata and downloading audio/video content with music metadata enrichment from MusicBrainz, iTunes, Spotify, and Last.fm.

## Features

- **Fast Metadata Fetching** - Parallel fetching of oEmbed (fast) and yt-dlp JSON (complete)
- **Music Metadata Enrichment** - Automatic enrichment from MusicBrainz, iTunes, Spotify, Last.fm
- **Format Selection** - List and select from all available video/audio formats
- **Download Management** - Real-time progress tracking with callbacks
- **Result Types** - Functional error handling with Result types (`{ success, data } | { success, error }`)
- **Plugin System** - Extensible architecture with hooks for customization
- **Cross-Platform** - Works on macOS, Linux, and Windows

## Installation

```bash
bun add @mks2508/yt-dl
```

## Requirements

- **Bun** >= 1.0.0
- **yt-dlp** installed in PATH

```bash
# macOS
brew install yt-dlp

# Linux
sudo curl -L https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -o /usr/local/bin/yt-dlp
sudo chmod a+rx /usr/local/bin/yt-dlp
```

## Quick Start

### Get Music Metadata

```typescript
import { YouTubeMusic } from '@mks2508/yt-dl'

const result = await YouTubeMusic.getMusicMetadata(
  'https://youtu.be/dQw4w9WgXcQ'
)

if (!result.success) {
  console.error('Error:', result.error)
  process.exit(1)
}

const { title, artist, album, artwork } = result.data
console.log(`♪ ${title} by ${artist}`)
```

### Download Audio

```typescript
const result = await YouTubeMusic.downloadBestAudio(
  'https://youtu.be/dQw4w9WgXcQ',
  './downloads',
  (p) => console.log(`${p.percent}% - ${p.speed}`)
)

if (result.success) {
  console.log('Downloaded:', result.data.filePath)
}
```

## API Reference

### YouTubeMusic (High-Level API)

```typescript
import { YouTubeMusic } from '@mks2508/yt-dl'

// Video Info
await YouTubeMusic.getVideoInfo(url)           // Complete info (oEmbed + yt-dlp + thumbnails)
await YouTubeMusic.getQuickInfo(url)           // Fast oEmbed metadata only
await YouTubeMusic.getFullInfo(url)            // Complete yt-dlp JSON

// Music Metadata
await YouTubeMusic.getMusicMetadata(url)       // Enriched music metadata
await YouTubeMusic.search(title, artist)       // Search by title/artist

// Formats
await YouTubeMusic.getFormats(url)             // Categorized formats (video/audio/combined)
await YouTubeMusic.getBestAudioFormat(url)     // Best audio format
await YouTubeMusic.getBestVideoFormat(url)     // Best video format

// Downloads
await YouTubeMusic.download(options)           // Custom download
await YouTubeMusic.downloadBestAudio(url)      // Best quality audio
await YouTubeMusic.downloadBestVideo(url)      // Best quality video
await YouTubeMusic.downloadBestCombined(url)   // Best quality combined
```

### Services

For advanced usage, you can use individual services:

```typescript
import {
  videoInfoService,
  musicMetadataService,
  formatService,
  downloadService
} from '@mks2508/yt-dl'

// Video info service
const info = await videoInfoService.getCompleteInfo(url, {
  thumbnailAnsiEnabled: true,
  thumbnailHeight: 14,
  fullInfoEnabled: true
})

// Music metadata service
const metadata = await musicMetadataService.getMusicMetadata(url, ytInfo, {
  useProviders: true,
  providerConfig: {
    spotify: { enabled: true, clientId: 'xxx', clientSecret: 'yyy' }
  }
})

// Format service
const categories = formatService.categorize(formats)
const bestAudio = formatService.getBestAudio(formats)

// Download service
const result = await downloadService.download({
  url,
  format: 'bestaudio',
  outputPath: './downloads',
  onProgress: (p) => console.log(`${p.percent}% - ${p.speed}`)
})
```

## Documentation

- [Getting Started](./docs/getting-started.md)
- [Metadata Fetching](./docs/metadata-fetching.md)
- [Downloads](./docs/downloads.md)
- [Format Selection](./docs/format-selection.md)
- [Error Handling](./docs/error-handling.md)
- [Configuration](./docs/configuration.md)
- [Examples](./docs/examples.md)

## Result Type Pattern

All service methods return a `Result<T, Error>` type for explicit error handling:

```typescript
type Result<T, E = Error> =
  | { success: true; data: T }
  | { success: false; error: E }
```

**Usage:**

```typescript
import { YouTubeMusic } from '@mks2508/yt-dl'

const result = await YouTubeMusic.getMusicMetadata(url)

if (!result.success) {
  // Handle error
  console.error('Failed:', result.error.message)
  return
}

// Use data
const { title, artist } = result.data
console.log(`${title} by ${artist}`)
```

## Configuration

Create a config file at `~/.config/ytdlp-tui/config.json`:

```json
{
  "mp3Metadata": {
    "providers": {
      "musicbrainz": { "enabled": true },
      "itunes": { "enabled": true },
      "spotify": { "enabled": false, "clientId": "", "clientSecret": "" },
      "lastfm": { "enabled": false, "apiKey": "" }
    }
  }
}
```

## TUI Application

This package also includes a terminal UI application:

```bash
# Interactive mode
bun yt-tui https://youtu.be/dQw4w9WgXcQ

# Non-interactive download
bun yt-tui -a https://youtu.be/dQw4w9WgXcQ

# List formats
bun yt-tui -l https://youtu.be/dQw4w9WgXcQ
```

See [TUI README](./README_TUI.md) for full CLI documentation.

## License

MIT