Skip to content

Video primitives: upload, validation, storage, and processing in core #499

@chubes4

Description

@chubes4

Overview

Data Machine core should provide platform-agnostic video primitives that any extension can consume — the same way core provides the OAuth framework, the GD image template engine, and the publish handler base classes.

Currently there is zero video support anywhere in the DM ecosystem. data-machine-socials needs it first (for Instagram Reels, Twitter video, etc.) but video handling belongs in core so any extension can use it.

What Core Should Provide

1. Video Upload

  • REST endpoint and/or ability for uploading video files
  • Store in managed temp directory or WordPress media library
  • Return a video reference (URL, path, or media ID) that extensions consume
  • Support both file upload and URL-based video (fetch from remote)

2. Video Validation

  • MIME type checking (MP4, MOV, WebM, etc.)
  • Duration extraction
  • Resolution/dimensions detection
  • File size limits (configurable)
  • Codec detection (H.264, H.265, VP9, etc.)
  • Constraint-based validation — extensions pass their requirements, core validates against them:
    $constraints = [
        'max_duration' => 900,    // 15 min (IG Reels)
        'max_file_size' => 1073741824, // 1GB
        'allowed_codecs' => ['h264'],
        'aspect_ratios' => ['9:16', '1:1', '4:5'],
    ];
    $result = $video_primitive->validate($video_path, $constraints);

3. Video Metadata

  • Extract duration, resolution, codec, bitrate, framerate
  • Return as structured data that extensions can inspect
  • Used for display (duration badges in UI) and validation

4. Thumbnail Generation

  • Extract frame from video at configurable timestamp (default: first frame or mid-point)
  • Generate thumbnail image in standard sizes
  • Return as WordPress media attachment or temp file
  • Extensions can use this for cover images (IG Reels cover, Twitter video thumbnail, etc.)

5. Temp Storage & Cleanup

  • Managed temp directory for video files (videos are large — needs proper lifecycle)
  • Configurable TTL with cron-based cleanup
  • Integrates with existing temp file patterns (see data-machine-socials#42)

6. Transcoding (future / optional)

  • Convert between formats (e.g. MOV → MP4/H.264)
  • Resize/re-encode to meet platform constraints
  • This may require ffmpeg on the server — should be optional and gracefully degrade
  • v1 can skip this and just validate + reject incompatible formats

Abilities API

Register core video abilities that extensions consume:

Ability Purpose
datamachine/upload-video Upload video file, return reference
datamachine/validate-video Validate against constraint set
datamachine/video-metadata Extract duration, resolution, codec, etc.
datamachine/video-thumbnail Generate thumbnail image from video

How Extensions Consume This

data-machine-socials example:

// In InstagramPublishAbility, when publishing a Reel:
$video = wp_get_ability('datamachine/video-metadata')->execute(['path' => $video_path]);
$valid = wp_get_ability('datamachine/validate-video')->execute([
    'path' => $video_path,
    'constraints' => InstagramSettings::get_reel_constraints(),
]);
if ($valid instanceof \WP_Error) {
    return $valid; // "Video exceeds 15 minute limit for Reels"
}
$thumbnail = wp_get_ability('datamachine/video-thumbnail')->execute(['path' => $video_path]);
// Then send video_url + cover_url to Instagram API

Any future extension:

// Event promo video, news wire clip, whatever
$meta = wp_get_ability('datamachine/video-metadata')->execute(['path' => $path]);
// duration: 45, resolution: 1920x1080, codec: h264, ...

Server Requirements

  • ffmpeg/ffprobe — standard tool for video metadata and thumbnail extraction. Available on most Linux servers, including Hetzner VPS.
  • Should detect availability at runtime and degrade gracefully (e.g. skip thumbnail generation if ffprobe not installed)
  • PHP's getID3 library is an alternative for metadata-only (no ffmpeg dependency) but can't generate thumbnails

Context

  • First consumer: data-machine-socials — needs video for Instagram Reels, Twitter video, Facebook video, Threads video, Pinterest video pins (data-machine-socials#41)
  • Upstream: extrachill-team — team members submit video content for approval (extrachill-team: Team dashboard plugin for team.extrachill.com extrachill-team#1)
  • Pattern: same as image primitives in core (GD engine, platform presets in PlatformPresets.php) — video follows the same layering

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions