@cherryblossomdevelopment/foto-video-component
v1.0.1
Published
A self contained Web Component for video and photos
Readme
Foto Video Web Component
A self contained Web Component for video and photos
Having run into multiple issues with most of features listed below, I've developed this self contained, drop in web component. It is cross browser, cross device, cross framework compatible
- Noise reduction using RNNoise WASM
- Normalization to MP4 in all browsers, because Apple, using FFMPEG WASM
- Pause and resume video recording (hello all other recorders I could find that do not have this)
- Captioning (with recording audio at same time, if needed)
Features
- Video recording with pause/resume functionality
- Photo capture mode
- Camera switching (front/back)
- Zoom controls with pinch-to-zoom support
- Noise filtering integration
- Mobile-responsive design
- Touch-friendly interface
Dependencies
- RecordRTC: For video/audio recording
- fix-webm-duration: For fixing WebM video duration metadata
- Noise Filter Component: Custom web component for audio noise suppression
Project Structure
src/
├── foto-video.ts # Main web component class
├── foto-video.css # Component styles
├── main.ts # Demo application
├── style.css # Demo page styles
├── noisefilter/ # Noise filter web component
│ ├── noise-filter.js
│ ├── noise-filter.umd.cjs
│ └── assets/
└── vite-env.d.ts # TypeScript environment definitionsUsage
Basic HTML Usage
<!DOCTYPE html>
<html>
<head>
<script type="module" src="./dist/foto-video.js"></script>
</head>
<body>
<foto-video id="my-video-component"></foto-video>
<script>
const component = document.getElementById('my-video-component');
// Show video recorder
component.show();
// Enable photo mode
component.setTakePhoto(true);
// Listen for events
component.addEventListener('video-recorded', (event) => {
console.log('Video recorded:', event.detail);
});
component.addEventListener('photo-taken', (event) => {
console.log('Photo taken:', event.detail);
});
</script>
</body>
</html>Attributes
take-photo: Boolean attribute to enable photo capture modedisplay: Boolean attribute to show/hide the component
Methods
show(): Display the componenthide(): Hide the componentsetTakePhoto(boolean): Enable/disable photo capture mode
Events
close: Fired when the component is closedvideo-recorded: Fired when a video is recorded (detail contains blob)photo-taken: Fired when a photo is captured (detail contains blob and thumbnail)
Development
Prerequisites
- Node.js (v16 or higher)
- npm or yarn
Installation
cd foto-video-component
npm installDevelopment Server
npm run devThis will start the Vite development server with hot reload.
Build
npm run buildThis will create a production build in the dist folder.
Preview Production Build
npm run previewBrowser Support
- Modern browsers with WebRTC support
- Mobile browsers (iOS Safari, Chrome Mobile, etc.)
- Desktop browsers (Chrome, Firefox, Safari, Edge)
Permissions Required
- Camera access (
navigator.mediaDevices.getUserMedia) - Microphone access (for video recording with audio)
Notes
- The component uses Shadow DOM for style encapsulation
- Mobile devices require HTTPS for camera access
- The noise filter component is included as a separate web component
- Zoom functionality requires devices with zoom capabilities, but will use digital zoom on unsupported devices.
- The component handles mobile orientation changes automatically
Files Overview
src/foto-video.ts: The main web component class with all functionalitydemo.html: A standalone demo page for testing the componentvite.config.ts: Configuration for building the component as a libraryDEPLOYMENT.md: Comprehensive deployment and integration guide
API Usage
const component = document.querySelector('foto-video');
// Show video recorder
component.setTakePhoto(false);
// Show photo capture
component.setTakePhoto(true);
// Hide component
component.hide();
// Listen for events
component.addEventListener('video-recorded', (event) => {
console.log('Video blob:', event.detail.blob);
});
component.addEventListener('photo-taken', (event) => {
console.log('Photo blob:', event.detail.blob);
});