承接 rllngr/kirby-videozer 相关项目开发

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

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

rllngr/kirby-videozer

最新稳定版本:1.3.0

Composer 安装命令:

composer require rllngr/kirby-videozer

包简介

Kirby CMS plugin — compresses uploaded videos with FFmpeg and generates poster frames

README 文档

README

A Kirby CMS plugin that automatically compresses uploaded videos using FFmpeg and generates poster frames. All processed files are stored in a video-cache/ directory outside Kirby's content folder and served directly by the web server.

What it produces for each uploaded video:

  • {name}-compressed.mp4 — H.264/AAC optimized MP4
  • {name}-opt.webm — VP9/Opus WebM variant (optional)
  • {name}-poster.jpg — Thumbnail extracted at 1 second (or 10% of duration)

The poster is also copied to the page's content directory so Kirby's thumb system can generate srcset variants and the Panel can show a video preview image. The video's orientation (portrait/landscape/square) is auto-detected from its dimensions and saved as a content field on upload.

Requirements

  • Kirby CMS ^4 || ^5
  • PHP >=8.0
  • FFmpeg installed on the server

Installation

Via Composer (recommended)

composer require rllngr/kirby-videozer

Manual

Download and extract the plugin into site/plugins/videozer/.

Configuration

Add options to your site/config/config.php:

return [
    // Path to the ffmpeg binary. Defaults to 'ffmpeg' (resolved via PATH).
    'rllngr.videozer.ffmpeg' => '/usr/local/bin/ffmpeg',

    // Named quality preset to use (web/high/low). Overrides crf/max_width when set.
    // Default: null (uses individual crf/max_width options below)
    'rllngr.videozer.preset' => 'web',

    // Built-in presets — override or extend as needed.
    'rllngr.videozer.presets' => [
        'web'  => ['crf' => 23, 'max_width' => 1280, 'ffpreset' => 'slow'],
        'high' => ['crf' => 18, 'max_width' => 1920, 'ffpreset' => 'slow'],
        'low'  => ['crf' => 28, 'max_width' => 720,  'ffpreset' => 'fast'],
    ],

    // H.264 CRF quality (0–51, lower = better quality). Used when no preset is set.
    'rllngr.videozer.crf' => 28,

    // Maximum output width in pixels (aspect ratio preserved). Default: 1920
    'rllngr.videozer.max_width' => 1920,

    // Strip audio from the output. Recommended for silent background/portfolio videos.
    // Default: false
    'rllngr.videozer.strip_audio' => false,

    // MP4 audio bitrate. Ignored when strip_audio is true. Default: '96k'
    'rllngr.videozer.audio_bitrate' => '96k',

    // Whether to generate a VP9/WebM variant. Default: true
    'rllngr.videozer.generate_webm' => true,

    // WebM CRF quality. Default: 33
    'rllngr.videozer.webm_crf' => 33,

    // WebM audio bitrate. Ignored when strip_audio is true. Default: '64k'
    'rllngr.videozer.webm_audio_bitrate' => '64k',

    // Restrict processing to specific page templates. null = all pages.
    'rllngr.videozer.templates' => ['project', 'article'],

    // File template to assign after processing. false = skip.
    'rllngr.videozer.change_template' => 'video',

    // Name of the gallery field to clean up on file deletion. null = skip.
    'rllngr.videozer.gallery_field' => 'gallery',

    // Custom base directory for the video cache. null = {webroot}/video-cache/.
    'rllngr.videozer.cache_dir' => null,
];

Usage

Page method

Use $page->videozFiles() to retrieve files excluding any generated variants (useful for gallery fields):

// In a blueprint field:
query: page.videozFiles

// In a template:
foreach ($page->videozFiles() as $file) { ... }

File methods

All methods are available directly on video file objects:

// Best available MP4 URL (compressed if cached, original otherwise)
$file->videozUrl()

// WebM URL if generated, null otherwise
$file->videozWebmUrl()

// Poster URL — always returns the expected URL (browser handles 404 gracefully via @error)
$file->videozPosterUrl()

// Srcset for the poster frame via Kirby's thumb system (requires content-dir copy to exist)
$file->videozPosterSrcset()

// Whether a compressed MP4 exists in the cache
$file->hasVideoz()

// Whether a poster exists in the cache
$file->videozHasPoster()

// Orientation string: 'portrait', 'landscape', or 'square'
// Returns the saved panel value if set, otherwise auto-detects from ffprobe/image dimensions
$file->videozOrientation()

// Panel image for use with `image.query` — returns poster for videos, self for images, null otherwise
$file->videozPanelImage()

// FFprobe metadata: duration, size, bitrate, width, height, codec, fps, hasAudio
$file->videozInfo()

// Manually trigger processing (optional preset + force flag)
$file->videozerProcess('high', force: true)

// Manually regenerate poster (optional force + timestamp in seconds)
$file->videozGeneratePoster(force: true, timestamp: 3.5)

Cache URL pattern

Generated files are stored at:

/video-cache/{page-id}/{name}-compressed.mp4
/video-cache/{page-id}/{name}-opt.webm
/video-cache/{page-id}/{name}-poster.jpg

Make sure your web server serves this directory statically. Example nginx rule:

location /video-cache/ {
    root /path/to/public;
    expires 30d;
    add_header Cache-Control "public";
}

Panel API routes

The plugin exposes three authenticated Panel API endpoints:

Method Endpoint Description
GET /api/videozer/status FFmpeg availability + video stats
POST /api/videozer/optimize Process a single file (page, filename, preset, force)
POST /api/videozer/optimize-all Batch process all videos (preset, force)

Troubleshooting

  • Check site/plugins/videozer/videozer.log for processing errors.
  • If FFmpeg is not found, set rllngr.videozer.ffmpeg to the full binary path.
  • Uploads trigger processBackground() — FFmpeg runs in a detached shell so the Panel request returns immediately. The poster and srcset will appear once the background job completes.
  • The API routes (/api/videozer/optimize, /api/videozer/optimize-all) use the synchronous process() method — suited for scripts and manual re-processing.

License

MIT — Nicolas Rollinger 🫰

统计信息

  • 总下载量: 10
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 5
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-03-26

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固