p3sdev/php-ytdlp-wrapper

Robust PHP 8.4 yt-dlp wrapper with Symfony 7 bundle integration

Maintainers

Package info

github.com/PavlenkoEvgeniy/php-ytdlp-wrapper

Homepage

Issues

Type:symfony-bundle

pkg:composer/p3sdev/php-ytdlp-wrapper

Statistics

Installs: 35

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.4 2026-02-14 02:29 UTC

This package is auto-updated.

Last update: 2026-03-14 02:39:37 UTC


README

Robust yt-dlp wrapper for PHP 8.4 with a ready-to-use Symfony 7 bundle.

✨ Features

  • Safe process execution through symfony/process
  • Structured request object (YtDlpRequest)
  • Raw execution + JSON extraction helpers
  • Strong error model (BinaryNotFoundException, ProcessFailedException)
  • Symfony 7 service wiring and configurable bundle options

📋 Requirements

  • PHP 8.4+
  • yt-dlp installed on the host machine (binary in PATH or custom path)

📦 Install

composer require p3sdev/php-ytdlp-wrapper

🧩 Symfony 7 Bundle Setup

1️⃣ Register bundle

If Symfony Flex does not auto-register it, add to config/bundles.php:

return [
    // ...
    P3s\YtDlp\YtDlpBundle::class => ['all' => true],
];

2️⃣ Configure bundle

Create config/packages/yt_dlp.yaml:

yt_dlp:
  binary_path: 'yt-dlp'
  default_arguments: ['--no-warnings']
  working_directory: ~
  timeout: 300
  environment: {}

🍱 Symfony Flex Recipe

A ready-to-submit Symfony Flex recipe scaffold is available in:

  • flex-recipe/1.0

To publish it for auto-install support, submit that recipe to symfony/recipes-contrib.

🚀 Usage in Symfony

Inject P3s\YtDlp\YtDlpClientInterface into your service:

<?php

declare(strict_types=1);

namespace App\Service;

use P3s\YtDlp\YtDlpClientInterface;

final class VideoService
{
    public function __construct(private readonly YtDlpClientInterface $ytDlp)
    {
    }

    public function download(string $url): void
    {
        $result = $this->ytDlp->download($url, [
            'format' => 'bv*+ba/b',
            'output' => '%(title)s.%(ext)s',
            'paths' => '/tmp/videos',
        ]);

        $result->requireSuccessful();
    }
}

🛠️ Core API

⬇️ download(string|array $urls, array $options = []): ProcessResult

Runs yt-dlp for download/processing workflows.

🧠 rawJson(string|array $urls, array $options = []): ProcessResult

Runs metadata mode (--dump-json --skip-download --no-warnings) and returns full process output.

🔎 extractInfo(string|array $urls, array $options = []): array

Convenience method that returns parsed JSON lines.

⚙️ run(YtDlpRequest $request): ProcessResult

Low-level execution with full control over options, flags, and extra arguments.

🧾 YtDlpRequest

$request = YtDlpRequest::create(
    urls: ['https://www.youtube.com/watch?v=BaW_jenozKc'],
    options: [
        'format' => 'bestvideo+bestaudio/best',
        'cookies' => '/secure/cookies.txt',
        'proxy' => 'socks5://127.0.0.1:1080',
        'playlist-items' => '1:3',
        'print' => ['id', 'title'],
    ],
    flags: ['no-progress'],
    extraArguments: ['--'],
);

⚠️ Errors

  • BinaryNotFoundException: custom binary path does not exist or is not executable
  • ProcessFailedException: command returned non-zero exit code
  • YtDlpException: base runtime exception

📝 Notes

  • The wrapper maps options directly to yt-dlp CLI flags (format -> --format).
  • Arrays in option values are emitted as repeated flags.
  • Boolean true emits a flag, false is ignored.

📄 License

MIT. See LICENSE.

✅ CI

GitHub Actions runs tests on push and pull requests for PHP 8.4 and 8.5.

Workflow file: .github/workflows/tests.yml