> ## Documentation Index
> Fetch the complete documentation index at: https://docs.videodb.io/llms.txt
> Use this file to discover all available pages before exploring further.

# When to Transcode

> Decide when transcoding is needed, understand input limits, and choose the right processing mode

Transcoding converts video to standardized formats for playback and processing. Not all uploads need transcoding - use this guide to decide.

## Quick Example

<CodeGroup>
  ```python Python theme={null}
  from videodb import TranscodeMode, VideoConfig

  job_id = conn.transcode(
      source="https://example.com/source.mov",
      callback_url="https://your-backend.com/webhooks",
      mode=TranscodeMode.lightning
  )
  print(f"Job queued: {job_id}")
  ```

  ```javascript Node.js theme={null}
  import { TranscodeMode } from 'videodb';

  const jobId = await conn.transcode(
      "https://example.com/source.mov",
      "https://your-backend.com/webhooks",
      TranscodeMode.lightning
  );
  console.log(`Job queued: ${jobId}`);
  ```
</CodeGroup>

***

## When You Need Transcoding

| Scenario                        | Transcode? | Why                             |
| :------------------------------ | :--------- | :------------------------------ |
| MOV, MKV, AVI input             | Yes        | Convert to MP4/HLS for playback |
| 4K source → 720p delivery       | Yes        | Reduce size and bandwidth       |
| High framerate (120fps) → 30fps | Yes        | Normalize for web               |
| Custom aspect ratio             | Yes        | Crop or letterbox               |
| MP4 already in target format    | No         | Upload directly                 |
| Already optimized for web       | No         | Save processing cost            |

***

## Input Limits

| Capability     | Limit             |
| :------------- | :---------------- |
| Max Resolution | 4K (3840 × 2160)  |
| Max Frame Rate | 100 fps           |
| Max File Size  | 8 GB              |
| Audio Support  | AAC, MP3, or mute |

<Note>
  Need larger files or custom pipelines? Contact [Sales](mailto:engg@videodb.io) or reach out on [Discord](https://discord.gg/py9P639jGz).
</Note>

***

## Processing Modes

Choose based on your latency and cost requirements:

| Mode        | Best For            | Trade-off           |
| :---------- | :------------------ | :------------------ |
| `lightning` | Real-time workflows | Faster, higher cost |
| `economy`   | Batch processing    | Slower, lower cost  |

<CodeGroup>
  ```python Python theme={null}
  from videodb import TranscodeMode

  # Fast - for user-facing flows
  job_id = conn.transcode(
      source=url,
      callback_url=callback,
      mode=TranscodeMode.lightning
  )

  # Economical - for batch jobs
  job_id = conn.transcode(
      source=url,
      callback_url=callback,
      mode=TranscodeMode.economy
  )
  ```

  ```javascript Node.js theme={null}
  import { TranscodeMode } from 'videodb';

  // Fast - for user-facing flows
  const jobId = await conn.transcode(
      url,
      callback,
      TranscodeMode.lightning
  );

  // Economical - for batch jobs
  const jobId = await conn.transcode(
      url,
      callback,
      TranscodeMode.economy
  );
  ```
</CodeGroup>

***

## Job Lifecycle

1. **Submit Job** - `conn.transcode()` → Status: `pending`
2. **Processing** - Fetch & encode → Status: `processing`
3. **Complete** - Webhook triggers with output URL

### Check Status

<CodeGroup>
  ```python Python theme={null}
  job = conn.get_transcode_details(job_id)
  print(job.status)  # pending | processing | completed | failed
  print(job.output)  # URL when completed
  ```

  ```javascript Node.js theme={null}
  const job = await conn.getTranscodeDetails(jobId);
  console.log(job.status);  // pending | processing | completed | failed
  console.log(job.output);  // URL when completed
  ```
</CodeGroup>

***

## Webhook Callbacks

### Success

```json theme={null}
{
  "success": true,
  "data": {
    "job_id": "xxx",
    "output": "https://transcoded-output-url.mp4"
  },
  "message": "Transcode job completed"
}
```

### Failure

```json theme={null}
{
  "success": false,
  "job_id": "xxx",
  "code": "invalid_source",
  "message": "Failed to download source media",
  "reason": "HTTP 403 Forbidden"
}
```

***

## Error Codes

| Code                    | Meaning                  | Fix                         |
| :---------------------- | :----------------------- | :-------------------------- |
| `invalid_video_config`  | Resolution/FPS/CRF error | Check ≤4K, ≤100 fps         |
| `invalid_audio_config`  | Conflicting audio params | Adjust audio config         |
| `invalid_source`        | URL not accessible       | Check URL permissions       |
| `invalid_media`         | Unsupported format       | Convert to supported format |
| `internal_server_error` | Unexpected error         | Retry or contact support    |

***

## Decision Flowchart

```
Source file arrives
        │
        ▼
Is it MP4/HLS at target resolution? ──Yes──► Upload directly
        │
       No
        ▼
Need resolution change? ──────────────────► Transcode
        │
       No
        ▼
Need format conversion? ──────────────────► Transcode
        │
       No
        ▼
Need framerate adjustment? ────────────────► Transcode
        │
       No
        ▼
Upload directly
```

***

## Next Steps

<CardGroup cols={2}>
  <Card icon="send" title="Output Formats" href="/pages/ingest/transcoding/output-formats">
    MP4/HLS, resolutions, quality settings
  </Card>

  <Card icon="upload" title="Upload Video" href="/pages/ingest/files-and-collections/upload-video">
    Ingest media into VideoDB
  </Card>
</CardGroup>
