Videos — Reference
The Videos surface is the video-asset plane for every SGEN site. It owns the video record, the source binding (uploaded file or external host), the thumbnail and transcript artifacts, and the embed handles used by pages, posts, and templates. Anything that surfaces as a playable video on a published page traces back to a record managed here.
This page is a reference for platform engineers and integrators who need to understand the surface before extending it, scripting against it, or scoping a media-handling tier. Customer-facing how-tos live in the customer docs set; this page describes the shape of the surface, not the steps to drive it.
Overview
Videos live under the Videos module in SG-Admin. The module renders three primary views — the video list, the video detail page (player preview, source info, thumbnail picker, transcript editor), and the embed-handle index — and exposes a small set of write operations for create, edit, thumbnail update, transcript edit, caption upload, soft delete, and restore.
The module is paired by convention with the Media library and with the Gallery module. Media holds raw uploaded file artifacts; Gallery curates ordered image sets; Videos covers both uploaded video files and externally-hosted embeds (YouTube, Vimeo, and any oEmbed-compatible source) under a single record shape. The split exists because video assets carry artifacts that images do not — captions, transcripts, multiple encoded variants — and benefit from a dedicated curation plane.
A second surface — transcripts and captions — lives inside each video record. Operators can paste a transcript, upload a caption file (WebVTT or SRT), or trigger an automatic transcript generation if the site's media-services tier supports it. Transcripts surface as a separate text block under the player; captions surface inline on the player itself.
Where it lives in SG-Admin:
- Sidebar: SG-Admin → Videos
- URL prefix:
/sg-admin/videos/ - View templates:
application/views/Admin/Videos/
┌──────────────────────────────────────────────────────────────────────┐│ SG-Admin → Videos [+ Add video] │├──────────────────────────────────────────────────────────────────────┤│ Title Source Duration Used on Updated ││ ────────────────────────── ─────────── ──────── ─────── ────────││ Product walkthrough Upload 4:12 3 pages 2h ago ││ Founder welcome Upload 1:38 Homepage 1d ago ││ Q1 webinar replay YouTube 58:24 1 post 4d ago ││ Customer story — Maria Vimeo 7:55 About 1w ago ││ Feature demo — invoices Upload 2:08 Docs 2w ago ││ ││ Filter: [Source ▼] [Captioned ▼] Bulk: [Regenerate thumbs] │└──────────────────────────────────────────────────────────────────────┘Actions
The Videos surface exposes the following operations. Each is described by what it does to the data, not by its internal method name.
List and search
Returns the video records visible to the current operator, paginated, with title, source, duration, usage count, and updated-at columns. Supports column sort, free-text filter, source filter (upload / YouTube / Vimeo / other), and captioned filter. Driven by the data-table contract used across SG-Admin modules — responses arrive as a row collection plus a total count, suitable for direct binding to a paged grid.
View detail
Loads the full video record into a read-mostly detail page — player preview, source info, thumbnail picker, transcript block, caption tracks list, and usage list. Editable fields are gated behind separate actions; the detail page itself does not write.
Add upload
Opens the upload composer. Operator selects a local video file; the surface streams the file to the configured storage backend, runs encoding (if the site's media-services tier supports it), generates a default thumbnail at the 10% mark, and persists the record. Required at minimum: title. Optional fields cover description, language, default thumbnail override, and tag list.
Engineering note: encoding runs asynchronously. The record persists immediately withsource_status = processing; the storefront player either shows a placeholder or hides the block untilsource_status = ready. The transition emits a webhook event for any subscribed integration.
Add embed
Opens the embed composer. Operator pastes an external URL (YouTube, Vimeo, or any oEmbed-compatible source); the surface resolves the URL against the provider's oEmbed endpoint, caches the response (player iframe, default thumbnail, duration, title), and persists the record. The cached oEmbed response is refreshed on a schedule and on manual demand.
Engineering note: embedded videos do not consume storage. The record holds only the source URL and the cached oEmbed payload. Bandwidth and analytics flow through the external provider.
Edit video
Loads an existing record into the edit form, pre-populated. Editable fields cover title, description, language, tags, default thumbnail, transcript, and caption tracks. Source binding (file or external URL) is not editable — replacing the source means creating a new record and updating the usage references. The form is partial-update by default.
Set thumbnail
A focused write path. Operator can pick a frame from the player scrub, upload a custom thumbnail image, or revert to the auto-generated default. The selected thumbnail surfaces in the list view, in playback overlays before the user clicks play, and in any embed that requests the canonical poster image.
Edit transcript
Replaces the stored transcript text. Transcripts are plain text or lightly-formatted Markdown; the surface does not enforce time-code alignment. For time-coded transcripts that drive captions, use the caption-track upload path instead.
Upload caption track
Accepts a WebVTT or SRT file and binds it to the record as a caption track. A record may carry multiple tracks (one per language). Operator picks the default track that auto-loads on play; viewers can switch tracks from the player UI.
Regenerate thumbnail
Re-runs the auto-thumbnail generation against the current source. For uploaded videos, regenerates from the source file at the configured frame mark. For embedded videos, re-fetches the oEmbed response and caches the provider's default thumbnail. Useful when the source has changed externally or the default frame is unsuitable.
Soft delete
Marks the record inactive without removing it from the database or the underlying storage object. Soft-deleted videos disappear from the default list view but remain queryable via the archive filter. References from pages and posts resolve to an empty render until the video is restored or replaced.
Restore
Reverses a soft delete. The record returns to the active list with its prior source binding, thumbnail, transcript, and caption tracks intact. Encoding state is preserved across the cycle.
Permanent delete
Hard-removes the record and, for uploaded videos, removes the underlying storage object. Available only after a soft delete. The surface returns a structured list of affected pages so operators can scope a replacement plan. This path is irreversible.
Data model
A video record carries the following fields. Field names below are the conceptual shape — the on-disk column names match closely but are not contractually stable across releases.
| Field | Type | Notes |
|---|---|---|
id | integer | Primary key. Stable across edits. |
slug | string | Unique. Used in the embed handle {{video:. |
title | string | Display name. Not unique. |
description | string | Optional. Surfaced to player overlay and meta tags. |
source_type | enum | upload, youtube, vimeo, oembed-other. |
source_url | string | Set for embedded sources. Empty for uploads. |
storage_key | string | Set for uploads. References the storage backend object. |
source_status | enum | processing, ready, failed. |
duration_sec | integer | Computed at encode time or from oEmbed response. |
thumbnail_url | string | Resolves against the Media library or a cached oEmbed asset. |
language | string | ISO 639-1 code. Optional. |
transcript | string | Plain text or Markdown. Optional. |
caption_tracks | array | Per-language WebVTT / SRT bindings — see below. |
usage | array | Computed at scan time — pages / posts / templates that reference this video. |
status | enum | active, inactive (soft-deleted), or archived. |
created_at | timestamp | Set on create, immutable. |
updated_at | timestamp | Touched on any edit. |
caption_tracks carries:| Field | Type | Notes |
|---|---|---|
language | string | ISO 639-1 code. Unique per video. |
label | string | Display name shown in the player track picker. |
format | enum | vtt or srt. |
storage_key | string | References the caption file in the storage backend. |
is_default | boolean | Exactly one track per video may carry the default flag. |
source_type discriminates the record's binding. Uploads carry a storage_key and an encoding lifecycle (processing → ready or failed); embeds carry a source_url and a cached oEmbed response that refreshes on a schedule. The player surfaces both as a unified playback experience.Soft-delete semantics: status = inactive is the soft-deleted state. For uploads, the storage object is retained until permanent delete. For embeds, no storage cleanup is needed; the record hides from active views.
Caption track defaults: the is_default flag is constrained — at most one track per video may hold it. Setting a new default releases the prior one. The viewer's selection in the player UI is persisted to the visitor's local preferences and overrides the default on return visits.
VIDEO RECORD├── id integer primary key├── slug string unique, drives {{video:<slug>}} handle├── title string display├── source binding source_type + (source_url | storage_key) + source_status├── duration_sec integer from encode or oEmbed├── thumbnail_url string default frame or custom override├── transcript string plain text, optional├── caption_tracks array per-language WebVTT/SRT, one default├── usage array computed scan — pages/posts that reference├── status enum active | inactive | archived└── timestamps created_at, updated_at↓ playback resolvesSTORAGE BACKEND (uploads) OR EXTERNAL PROVIDER (embeds)encoded variants, poster iframe, poster, bandwidthPermissions
Access to the Videos surface is gated at two layers.
Layer 1 — admin gate. Every action under SG-Admin passes through the platform's standard admin access check at request entry. An unauthenticated request never reaches the Videos surface.
Layer 2 — per-action capability. Within SG-Admin, each Videos action checks a capability associated with the calling operator's role. The default role configuration ships with three media-adjacent roles — Content Editor, Designer, Read-only Reviewer — layered on top of the platform's base roles. The capability map is:
| Capability | Administrator | Content Editor | Designer | Reviewer |
|---|---|---|---|---|
| List videos | ✔ | ✔ | ✔ | ✔ |
| View detail | ✔ | ✔ | ✔ | ✔ |
| Add upload | ✔ | ✔ | — | — |
| Add embed | ✔ | ✔ | ✔ | — |
| Edit video metadata | ✔ | ✔ | ✔ | — |
| Set thumbnail | ✔ | ✔ | ✔ | — |
| Edit transcript | ✔ | ✔ | — | — |
| Upload caption track | ✔ | ✔ | — | — |
| Regenerate thumbnail | ✔ | ✔ | ✔ | — |
| Soft delete | ✔ | ✔ | — | — |
| Restore | ✔ | ✔ | — | — |
| Permanent delete | ✔ | — | — | — |
Self-protection rules. A video referenced by published pages or posts cannot be permanently deleted without an explicit override capability; the surface returns the affected list as a structured rejection. Upload records in source_status = processing cannot be edited or deleted until the encoder completes or fails.
Audit. Every write — create, edit, thumbnail set, transcript edit, caption upload, regenerate, soft delete, restore, permanent delete — emits an Activity Log entry. The log records the acting operator, the target record, and the change shape. Activity Log retention is governed by the site's general settings.
REQUEST│▼┌───────────────────────────┐│ Admin gate │ unauth → reject└─────────────┬─────────────┘│ authed▼┌───────────────────────────┐│ Capability check │ role lacks cap → reject│ (per-action, per-role) │└─────────────┬─────────────┘│ allowed▼┌───────────────────────────┐│ Source-state + usage │ processing → block; in-use delete│ guards │ → require override└─────────────┬─────────────┘│ passes▼action executes│▼Storage/CDN/oEmbed updatedActivity Log entry writtenRelated references
- Media — Reference. Owns the storage backend that uploaded video files persist to. Thumbnail images resolve against the Media library for both uploaded and embedded video records.
- Gallery — Reference. The image-collection analogue of this surface. Curated video collections share the embed-handle pattern.
- Pages — Reference. Page content references videos via the
{{video:handle. The usage scan reads from page content.}} - Posts — Reference. Blog posts reference videos the same way pages do. Permanent delete of an in-use video returns the affected post list.
- Custom Codes — Reference. Player customization (autoplay defaults, control overlays, player skin) lives in the template surfaces. The video handle resolves against the same record from any template.
- Settings — Reference. Owns the media-services tier (encoding behavior), the storage backend selection, and the oEmbed provider allowlist.
/docs/videos.