@interactify-live/media-display
v1.0.10
Published
Pure JavaScript library for displaying videos and images
Maintainers
Readme
@interactify-live/media-display
A pure JavaScript library for displaying videos and images with a simple, lightweight API. Supports HLS streams, camera streams, and provides comprehensive media playback controls.
Features
- Pure JavaScript: Minimal dependencies, works in any modern browser
- Image Support: Display images with various object-fit options
- Video Support: Full video player functionality with controls
- HLS Support: Native HLS stream playback using HLS.js
- Camera Streams: Support for live camera/media streams
- TypeScript: Complete TypeScript support with type definitions
- Lightweight: Optimized bundle size for performance
- Flexible: Customizable styling and behavior options
- Event-driven: Rich event system for media interactions
- SSR Safe: Dynamic imports prevent server-side rendering issues
Installation
npm install @interactify-live/media-displayQuick Start
Basic Usage
import { MediaDisplay } from "@interactify-live/media-display";
// Create a media display instance
const mediaDisplay = new MediaDisplay({
width: 400,
height: 300,
objectFit: "contain",
});
// Add to DOM
document.body.appendChild(mediaDisplay.element);
// Load an image
mediaDisplay.load({
id: "image1",
type: "image",
url: "https://example.com/image.jpg",
alt: "Sample image",
});
// Load a video
mediaDisplay.load({
id: "video1",
type: "video",
url: "https://example.com/video.mp4",
});
// Load an HLS stream
mediaDisplay.load({
id: "hls-stream",
type: "video",
url: "https://example.com/stream.m3u8",
});
// Play the video
await mediaDisplay.play();
### With TypeScript
```typescript
import {
MediaDisplay,
MediaItem,
MediaDisplayOptions,
} from "@interactify-live/media-display";
const options: MediaDisplayOptions = {
width: 400,
height: 300,
autoplay: true,
muted: true,
loop: true,
controls: true,
objectFit: "contain",
backgroundColor: "#000000",
onLoad: (media: MediaItem) => console.log("Media loaded:", media),
onError: (media: MediaItem, error: Error) => console.error("Error:", error),
onPlay: (media: MediaItem) => console.log("Started playing:", media),
onPause: (media: MediaItem) => console.log("Paused:", media),
onEnded: (media: MediaItem) => console.log("Ended:", media),
};
const mediaDisplay = new MediaDisplay(options);Camera Stream Support
// Get camera stream
navigator.mediaDevices
.getUserMedia({ video: true })
.then((stream) => {
// Load camera stream
mediaDisplay.loadStream(stream);
})
.catch((error) => {
console.error("Failed to get camera stream:", error);
});API Reference
MediaDisplay Constructor
new MediaDisplay(options?: MediaDisplayOptions)Options
width?: number | string- Width of the containerheight?: number | string- Height of the containerautoplay?: boolean- Auto-play videos (default: false)muted?: boolean- Start videos muted (default: false)loop?: boolean- Loop videos (default: false)controls?: boolean- Show video controls (default: false)objectFit?: "contain" | "cover" | "fill" | "none" | "scale-down"- CSS object-fit property (default: "contain")backgroundColor?: string- Background color of the containeronLoad?: (media: MediaItem) => void- Called when media loads successfullyonError?: (media: MediaItem, error: Error) => void- Called when media fails to loadonPlay?: (media: MediaItem) => void- Called when video starts playingonPause?: (media: MediaItem) => void- Called when video is pausedonEnded?: (media: MediaItem) => void- Called when video endsonVideoReady?: (videoElement: HTMLVideoElement) => void- Called when video element is ready
MediaDisplay Methods
load(media: MediaItem): void
Loads a new media item (image or video). Automatically handles HLS streams (.m3u8 files).
loadStream(stream: MediaStream): void
Loads a camera or media stream. Automatically creates a video element and starts playback.
play(): Promise<void>
Plays the current video. Throws error if current media is not a video.
pause(): void
Pauses the current video. No effect if current media is not a video.
destroy(): void
Destroys the current media element and cleans up resources (including HLS instances).
getCurrentTime(): number
Returns the current playback time of the video (0 for images).
getDuration(): number
Returns the total duration of the video (0 for images).
setCurrentTime(time: number): void
Sets the current playback time of the video.
setVolume(volume: number): void
Sets the volume of the video (0-1).
getVolume(): number
Returns the current volume of the video (0-1).
mute(): void
Mutes the video.
unmute(): void
Unmutes the video.
isMuted(): boolean
Returns true if the video is muted.
isPlaying(): boolean
Returns true if the video is currently playing.
getCurrentMedia(): MediaItem | null
Returns the currently loaded media item.
updateOptions(newOptions: Partial<MediaDisplayOptions>): void
Updates the display options dynamically.
MediaItem Interface
interface MediaItem {
id: string; // Unique identifier
type: "image" | "video"; // Media type
url: string; // Media URL (supports .m3u8 for HLS)
thumbnail?: string; // Optional thumbnail URL
alt?: string; // Optional alt text for images
}Utility Functions
The library also exports utility functions for advanced use cases:
import {
isValidUrl,
validateMediaItem,
createContainer,
createImageElement,
createVideoElement,
addMediaEventListeners,
} from "@interactify-live/media-display";Examples
Image Gallery
const gallery = new MediaDisplay({
width: 600,
height: 400,
objectFit: "cover",
});
const images = [
{ id: "1", type: "image", url: "image1.jpg" },
{ id: "2", type: "image", url: "image2.jpg" },
{ id: "3", type: "image", url: "image3.jpg" },
];
let currentIndex = 0;
function showNext() {
currentIndex = (currentIndex + 1) % images.length;
gallery.load(images[currentIndex]);
}
function showPrevious() {
currentIndex = (currentIndex - 1 + images.length) % images.length;
gallery.load(images[currentIndex]);
}HLS Stream Player
const hlsPlayer = new MediaDisplay({
width: 800,
height: 450,
controls: true,
autoplay: false,
muted: false,
onLoad: (media) => console.log("HLS stream loaded:", media),
onError: (media, error) => console.error("HLS error:", error),
});
// Load HLS stream
hlsPlayer.load({
id: "live-stream",
type: "video",
url: "https://example.com/live/stream.m3u8",
});Camera Stream with Controls
const cameraDisplay = new MediaDisplay({
width: 640,
height: 480,
objectFit: "cover",
onVideoReady: (videoElement) => {
console.log("Camera stream ready");
// Custom video element setup
},
});
// Start camera
async function startCamera() {
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: 640, height: 480 },
audio: false,
});
cameraDisplay.loadStream(stream);
} catch (error) {
console.error("Failed to start camera:", error);
}
}
// Stop camera
function stopCamera() {
cameraDisplay.destroy();
}Video Player with Controls
const videoPlayer = new MediaDisplay({
width: 800,
height: 450,
controls: true,
autoplay: false,
muted: false,
onPlay: (media) => console.log("Video started playing"),
onPause: (media) => console.log("Video paused"),
onEnded: (media) => console.log("Video ended"),
});
// Custom controls
const playButton = document.getElementById("play-btn");
const pauseButton = document.getElementById("pause-btn");
const muteButton = document.getElementById("mute-btn");
const progressBar = document.getElementById("progress");
playButton.addEventListener("click", () => videoPlayer.play());
pauseButton.addEventListener("click", () => videoPlayer.pause());
muteButton.addEventListener("click", () => {
if (videoPlayer.isMuted()) {
videoPlayer.unmute();
muteButton.textContent = "Mute";
} else {
videoPlayer.mute();
muteButton.textContent = "Unmute";
}
});
// Update progress bar
setInterval(() => {
const current = videoPlayer.getCurrentTime();
const duration = videoPlayer.getDuration();
const progress = (current / duration) * 100;
progressBar.style.width = `${progress}%`;
}, 100);Responsive Media Display
const responsiveDisplay = new MediaDisplay({
width: "100%",
height: "100vh",
objectFit: "contain",
backgroundColor: "#f0f0f0",
});
// Update options on window resize
window.addEventListener("resize", () => {
responsiveDisplay.updateOptions({
width: window.innerWidth,
height: window.innerHeight,
});
});Dependencies
- hls.js: For HLS stream playback (automatically imported when needed)
- tslib: TypeScript runtime helpers
Browser Support
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
License
MIT
