parevo-interactive-video
Version:
Framework-agnostic interactive video library with quiz overlays for React, Vue, and vanilla JS
333 lines (266 loc) ⢠8.18 kB
Markdown
Framework-agnostic interactive video library with quiz overlays for React, Vue, and vanilla JavaScript.
š„ **HTML5 Video Based**: Lightweight, no external video library dependencies
šÆ **Interactive Quizzes**: Automatic pause and quiz overlay at predefined times
š **Smart Rewind**: Wrong answers rewind to specified timestamps
š **Framework Agnostic**: Works with React, Vue, and vanilla JavaScript
š± **Universal Compatibility**: SSR-safe, works in all modern environments
šØ **Customizable**: Minimal styling, easy to customize
š **Event Tracking**: Comprehensive event system for progress monitoring
```bash
npm install @parevo/interactive-video
```
```html
<!DOCTYPE html>
<html>
<head>
<script type="module">
import { InteractiveVideo } from '@parevo/interactive-video';
const config = {
questions: [
{
id: 'q1',
triggerTime: 30, // Pause at 30 seconds
question: 'What is the main topic?',
options: [
{ id: 'a', text: 'Option A', isCorrect: true },
{ id: 'b', text: 'Option B', isCorrect: false }
],
rewindTime: 15 // Rewind to 15 seconds if wrong
}
]
};
const player = new InteractiveVideo('#video-container', {
src: '/path/to/video.mp4',
config: config,
width: 800,
height: 450,
onQuestionAnswered: (questionId, optionId, isCorrect) => {
console.log(`Question ${questionId}: ${isCorrect ? 'Correct' : 'Wrong'}`);
}
});
</script>
</head>
<body>
<div id="video-container"></div>
</body>
</html>
```
```tsx
import { InteractiveVideo } from '@parevo/interactive-video/react';
function App() {
const config = {
questions: [
{
id: 'q1',
triggerTime: 30,
question: 'What is the main topic?',
options: [
{ id: 'a', text: 'Option A', isCorrect: true },
{ id: 'b', text: 'Option B', isCorrect: false }
],
rewindTime: 15
}
]
};
return (
<InteractiveVideo
src="/path/to/video.mp4"
config={config}
width={800}
height={450}
onQuestionAnswered={(questionId, optionId, isCorrect) => {
console.log(`Question ${questionId}: ${isCorrect ? 'Correct' : 'Wrong'}`);
}}
/>
);
}
```
```vue
<template>
<InteractiveVideo
:src="videoSrc"
:config="config"
:width="800"
:height="450"
@question-answered="handleAnswer"
/>
</template>
<script setup>
import { InteractiveVideo } from '@parevo/interactive-video/vue';
const videoSrc = '/path/to/video.mp4';
const config = {
questions: [
{
id: 'q1',
triggerTime: 30,
question: 'What is the main topic?',
options: [
{ id: 'a', text: 'Option A', isCorrect: true },
{ id: 'b', text: 'Option B', isCorrect: false }
],
rewindTime: 15
}
]
};
const handleAnswer = (data) => {
console.log(`Question ${data.questionId}: ${data.isCorrect ? 'Correct' : 'Wrong'}`);
};
</script>
```
```tsx
import dynamic from 'next/dynamic';
const InteractiveVideo = dynamic(
() => import('@parevo/interactive-video/react').then(mod => mod.InteractiveVideo),
{ ssr: false }
);
export default function VideoPage() {
// ... same as React example
}
```
```typescript
interface InteractiveVideoOptions {
src: string; // Video source URL
config: InteractiveVideoConfig; // Quiz configuration
width?: number; // Video width (default: 640)
height?: number; // Video height (default: 360)
autoplay?: boolean; // Auto play video (default: false)
muted?: boolean; // Mute video (default: false)
controls?: boolean; // Show video controls (default: true)
className?: string; // CSS class name
onQuestionAnswered?: Function; // Question answered callback
onVideoEnd?: Function; // Video ended callback
onError?: Function; // Error callback
}
```
```typescript
interface InteractiveVideoConfig {
questions: QuizQuestion[];
}
interface QuizQuestion {
id: string; // Unique question ID
triggerTime: number; // When to show question (seconds)
question: string; // Question text
options: QuizOption[]; // Answer options
rewindTime: number; // Where to rewind on wrong answer (seconds)
}
interface QuizOption {
id: string; // Unique option ID
text: string; // Option text
isCorrect: boolean; // Whether this is the correct answer
}
```
```typescript
const player = new InteractiveVideo(container, options);
player.play(); // Play video
player.pause(); // Pause video
player.currentTime(); // Get current time
player.currentTime(30); // Set current time to 30 seconds
player.destroy(); // Clean up and remove
// Event listeners
player.on('questionAnswered', (data) => { /* ... */ });
player.on('videoEnd', () => { /* ... */ });
player.off('questionAnswered', callback);
```
```bash
git clone <repository-url>
cd interactive-video
npm install
npm run build
```
```bash
npm run dev-server
```
```bash
```
```
@parevo/interactive-video/
āāā core
āāā react
āāā vue
```
```javascript
// Core library (vanilla JS)
import { InteractiveVideo } from '@parevo/interactive-video';
import { InteractiveVideo } from '@parevo/interactive-video/core';
// React wrapper
import { InteractiveVideo } from '@parevo/interactive-video/react';
// Vue wrapper
import { InteractiveVideo } from '@parevo/interactive-video/vue';
```
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
- **Training Videos**: Corporate training with comprehension checks
- **Educational Content**: E-learning courses with interactive elements
- **Compliance Training**: Ensure understanding before progression
- **Product Demos**: Interactive product walkthroughs
The component uses minimal CSS classes that you can customize:
```css
.interactive-video-quiz-overlay { /* Overlay background */ }
.quiz-content { /* Quiz content box */ }
.quiz-question { /* Question text */ }
.quiz-options { /* Options container */ }
.quiz-option { /* Individual option button */ }
```
```javascript
player.on('questionAnswered', ({ questionId, optionId, isCorrect }) => {
// Handle question answer
});
player.on('videoEnd', () => {
// Handle video end
});
player.on('error', (error) => {
// Handle errors
});
```
```tsx
<InteractiveVideo
onQuestionAnswered={(questionId, optionId, isCorrect) => {}}
onVideoEnd={() => {}}
onError={(error) => {}}
/>
```
```vue
<InteractiveVideo
@question-answered="handleAnswer"
@video-end="handleEnd"
@error="handleError"
/>
```
MIT
1. Fork the repository
2. Create your feature branch
3. Commit your changes
4. Push to the branch
5. Create a Pull Request