Integrate videos directly from Bunny.net CDN for faster streaming
Implements Bunny.net CDN integration for video streaming and utilizes its API to fetch and display videos. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 50814a1e-92e4-4968-856f-7bc7eedf5e8f Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/8cc42625-c1f5-4e43-99bd-77f2c4dedee2/50814a1e-92e4-4968-856f-7bc7eedf5e8f/DXDnT5V
This commit is contained in:
+97
-1
@@ -1,5 +1,6 @@
|
||||
import { type Video, type InsertVideo } from "@shared/schema";
|
||||
import { randomUUID } from "crypto";
|
||||
import { BunnyService } from "./bunny";
|
||||
|
||||
export interface IStorage {
|
||||
getVideos(limit?: number, offset?: number, search?: string, category?: string): Promise<Video[]>;
|
||||
@@ -146,4 +147,99 @@ export class MemStorage implements IStorage {
|
||||
}
|
||||
}
|
||||
|
||||
export const storage = new MemStorage();
|
||||
// Use Bunny.net storage if API keys are available, otherwise fallback to memory storage
|
||||
class BunnyStorage implements IStorage {
|
||||
private bunnyService: BunnyService;
|
||||
private viewsCache: Map<string, number> = new Map();
|
||||
|
||||
constructor() {
|
||||
this.bunnyService = new BunnyService();
|
||||
}
|
||||
|
||||
async getVideos(limit = 20, offset = 0, search?: string, category?: string): Promise<Video[]> {
|
||||
try {
|
||||
const page = Math.floor(offset / limit) + 1;
|
||||
const { videos } = await this.bunnyService.getVideos(page, limit, search);
|
||||
|
||||
// Filter by category if specified
|
||||
let filteredVideos = videos;
|
||||
if (category && category !== "All Categories") {
|
||||
filteredVideos = videos.filter(video => video.category === category);
|
||||
}
|
||||
|
||||
// Apply cached view counts
|
||||
filteredVideos.forEach(video => {
|
||||
if (this.viewsCache.has(video.id)) {
|
||||
video.views += this.viewsCache.get(video.id)!;
|
||||
}
|
||||
});
|
||||
|
||||
return filteredVideos;
|
||||
} catch (error) {
|
||||
console.error('Error fetching videos from Bunny:', error);
|
||||
// Fallback to empty array on error
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async getVideo(id: string): Promise<Video | undefined> {
|
||||
try {
|
||||
const video = await this.bunnyService.getVideo(id);
|
||||
if (!video) return undefined;
|
||||
|
||||
// Apply cached view counts
|
||||
if (this.viewsCache.has(video.id)) {
|
||||
video.views += this.viewsCache.get(video.id)!;
|
||||
}
|
||||
|
||||
return video;
|
||||
} catch (error) {
|
||||
console.error(`Error fetching video ${id} from Bunny:`, error);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
async createVideo(video: InsertVideo): Promise<Video> {
|
||||
// Note: Creating videos would require uploading to Bunny.net
|
||||
// For now, we'll throw an error as this operation is not supported
|
||||
throw new Error("Creating videos is not supported with Bunny.net integration");
|
||||
}
|
||||
|
||||
async updateVideoViews(id: string): Promise<void> {
|
||||
// Since we can't update views in Bunny.net directly, we'll cache them locally
|
||||
const currentViews = this.viewsCache.get(id) || 0;
|
||||
this.viewsCache.set(id, currentViews + 1);
|
||||
}
|
||||
|
||||
async getVideoCount(search?: string, category?: string): Promise<number> {
|
||||
try {
|
||||
const { total } = await this.bunnyService.getVideos(1, 1, search);
|
||||
return total;
|
||||
} catch (error) {
|
||||
console.error('Error getting video count from Bunny:', error);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to use Bunny.net storage, fallback to memory storage if not configured
|
||||
let storage: IStorage;
|
||||
|
||||
// Check if Bunny.net environment variables are available
|
||||
const hasBunnyConfig = process.env.BUNNY_API_KEY && process.env.BUNNY_LIBRARY_ID && process.env.BUNNY_HOSTNAME;
|
||||
|
||||
if (hasBunnyConfig) {
|
||||
try {
|
||||
storage = new BunnyStorage();
|
||||
console.log('✅ Using Bunny.net storage with library ID:', process.env.BUNNY_LIBRARY_ID);
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to initialize Bunny.net storage:', error);
|
||||
console.log('📁 Falling back to memory storage');
|
||||
storage = new MemStorage();
|
||||
}
|
||||
} else {
|
||||
console.log('📁 Bunny.net environment variables not found, using memory storage');
|
||||
storage = new MemStorage();
|
||||
}
|
||||
|
||||
export { storage };
|
||||
|
||||
Reference in New Issue
Block a user