承接 micilini/video-stream 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

micilini/video-stream

Composer 安装命令:

composer require micilini/video-stream

包简介

PHP video streaming library with HTTP Range support and optional disk cache. Works standalone or with Laravel.

README 文档

README

🎬 VideoStream

PHP video streaming library with HTTP Range support, disk cache, events, temporary tokens, rate limiting, subtitles, and Laravel integration.

Works standalone (plain PHP) or with Laravel 10/11/12/13+.

PHP Laravel License Tests Packagist

Example Usage
Example of usage

Features

  • Local streaming — stream local video files with proper HTTP Range support
  • Remote streaming — proxy remote video URLs with native Range passthrough
  • Disk cache — optional file-based cache for remote videos with TTL, LRU eviction, and stale fallback
  • HTTP Range Requests — seek, scrub, and resume support for HTML5 players
  • Events / hooks — listen to the streaming lifecycle in plain PHP or Laravel
  • Temporary tokens — protect streams with signed, expiring tokens
  • Rate limiting — limit concurrent streams and requests per minute by IP
  • Subtitles — serve .vtt / .srt subtitles and associate subtitle tracks with videos
  • Laravel integration — Service Provider, Facade, publishable config, and Artisan commands
  • Framework agnostic — works with Laravel, Symfony, Slim, CodeIgniter, or plain PHP
  • Zero required third-party packages in the core — the main library relies on PHP 8.2+ and ext-curl

Installation

composer require micilini/video-stream

Requirements

  • PHP 8.2 or higher
  • ext-curl

Quick Start

Plain PHP

<?php

require 'vendor/autoload.php';

use Micilini\VideoStream\VideoStream;

// Local video
$stream = new VideoStream();
$stream->local('/var/www/videos/movie.mp4')->output();
<?php

require 'vendor/autoload.php';

use Micilini\VideoStream\VideoStream;

// Remote video
$stream = new VideoStream();
$stream->remote('https://cdn.example.com/video.mp4')->output();
<?php

require 'vendor/autoload.php';

use Micilini\VideoStream\VideoStream;

// Remote video with cache
$stream = new VideoStream();
$stream->remote('https://cdn.example.com/video.mp4')
    ->cache(
        enabled: true,
        ttl: 3600,
        fresh: false,
        path: '/tmp/video-cache',
        maxDisk: 10 * 1024 * 1024 * 1024
    )
    ->output();

Laravel

After installation, the Service Provider and Facade are auto-discovered.

Publish the config (optional):

php artisan vendor:publish --tag=video-stream-config

Routes example:

use Illuminate\Support\Facades\Route;
use Micilini\VideoStream\Laravel\VideoStreamFacade as VideoStream;

Route::get('/video/{file}', function (string $file) {
    $path = storage_path("app/videos/{$file}");
    return VideoStream::local($path)->stream();
});

Route::get('/stream', function () {
    $url = request('url');

    return VideoStream::remote($url)
        ->cache(enabled: true)
        ->stream();
});

Symfony

use Micilini\VideoStream\VideoStream;
use Symfony\Component\HttpFoundation\Response;

class VideoController
{
    public function play(): Response
    {
        $stream = new VideoStream();
        return $stream->local('/path/to/video.mp4')->stream();
    }
}

Other frameworks

use Micilini\VideoStream\VideoStream;

$stream = new VideoStream();
$stream->local('/path/to/video.mp4')->output();

API Overview

Main class

$stream = new VideoStream(
    defaultBufferSize: 262144,
    defaultContentType: 'video/mp4',
    cacheHandler: null,
);

Fluent methods

Method Description
->local(string $path) Set a local file as the video source
->remote(string $url) Set a remote URL as the video source
->contentType(string $type) Override the Content-Type header
->buffer(int $bytes) Override the buffer size
->cacheControl(string $value) Override the Cache-Control header
->cache(...) Configure disk cache for remote videos
->on(string $event, callable $listener) Register an event listener
->withToken(...) Validate a signed token before streaming
->rateLimit(...) Limit concurrent streams and requests by IP
->subtitle(string $path) Output a subtitle file directly
->subtitles(array $tracks) Associate subtitle tracks with a video
->output() Stream directly via echo + flush
->stream() Return StreamedResponse if Symfony is available, otherwise call output()
VideoStream::generateToken(...) Generate a signed expiring token

Disk Cache

$stream->remote($url)->cache(
    enabled: true,
    ttl: 86400,
    fresh: false,
    path: '/tmp/video-cache',
    maxDisk: 10_737_418_240,
)->output();

For local videos, ->cache() is ignored.

Cache behavior

Scenario Behavior
Cache hit, not expired Serve from disk immediately
Cache hit, expired, remote OK Re-download and replace cache
Cache hit, expired, remote down Serve stale cache
Cache miss, remote OK Download, cache, and serve
Cache miss, remote down Throw StreamException
Disk full LRU eviction removes the oldest files

Events / Hooks

Use events to monitor the stream lifecycle, add custom logging, or feed analytics.

Plain PHP

use Micilini\VideoStream\VideoStream;

$stream = new VideoStream();

$stream->on('beforeStream', function (array $context) {
    error_log('Starting stream: ' . ($context['source'] ?? 'unknown'));
});

$stream->on('afterStream', function (array $context) {
    error_log('Finished stream');
});

$stream->remote('https://cdn.example.com/video.mp4')->output();

Available events

  • beforeStream
  • afterStream
  • onCacheHit
  • onCacheMiss
  • onCacheExpired
  • onError

Laravel

In Laravel, you can bridge those hooks to framework events and listeners through the package integration layer.

Temporary Tokens

Use signed tokens to protect streaming URLs.

Generate a token

use Micilini\VideoStream\VideoStream;

$token = VideoStream::generateToken(
    videoId: 'movie-123',
    secret: 'my-app-secret',
    expiresIn: 3600,
    ip: '192.168.1.100',
);

Validate before streaming

use Micilini\VideoStream\VideoStream;

$stream = new VideoStream();

$stream->remote('https://cdn.example.com/video.mp4')
    ->withToken(
        token: $_GET['token'],
        secret: 'my-app-secret',
        videoId: 'movie-123',
        ip: $_SERVER['REMOTE_ADDR'] ?? null,
    )
    ->output();

If the token is invalid or expired, the package throws an exception.

Rate Limiting

Limit the number of simultaneous streams and requests per minute for a given IP.

use Micilini\VideoStream\VideoStream;

$stream = new VideoStream();

$stream->remote('https://cdn.example.com/video.mp4')
    ->rateLimit(
        maxConcurrent: 3,
        maxPerMinute: 30,
        storagePath: '/tmp/video-stream-rate-limit',
        ip: $_SERVER['REMOTE_ADDR'] ?? null,
    )
    ->output();

This is useful to reduce abuse and protect server resources without external infrastructure.

Subtitles

Output a subtitle file directly

use Micilini\VideoStream\VideoStream;

$stream = new VideoStream();
$stream->subtitle('/path/to/subtitles/movie.vtt')->output();

Associate subtitles with a video

use Micilini\VideoStream\VideoStream;

$stream = new VideoStream();

$stream->local('/path/to/video.mp4')
    ->subtitles([
        'pt' => '/subtitles/movie-pt.vtt',
        'en' => '/subtitles/movie-en.vtt',
    ])
    ->output();

Supported subtitle scenarios:

  • .vtt output
  • .srt support
  • .srt to .vtt conversion when needed
  • subtitle metadata association through the video response pipeline

Example Demo

The repository includes a runnable example application under the example/ directory.

Suggested structure:

example/
├── index.php
├── index.html
├── cache/
├── rate-limit/
├── subtitles/
└── videos/

Notes

  • Keep the demo HTML inside example/
  • Use a relative base path in the frontend, such as:
const PURE_BASE = './index.php';
  • Open the demo through a local web server, not file://
  • The demo is useful to validate:
    • local streaming
    • remote streaming
    • cache
    • temporary tokens
    • rate limiting
    • subtitles
    • event logging

Laravel Configuration

After publishing the config:

php artisan vendor:publish --tag=video-stream-config

A typical config/video-stream.php may include:

