@saebyn/glowing-telegram-video-editor
v0.3.1
Published
A video editor component for glowing-telegram
Downloads
320
Readme
Glowing Telegram Video Editor
A React TypeScript component library for reviewing and editing video highlights, moments requiring attention, and transcription errors. Provides synchronized video/audio playback while reviewing AI-generated information.
This is part of the larger glowing-telegram tool: https://github.com/saebyn/glowing-telegram
Installation
Install the package via npm:
npm install @saebyn/glowing-telegram-video-editorOr via yarn:
yarn add @saebyn/glowing-telegram-video-editorPeer Dependencies
This library requires React 19.x as a peer dependency:
npm install react react-domImporting Styles
Don't forget to import the CSS file in your application:
import '@saebyn/glowing-telegram-video-editor/styles.css';Available Components
The library exports the following components:
VideoSelectionPage- Main page component for video review and clip selectionVideoPreview- Preview component for rendering videos with audio mixingProjectClipPool- Pool of available clips that can be added to a timelineProjectClipTimeline- Interactive timeline for arranging and editing clipsProjectClipPreview- Visual preview of individual video clips with thumbnailsAudioChannelNameEditor- Inline editor for audio channel names
All TypeScript types are also exported for use in your application.
Component Usage
VideoSelectionPage
The main component for reviewing video content with AI-generated highlights, attentions, and transcription errors. Provides synchronized playback, timeline visualization, and clip selection.
Props:
interface VideoSelectionPageProps {
content: VideoMetadata; // Video metadata including highlights, attentions, etc.
onExport?: (clips: VideoClip[]) => void; // Callback when clips are exported
}Example:
import { VideoSelectionPage } from '@saebyn/glowing-telegram-video-editor';
import '@saebyn/glowing-telegram-video-editor/styles.css';
function App() {
const videoData = {
title: "My Gaming Stream",
video_url: "https://example.com/video.m3u8",
length: 3600000, // 1 hour in milliseconds
highlights: [],
attentions: [],
transcription_errors: [],
silences: [],
chat_history: [],
transcript: []
};
const handleExport = (clips) => {
console.log('Exporting clips:', clips);
// Send clips to your backend
};
return (
<VideoSelectionPage
content={videoData}
onExport={handleExport}
/>
);
}Features:
- Synchronized video player with HLS support
- Timeline with color-coded markers for highlights, attentions, and transcription errors
- Live transcript and chat history display
- Click-to-add clip selection from timeline
- Export selected clips for rendering
- Keyboard shortcuts for playback control
VideoPreview
Component for previewing rendered videos with audio mixing controls and timeline editing.
Props:
interface VideoPreviewProps {
settings: PreviewSettings; // Preview configuration
previewVideoUrl: string; // HLS stream URL
playheadPosition?: number; // Current playhead in ms
duration: number; // Total duration in ms
onSettingsChange?: (settings: PreviewSettings) => void;
onRegenerate?: (settings: PreviewSettings) => void;
onSave?: (settings: PreviewSettings) => void;
regenerating?: boolean;
saving?: boolean;
}Example:
import { VideoPreview } from '@saebyn/glowing-telegram-video-editor';
function PreviewPage() {
const [settings, setSettings] = useState({
cutlist: [
{ id: '1', start: 0, end: 30000 },
{ id: '2', start: 60000, end: 120000 }
],
audioChannels: [
{ id: 'ch1', name: 'Game Audio', level: 0.8, muted: false },
{ id: 'ch2', name: 'Microphone', level: 0.6, muted: false }
],
waveformData: []
});
return (
<VideoPreview
settings={settings}
previewVideoUrl="https://example.com/preview.m3u8"
duration={180000}
onSettingsChange={setSettings}
onRegenerate={(settings) => console.log('Regenerate with:', settings)}
onSave={(settings) => console.log('Save:', settings)}
/>
);
}ProjectClipPool
A pool of available video clips that can be dragged to a timeline.
Props:
interface ProjectClipPoolProps {
clips: VideoClip[]; // Available clips
thumbnails: Record<string, string>; // Thumbnail URLs by clip ID
keyframes: Record<string, string[]>; // Keyframe URLs for hover animation
titles: Record<string, string>; // Custom titles by clip ID
clipWidth?: string; // Width of each clip preview
clipHeight?: string; // Height of each clip preview
onClipSelect?: (clipId: string, selected: boolean) => void;
onTitleUpdate?: (clipId: string, newTitle: string) => void;
onDragStart?: (clipIds: string[]) => void;
showCheckboxes?: boolean;
}Example:
import { ProjectClipPool } from '@saebyn/glowing-telegram-video-editor';
function ClipManager() {
const clips = [
{ id: 'clip1', start: 0, end: 30000 },
{ id: 'clip2', start: 60000, end: 90000 }
];
const thumbnails = {
'clip1': 'https://example.com/thumb1.jpg',
'clip2': 'https://example.com/thumb2.jpg'
};
return (
<ProjectClipPool
clips={clips}
thumbnails={thumbnails}
keyframes={{}}
titles={{ 'clip1': 'Introduction', 'clip2': 'Highlights' }}
showCheckboxes={true}
onClipSelect={(id, selected) => console.log(`Clip ${id} ${selected ? 'selected' : 'deselected'}`)}
/>
);
}ProjectClipTimeline
Interactive timeline for arranging clips in sequence with drag-and-drop reordering and trimming.
Props:
interface ProjectClipTimelineProps {
clips: VideoClip[]; // Clips on the timeline
duration: number; // Total timeline duration in ms
thumbnails: Record<string, string>;
keyframes: Record<string, string[]>;
titles: Record<string, string>;
playheadPosition?: number;
height?: string;
onClipsReorder?: (clips: VideoClip[]) => void;
onClipRemove?: (clipId: string) => void;
onTitleUpdate?: (clipId: string, newTitle: string) => void;
onSeek?: (milliseconds: number) => void;
onClipsAdd?: (clipIds: string[], position: number) => void;
onClipTrim?: (clipId: string, newStart: number, newEnd: number) => void;
}Example:
import { ProjectClipTimeline } from '@saebyn/glowing-telegram-video-editor';
function Timeline() {
const [clips, setClips] = useState([
{ id: 'clip1', start: 0, end: 30000 },
{ id: 'clip2', start: 30000, end: 60000 }
]);
return (
<ProjectClipTimeline
clips={clips}
duration={180000}
thumbnails={{}}
keyframes={{}}
titles={{}}
onClipsReorder={setClips}
onClipRemove={(id) => setClips(clips.filter(c => c.id !== id))}
onClipTrim={(id, start, end) => {
setClips(clips.map(c => c.id === id ? { ...c, start, end } : c));
}}
/>
);
}ProjectClipPreview
Visual preview component for individual video clips with thumbnail and duration display.
Props:
interface ProjectClipPreviewProps {
id: string;
thumbnailUrl: string;
keyframeUrls: string[]; // URLs for hover animation
title?: string;
durationSeconds: number;
width: string;
height: string;
onTitleUpdate?: (id: string, newTitle: string) => void;
showCheckbox?: boolean;
onSelect?: (id: string, selected: boolean) => void;
}Example:
import { ProjectClipPreview } from '@saebyn/glowing-telegram-video-editor';
function ClipCard() {
return (
<ProjectClipPreview
id="clip1"
thumbnailUrl="https://example.com/thumb.jpg"
keyframeUrls={[]}
title="Epic Moment"
durationSeconds={45}
width="200px"
height="150px"
showCheckbox={false}
/>
);
}AudioChannelNameEditor
Inline editable component for audio channel names with click-to-edit functionality.
Props:
interface AudioChannelNameEditorProps {
name: string; // Current channel name
onNameChange: (name: string) => void;
disabled?: boolean;
placeholder?: string;
maxLength?: number; // Default: 50
}Example:
import { AudioChannelNameEditor } from '@saebyn/glowing-telegram-video-editor';
function AudioChannelRow() {
const [channelName, setChannelName] = useState('Game Audio');
return (
<AudioChannelNameEditor
name={channelName}
onNameChange={setChannelName}
placeholder="Channel Name"
/>
);
}TypeScript Types
The library exports all TypeScript types for use in your application:
import type {
VideoMetadata,
VideoClip,
Section,
AudioChannel,
PreviewSettings,
WaveformData,
TranscriptSegment,
ChatMessage
} from '@saebyn/glowing-telegram-video-editor';Key Types
VideoMetadata: Parsed video metadata for the frontend
title: Video titlevideo_url: HLS stream URLlength: Video duration in millisecondshighlights,attentions,transcription_errors,silences: Arrays ofSectionchat_history: Array ofChatMessagetranscript: Array ofTranscriptSegment
VideoClip: A selection within a video
id: Unique identifierstart: Start time in millisecondsend: End time in millisecondskeyframeSrc: Optional thumbnail URL
AudioChannel: Audio channel configuration
id: Channel identifiername: Display namelevel: Audio level (0.0 to 1.0)muted: Whether channel is muted
Overview
The Glowing Telegram Video Editor is a web-based Single Page Application (SPA) designed to review and edit video highlights, moments that require additional attention, and possible transcription errors, and select clips for rendering. This application aims to provide an intuitive interface for vetting and correcting data to feed into an automated pipeline that posts edited stream VODs to YouTube.
Goals
- Enable users to review, edit, and manage video highlights, attentions, and transcription errors efficiently
- Provide synchronized video/audio playback while reviewing AI-generated information
- Integrate seamlessly into the larger glowing-telegram tool ecosystem
- Ensure usability on various screen sizes, with a primary focus on desktop use
Key Features
- Video Review and Clip Selection: Browse AI-generated highlights, attentions, and transcription errors with synchronized video playback
- Interactive Timeline: Color-coded markers for different event types with zoom/pan functionality
- Clip Management: Select, reorder, and trim video clips with drag-and-drop interface
- Audio Mixing: Multi-channel audio control with per-channel muting and level adjustment
- Live Transcript: Real-time transcript and chat history display synchronized with video playback
- Keyboard Shortcuts: Efficient navigation with keyboard controls for playback and seeking
- HLS Video Support: Built-in support for HLS streaming with HLS.js
Design Decisions
- Component-Based Architecture: Modular design following atomic design principles (atoms, molecules, organisms, pages)
- TypeScript First: Full TypeScript support with exported types for all components
- Integrated Workflow: Designed to integrate directly into larger applications
- Responsive Layout: Primarily desktop-focused but adaptable to various screen sizes
Development
This project uses modern web development tools:
- Vite - Build tool and dev server
- React - UI framework (v19)
- TypeScript - Type safety
- Vitest - Unit testing
- Testing Library - Component testing
- Tailwind CSS - Styling (v4)
- Biome - Linting and formatting
- Storybook - Component development
- HLS.js - Video streaming
Getting Started
Clone the repository and install dependencies:
git clone https://github.com/saebyn/glowing-telegram-video-editor.git
cd glowing-telegram-video-editor
npm installDevelopment Commands
Start development mode (rebuild on changes):
npm run devRun Storybook (component development):
npm run storybookVisit http://localhost:6006 to view components in isolation.
Type checking:
npm run typecheckLinting:
npm run lintFormat code:
npm run formatBuilding
Build the library for production:
npm run buildThis creates ES module output in dist/ with TypeScript declarations.
Testing
Run unit tests:
npm run testInteractive test UI:
npm run test:uiVisit http://localhost:51204/vitest/ to interact with tests.
Project Structure
src/
├── components/
│ ├── atoms/ # Basic UI elements (buttons, inputs, etc.)
│ ├── molecules/ # Composite components (video player, dialogs, etc.)
│ ├── organisms/ # Complex components (timeline, sidebar, etc.)
│ └── pages/ # Full page components
├── context/ # React context providers
├── hooks/ # Custom React hooks
├── types.ts # TypeScript type definitions
├── utils/ # Utility functions
└── index.ts # Main library entry pointLicense
This project is licensed under the AGPL-3.0 License - see the LICENSE file for details.
