Statamic addon for 3q.video hosting platform integration

Maintainers

Package info

github.com/takepart-media/vidiq

Type:statamic-addon

pkg:composer/takepart-media/vidiq

Statistics

Installs: 22

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.4 2026-04-16 12:32 UTC

This package is auto-updated.

Last update: 2026-04-16 12:38:13 UTC


README

Latest Version on Packagist License PHP Version Statamic

A Statamic addon that integrates the 3q.video hosting platform into the Statamic Control Panel asset browser. Videos hosted on 3q appear as browsable, deletable assets with thumbnail previews. A Blade component is provided for embedding videos in frontend templates.

This addon has only been tested with Statamic 5 and 3Q's SDN API v2.

Features

  • Asset browser integration — 3Q videos appear in Statamic's CP file browser with thumbnail previews and release-status colour strips (published / unpublished / draft)
  • Asset editor player — opening a video in the CP asset editor replaces the default <video> element with the 3Q player iframe
  • Fieldtype support — videos selected via an Assets fieldtype display thumbnails and status indicators in entry forms
  • Read-only (for now) — browse videos directly from the CP; write operations (upload, delete, rename, move) are currently unsupported — manage content in 3Q's own dashboard. Full write support may be added in a future release.
  • CP Cache Utility — manage the vidiq cache directly from the Statamic Control Panel (Utilities → vidiQ Cache) with Warm and Clear buttons
  • Cache warm-up commandvidiq:warm-cache Artisan command pre-populates listing and embed-code caches during deployment
  • Flysystem v3 adapter — custom ThreeQAdapter implements the Flysystem interface backed by the 3Q SDN API
  • Embed codes — fetches the full FileEmbedCodes array per video via the 3Q playout API (cached)
  • Virtual meta files — generates .meta/ YAML on the fly so Statamic stores title, thumbnail URL, video ID and release status without writing to disk
  • Blade component<x-vidiq::embed> for embedding the 3Q player in frontend templates

Requirements

  • PHP 8.3+
  • Statamic 5.x
  • GuzzleHTTP 7.x
  • A 3q.video account with API access

Installation

Install the package via Composer:

composer require takepart-media/vidiq

Statamic will auto-discover the addon's service provider. No additional registration steps are needed.

Environment variables

Add the following to your .env file:

VIDIQ_API_TOKEN=your-api-token-here
VIDIQ_PROJECT_ID=your-project-id-here

# Optional — defaults shown
VIDIQ_API_ENDPOINT=https://sdn.3qsdn.com/api
VIDIQ_API_TIMEOUT=30

Asset container

Create content/assets/vidiq.yaml in your Statamic project:

title: '3Q Videos'
disk: 3q
allow_uploads: false
allow_downloading: false
allow_renaming: false
allow_moving: false
create_folders: false

Statamic will display this container as "3Q Videos" in the CP under Assets.

How It Works

Flysystem adapter (ThreeQAdapter)

The adapter connects to the 3Q SDN REST API and implements League\Flysystem\FilesystemAdapter:

Operation Behaviour
listContents Fetches all files from GET /v2/projects/{id}/files and yields FileAttributes. Listing is cached for 1 hour by default (configurable via VIDIQ_CACHE_TTL).
fileExists Resolved from the listing cache.
read For .meta/ paths: returns generated YAML. Direct reads of asset paths are not supported and throw UnableToReadFile.
readStream For .meta/ paths: streams the generated YAML. For asset paths: downloads the video thumbnail from 3Q for Statamic/Glide to cache.
delete Accepted only for .meta/ paths (no-op, virtual files have no remote counterpart). All other paths throw UnableToDeleteFile.
getUrl Calls GET /v2/projects/{id}/files/{fileId}/playouts/default/embed and returns the full FileEmbedCodes array (e.g. JavaScript, PlayerURL). Cached per file ID via VIDIQ_CACHE_TTL.
write / writeStream Accepted only for .meta/ paths (Statamic metadata edits stored in Laravel cache). All other writes throw UnableToWriteFile.
move, copy, createDirectory, deleteDirectory Not supported; throw the corresponding Flysystem exceptions.

Path convention

Each video's path is its sanitized display title (e.g. My Interview.mp4). If two videos share the same title, the last 6 characters of the FileId are appended to avoid collisions. The FileId→path mapping is stored in the listing cache.

Virtual meta files

listContents also yields a virtual .meta/{path}.yaml entry for every video. This YAML contains:

size: 12345678
last_modified: 1700000000
mime_type: 'video/mp4'
data:
  alt: 'Video title'
  thumbnail_url: 'https://...'
  video_id: '12345678'
  release_status: 'published'

Statamic reads this file automatically; because the file exists virtually, Statamic skips calling writeMeta() and leaves the adapter's read-only behaviour intact.

CP JavaScript (thumbnail injection, status strips & player)