return [
    'buffer_size' => 262144,
    'default_content_type' => 'video/mp4',

    'cache' => [
        'enabled' => env('VIDEO_STREAM_CACHE', false),
        'path' => storage_path('app/video-cache'),
        'ttl' => (int) env('VIDEO_STREAM_CACHE_TTL', 86400),
        'max_disk_usage' => (int) env('VIDEO_STREAM_CACHE_MAX_DISK', 10 * 1024 * 1024 * 1024),
    ],

    'auth' => [
        'secret' => env('VIDEO_STREAM_AUTH_SECRET', ''),
        'default_ttl' => (int) env('VIDEO_STREAM_AUTH_TTL', 3600),
    ],

    'events' => [
        'enabled' => env('VIDEO_STREAM_EVENTS_ENABLED', true),
    ],

    'rate_limit' => [
        'enabled' => env('VIDEO_STREAM_RATE_LIMIT_ENABLED', false),
        'max_concurrent' => (int) env('VIDEO_STREAM_RATE_LIMIT_MAX_CONCURRENT', 3),
        'max_per_minute' => (int) env('VIDEO_STREAM_RATE_LIMIT_MAX_PER_MINUTE', 30),
    ],
];

Example .env

VIDEO_STREAM_CACHE=true
VIDEO_STREAM_CACHE_TTL=86400
VIDEO_STREAM_CACHE_MAX_DISK=10737418240

VIDEO_STREAM_AUTH_SECRET=change-this-secret
VIDEO_STREAM_AUTH_TTL=3600

VIDEO_STREAM_EVENTS_ENABLED=true

VIDEO_STREAM_RATE_LIMIT_ENABLED=false
VIDEO_STREAM_RATE_LIMIT_MAX_CONCURRENT=3
VIDEO_STREAM_RATE_LIMIT_MAX_PER_MINUTE=30

Artisan commands

php artisan video-stream:cache-status
php artisan video-stream:cache-clear
php artisan video-stream:cache-clear --expired

Project Structure

src/
├── VideoStream.php
├── Contracts/
│   ├── StreamDriverInterface.php
│   ├── CacheHandlerInterface.php
│   └── EventDispatcherInterface.php
├── Config/
│   └── StreamConfig.php
├── Drivers/
│   ├── LocalStreamDriver.php
│   └── RemoteStreamDriver.php
├── Cache/
│   └── FileCacheHandler.php
├── Http/
│   ├── RangeRequestHandler.php
│   └── RateLimiter.php
├── Auth/
│   ├── TokenGenerator.php
│   └── TokenValidator.php
├── Events/
│   ├── StreamEvent.php
│   ├── BeforeStream.php
│   ├── AfterStream.php
│   ├── CacheHit.php
│   ├── CacheMiss.php
│   ├── CacheExpired.php
│   ├── StreamError.php
│   └── CallbackEventDispatcher.php
├── Subtitles/
│   ├── SubtitleHandler.php
│   └── SrtToVttConverter.php
├── Exceptions/
│   ├── StreamException.php
│   ├── VideoNotFoundException.php
│   ├── InvalidConfigException.php
│   ├── CacheException.php
│   ├── InvalidTokenException.php
│   ├── TokenExpiredException.php
│   └── RateLimitExceededException.php
└── Laravel/
    ├── VideoStreamServiceProvider.php
    ├── VideoStreamFacade.php
    └── Commands/
        ├── CacheClearCommand.php
        └── CacheStatusCommand.php

Testing

composer install
vendor/bin/phpunit

The test suite should cover:

  • StreamConfig validation
  • HTTP Range parsing
  • local streaming
  • remote streaming
  • cache TTL / eviction / stale fallback
  • event dispatching
  • token generation and validation
  • rate limiting
  • subtitle output and conversion
  • integration with the fluent API

Upgrade Notes

If you removed the legacy v1-style API in the new major version, document that change in an UPGRADE.md file and keep the README focused on the fluent API only.

Contributing

Pull requests are welcome. For major changes, open an issue first so the scope can be discussed before implementation.

License

MIT

Made with ☕ by Micilini

micilini/video-stream 适用场景与选型建议

micilini/video-stream 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 918 次下载、GitHub Stars 达 7, 最近一次更新时间为 2022 年 11 月 16 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「php」 「cache」 「video」 「streaming」 「laravel」 「range-request」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 micilini/video-stream 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 micilini/video-stream 我们能提供哪些服务?
定制开发 / 二次开发

基于 micilini/video-stream 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 918
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 7
  • 点击次数: 15
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 7
  • Watchers: 2
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2022-11-16