zhitoo/laravel-hls-converter

Laravel package for converting videos to HLS format using the HLS Converter microservice

Maintainers

Package info

github.com/zhitoo/laravel-hls-converter

pkg:composer/zhitoo/laravel-hls-converter

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.0 2026-06-23 07:08 UTC

This package is auto-updated.

Last update: 2026-06-23 07:13:29 UTC


README

A Laravel package for converting videos to HLS (HTTP Live Streaming) format via the HLS Converter microservice.

Requirements

  • PHP 8.1+
  • Laravel 10 or 11
  • PHP zip extension (for extraction features)

Installation

composer require zhitoo/laravel-hls-converter

Publish the config file:

php artisan vendor:publish --tag=hls-converter-config

Configuration

Add the following to your .env:

HLS_CONVERTER_BASE_URL=https://hls.yourdomain.com
HLS_CONVERTER_API_KEY=your-secret-api-key
HLS_CONVERTER_TIMEOUT=30
HLS_CONVERTER_DOWNLOAD_TIMEOUT=120

# Optional: temp directory for ZIP download/extract (default: storage/app/hls-temp)
HLS_CONVERTER_TEMP_PATH=/tmp/hls-temp

Usage

Submit a conversion job

use Zhitoo\HlsConverter\Facades\HlsConverter;

$taskId = HlsConverter::convert(
    videoUrl: 'https://example.com/video.mp4',
    resolutions: [1080, 720, 480],   // omit for original quality only
    chunkDuration: 10,
    audioChannels: 2,
);

Check status

$status = HlsConverter::status($taskId);

echo $status->status;    // Pending | Processing | Completed | Failed
echo $status->progress;  // 0–100

if ($status->isCompleted()) {
    echo $status->masterPlaylist; // "master.m3u8"
    foreach ($status->qualities as $q) {
        echo $q['label'] . '' . $q['playlist'];
        // 720p → 720p/output.m3u8
    }
}

Download ZIP

// Save to an explicit path
HlsConverter::downloadToFile($taskId, storage_path("hls/{$taskId}.zip"));

// Or get a PSR-7 stream
$stream = HlsConverter::download($taskId);
file_put_contents(storage_path("hls/{$taskId}.zip"), $stream);

Extract ZIP to a local directory

Downloads the ZIP, extracts it, deletes the ZIP, and returns the list of extracted file paths.

$files = HlsConverter::extractTo($taskId, storage_path("hls/{$taskId}"));

// $files is an array of absolute paths:
// [
//   '/var/www/storage/app/hls/<taskId>/master.m3u8',
//   '/var/www/storage/app/hls/<taskId>/720p/output.m3u8',
//   '/var/www/storage/app/hls/<taskId>/720p/segment_000.ts',
//   ...
// ]

Transfer HLS files to a Laravel storage disk

Downloads the ZIP, extracts it, uploads every file to the chosen storage disk, and cleans up all temp files automatically.

// Transfer to a specific disk (local, s3, ftp, etc.)
$result = HlsConverter::transferToStorage(
    taskId: $taskId,
    storagePath: "videos/hls/{$taskId}",
    disk: 's3',
);

// Or use the default filesystem disk
$result = HlsConverter::transferToDefaultStorage(
    taskId: $taskId,
    storagePath: "videos/hls/{$taskId}",
);

echo $result->disk;                  // "s3"
echo $result->basePath;              // "videos/hls/<taskId>"
echo $result->masterPlaylistPath();  // "videos/hls/<taskId>/master.m3u8"

foreach ($result->files as $path) {
    echo Storage::disk($result->disk)->url($path);
}

// Get as array
$array = $result->toArray();
// [
//   'disk'            => 's3',
//   'base_path'       => 'videos/hls/<taskId>',
//   'master_playlist' => 'videos/hls/<taskId>/master.m3u8',
//   'files'           => [...],
// ]

Polling until done then transferring

use Zhitoo\HlsConverter\Facades\HlsConverter;
use Zhitoo\HlsConverter\Exceptions\HlsConverterException;

$taskId = HlsConverter::convert('https://example.com/video.mp4', [720, 480]);

do {
    sleep(5);
    $status = HlsConverter::status($taskId);
} while ($status->isPending() || $status->isProcessing());

if ($status->isFailed()) {
    $log = HlsConverter::logs($taskId);
    throw new \RuntimeException("Conversion failed.\n{$log}");
}

$result = HlsConverter::transferToStorage($taskId, "videos/hls/{$taskId}", 's3');

Dependency injection

use Zhitoo\HlsConverter\HlsConverter;
use Zhitoo\HlsConverter\DTOs\TransferResult;

class VideoService
{
    public function __construct(private HlsConverter $hls) {}

    public function process(string $url, string $taskId): TransferResult
    {
        return $this->hls->transferToStorage($taskId, "hls/{$taskId}", 's3');
    }
}

Exception Handling

All methods throw Zhitoo\HlsConverter\Exceptions\HlsConverterException on failure.

use Zhitoo\HlsConverter\Exceptions\HlsConverterException;

try {
    $result = HlsConverter::transferToStorage($taskId, 'videos/hls', 's3');
} catch (HlsConverterException $e) {
    logger()->error('HLS transfer failed', ['error' => $e->getMessage()]);
}

API Reference

Method Description Returns
convert($url, $resolutions, $chunkDuration, $audioChannels) Submit a conversion job string task_id
status($taskId) Get task status TaskStatus
logs($taskId) Get raw FFmpeg log string
download($taskId) Get ZIP as a PSR-7 stream StreamInterface
downloadToFile($taskId, $path) Save ZIP to a local file void
extractTo($taskId, $destination) Download + extract ZIP to a local dir string[] file paths
transferToStorage($taskId, $storagePath, $disk) Download + extract + upload to storage disk TransferResult
transferToDefaultStorage($taskId, $storagePath) Same, using filesystems.default disk TransferResult

TaskStatus DTO

Property Type Description
taskId string Task UUID
status string Pending, Processing, Completed, Failed
progress int 0–100
currentStep string Current processing step
retryCount int Number of retries so far
createdAt string ISO 8601
updatedAt string ISO 8601
masterPlaylist string|null master.m3u8 — only when Completed
qualities array [{height, label, playlist}] — only when Completed

Helper methods: isPending(), isProcessing(), isCompleted(), isFailed()

TransferResult DTO

Property Type Description
disk string Storage disk name
basePath string Base path inside the disk
masterPlaylist string|null master.m3u8 relative name, or null
files string[] Full storage paths of all uploaded files

Methods: masterPlaylistPath() — full path including basePath, toArray()

License

MIT