Statamic's asset browser only renders thumbnail images for assets where is_image: true. The addon registers an Axios response interceptor (via Statamic.booted()) that enriches several CP views:

  1. Asset browser — intercepts folder listing responses for any 3Q-backed container, fetches the thumbnail & status map from GET /cp/vidiq/assets (once per page load), and injects is_image: true + thumbnail: <url> into each asset object. A coloured left-edge strip is added to each thumbnail to indicate the release status (green = published, yellow = unpublished, grey = draft).
  2. Asset editor — when a 3Q video is opened in the editor modal, the default <video> element is replaced with a 3Q player iframe fetched from GET /cp/vidiq/player-url.
  3. Assets fieldtype — when an entry form contains an Assets field referencing a 3Q container, the interceptor injects thumbnails and status indicators into the fieldtype row display.

Blade Component

<x-vidiq::embed>

Embeds a 3Q video using one of three output methods. The method defaults to the config value vidiq.embed_fallback_method (default: JavaScript).

{{-- Default method from config --}}
<x-vidiq::embed :asset="$asset" />

{{-- Explicit method --}}
<x-vidiq::embed :asset="$asset" method="iFrame" />

Props

Prop Type Default Description
asset Statamic\Assets\Asset|null null The asset object. Renders nothing if null or if no player URL can be resolved.
method string|null config('vidiq.embed_fallback_method') Embed output method: JavaScript, iFrame, or PlayerURL.

Methods

Value Output
JavaScript Renders the JS embed snippet ({!! $embedCodes['JavaScript'] !!}) provided by 3Q.
iFrame Renders an <iframe> with the PlayerURL as src and the video-embed CSS class.
PlayerURL Outputs only the plain player URL string (useful for custom markup or JS integration).

Configuration

config/vidiq.php (addon)

Key Env variable Default Description
cache.ttl VIDIQ_CACHE_TTL 3600 Cache TTL in seconds for listings and embed codes
cache.permanent VIDIQ_CACHE_PERMANENT false When true, caches are stored forever (ignores TTL)
cache.prefix vidiq Prefix for all cache keys (scoped per project ID)
embed_fallback_method VIDIQ_FALLBACK_METHOD JavaScript Default embed method (JavaScript, iFrame, PlayerURL)

config/vidiq-disk.php (addon)

Configures the 3q Laravel filesystem disk that is registered automatically by the ServiceProvider. The disk uses the custom 3q driver backed by ThreeQAdapter.

Key Env variable Default Description
api_token VIDIQ_API_TOKEN 3Q API token
project_id VIDIQ_PROJECT_ID 3Q project identifier
endpoint VIDIQ_API_ENDPOINT https://sdn.3qsdn.com/api 3Q API base URL
timeout VIDIQ_API_TIMEOUT 30 HTTP timeout in seconds

Multiple Projects

To connect a second 3Q project, add another disk entry in config/filesystems.php and a matching asset container YAML:

// config/filesystems.php
'3q-project-b' => [
    'driver'     => '3q',
    'api_token'  => env('VIDIQ_PROJECT_B_API_TOKEN', ''), // or use your default token VIDIQ_API_TOKEN
    'project_id' => env('VIDIQ_PROJECT_B_PROJECT_ID', ''),
    'endpoint'   => env('VIDIQ_API_ENDPOINT', 'https://sdn.3qsdn.com/api'),
    'timeout'    => env('VIDIQ_API_TIMEOUT', 30),
],
# content/assets/vidiq-project-b.yaml
title: '3Q Videos — Project B'
disk: 3q-project-b
allow_uploads: false
allow_downloading: false
allow_renaming: false
allow_moving: false
create_folders: false

After that update .env with the new credentials and clear or refresh caches:

php artisan cache:clear
php artisan config:clear

Development

Clone the repository and install dependencies:

git clone https://github.com/takepart-media/vidiq.git
cd vidiq
composer install
npm install

Build CP assets

npm run dev      # Vite dev server
npm run build    # Production build

Cache management

CP Utility

The addon registers a vidiQ Cache utility in the Statamic Control Panel under Utilities → vidiQ Cache. It displays the number of cached videos and the current cache mode (TTL or Permanent). Two actions are available:

  • Warm — dispatches a background queue job (WarmCacheJob) that flushes all vidiq caches, re-fetches the listing from the 3Q API, and pre-fetches embed codes for every video.
  • Clear — immediately flushes all vidiq-specific cache entries (listing, embed codes, meta edits).

Warm the cache (CLI)

Pre-populate the video listing cache (and optionally embed codes) so the first frontend request avoids an API round-trip:

php artisan vidiq:warm-cache           # Warm listing cache only
php artisan vidiq:warm-cache --embed   # Also pre-fetch embed codes for every video

This is intended to run once during deployment (e.g. in a post-deploy script or CI pipeline).

Flush caches

php artisan cache:clear                # Flush all Laravel caches (including vidiq)
php artisan statamic:stache:clear      # Clear Statamic file cache
php artisan config:clear               # Clear Laravel config cache

The vidiq:warm-cache command automatically flushes all vidiq-specific cache entries (listing, embed codes, meta edits) before re-populating.

License

The MIT License (MIT). Please see the LICENSE file for more information.