Add support for displaying video advertisement metadata
Integrate Bunny.net API to fetch and display video ad spots, including type, duration, and priority, on the video page. Define new database schema for video ads and create API endpoints for retrieving ad information. 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/jsdCVZt
This commit is contained in:
@@ -9,6 +9,23 @@ interface BunnyVideo {
|
||||
views: number;
|
||||
thumbnailFileName?: string;
|
||||
category?: string;
|
||||
metaTags?: Array<{
|
||||
property: string;
|
||||
value: string;
|
||||
}>;
|
||||
moments?: Array<{
|
||||
type: string; // "preroll", "midroll", "postroll"
|
||||
position?: number; // seconds for midroll
|
||||
vastTag?: string;
|
||||
duration?: number;
|
||||
network?: string;
|
||||
title?: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
interface BunnyVideoDetails extends BunnyVideo {
|
||||
description?: string;
|
||||
customMetadata?: Record<string, any>;
|
||||
}
|
||||
|
||||
interface BunnyLibraryResponse {
|
||||
@@ -124,6 +141,52 @@ export class BunnyService {
|
||||
}
|
||||
}
|
||||
|
||||
async getVideoDetails(videoId: string): Promise<BunnyVideoDetails | null> {
|
||||
try {
|
||||
console.log(`Fetching detailed video data for: ${videoId}`);
|
||||
const videoDetails: BunnyVideoDetails = await this.makeRequest(`videos/${videoId}`);
|
||||
console.log(`Retrieved video details with ${videoDetails.moments?.length || 0} ad spots`);
|
||||
return videoDetails;
|
||||
} catch (error) {
|
||||
console.error(`Error fetching video details for ${videoId}:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getVideoAds(videoId: string): Promise<Array<{
|
||||
adType: string;
|
||||
adUrl?: string;
|
||||
adTitle?: string;
|
||||
adDuration?: number;
|
||||
position?: number;
|
||||
vastTag?: string;
|
||||
adNetwork?: string;
|
||||
priority: number;
|
||||
}>> {
|
||||
try {
|
||||
const videoDetails = await this.getVideoDetails(videoId);
|
||||
if (!videoDetails || !videoDetails.moments) {
|
||||
console.log(`No ad moments found for video ${videoId}`);
|
||||
return [];
|
||||
}
|
||||
|
||||
console.log(`Found ${videoDetails.moments.length} ad moments for video ${videoId}`);
|
||||
return videoDetails.moments.map((moment, index) => ({
|
||||
adType: moment.type,
|
||||
adUrl: moment.vastTag || '',
|
||||
adTitle: moment.title || `${moment.type} Ad`,
|
||||
adDuration: moment.duration || 30,
|
||||
position: moment.position || 0,
|
||||
vastTag: moment.vastTag,
|
||||
adNetwork: moment.network || 'Unknown',
|
||||
priority: index + 1,
|
||||
}));
|
||||
} catch (error) {
|
||||
console.error(`Error fetching video ads for ${videoId}:`, error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getCategories(): Promise<string[]> {
|
||||
try {
|
||||
// Get all videos and extract unique categories
|
||||
|
||||
@@ -233,6 +233,41 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
||||
}
|
||||
});
|
||||
|
||||
// Get video ads/spots metadata from Bunny.net
|
||||
app.get("/api/videos/:id/ads", async (req, res) => {
|
||||
try {
|
||||
const { id } = req.params;
|
||||
|
||||
// Check if video exists first
|
||||
const video = await storage.getVideo(id);
|
||||
if (!video) {
|
||||
return res.status(404).json({ message: "Video not found" });
|
||||
}
|
||||
|
||||
// Get ads from Bunny.net API
|
||||
let ads = [];
|
||||
try {
|
||||
const { BunnyService } = await import("./bunny");
|
||||
const bunnyService = new BunnyService();
|
||||
ads = await bunnyService.getVideoAds(id);
|
||||
console.log(`Retrieved ${ads.length} ad spots for video ${id}`);
|
||||
} catch (error) {
|
||||
console.error(`Failed to get ads from Bunny.net for video ${id}:`, error);
|
||||
// Return empty array if Bunny service fails
|
||||
ads = [];
|
||||
}
|
||||
|
||||
res.json({
|
||||
videoId: id,
|
||||
ads: ads,
|
||||
totalAds: ads.length
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(`Error fetching ads for video ${id}:`, error);
|
||||
res.status(500).json({ message: "Failed to fetch video ads" });
|
||||
}
|
||||
});
|
||||
|
||||
// Update video views
|
||||
app.post("/api/videos/:id/view", async (req, res) => {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user