videofolxtv/client/src/components/vast-ad-player.tsx
sebastjanartic 635f5eb197 Add monetization indicators and ad network management features
Introduce a new component for managing ad networks with detailed analytics and integrate VAST ad playback with Video.js, including an indicator for monetized content.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: d7424866-83d1-4486-a212-ac12b4c7becf
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/d7424866-83d1-4486-a212-ac12b4c7becf/A9pVG1H
2025-08-08 21:38:22 +00:00

123 lines
3.1 KiB
TypeScript

import { useEffect, useRef, useState } from 'react';
import videojs from 'video.js';
// @ts-ignore
import 'videojs-ima';
// @ts-ignore
import 'videojs-contrib-ads';
import 'video.js/dist/video-js.css';
interface VASTAdPlayerProps {
videoId: string;
videoUrl: string;
posterUrl?: string;
adTagUrl?: string;
onAdStart?: () => void;
onAdEnd?: () => void;
onAdError?: (error: any) => void;
}
export default function VASTAdPlayer({
videoId,
videoUrl,
posterUrl,
adTagUrl = 'https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/single_ad_samples&ciu_szs=300x250&impl=s&gdfp_req=1&env=vp&output=vast&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ct%3Dlinear&correlator=',
onAdStart,
onAdEnd,
onAdError
}: VASTAdPlayerProps) {
const videoRef = useRef<HTMLVideoElement>(null);
const playerRef = useRef<any>(null);
const [isAdPlaying, setIsAdPlaying] = useState(false);
useEffect(() => {
if (!videoRef.current) return;
// Initialize Video.js player with IMA plugin
const player = videojs(videoRef.current, {
controls: true,
responsive: true,
fluid: true,
playbackRates: [0.5, 1, 1.25, 1.5, 2],
poster: posterUrl,
sources: [{
src: videoUrl,
type: 'video/mp4'
}]
});
playerRef.current = player;
// Initialize ads
player.ready(() => {
// @ts-ignore
player.ads({
debug: false,
timeout: 5000
});
// Initialize IMA
// @ts-ignore
player.ima({
adTagUrl: adTagUrl,
adsManagerLoadedCallback: () => {
console.log('IMA ads manager loaded');
},
adsManagerErrorCallback: (error: any) => {
console.error('IMA ads manager error:', error);
onAdError?.(error);
}
});
// Ad event listeners
player.on('ads-ad-started', () => {
console.log('Ad started');
setIsAdPlaying(true);
onAdStart?.();
});
player.on('ads-ad-ended', () => {
console.log('Ad ended');
setIsAdPlaying(false);
onAdEnd?.();
});
player.on('adserror', (event: any) => {
console.error('Ad error:', event);
onAdError?.(event);
});
player.on('ads-request', () => {
console.log('Ad request made');
});
player.on('ads-load', () => {
console.log('Ad loaded');
});
});
return () => {
if (playerRef.current) {
playerRef.current.dispose();
playerRef.current = null;
}
};
}, [videoId, videoUrl, adTagUrl, posterUrl, onAdStart, onAdEnd, onAdError]);
return (
<div className="relative w-full">
{isAdPlaying && (
<div className="absolute top-2 right-2 z-50 bg-black bg-opacity-75 text-white text-xs px-2 py-1 rounded">
Oglas
</div>
)}
<video
ref={videoRef}
className="video-js vjs-default-skin w-full"
controls
preload="auto"
data-setup="{}"
data-testid={`video-player-${videoId}`}
/>
</div>
);
}