-
-
- Share
-
-
-
- {showFormats && (
-
setShowFormats(false)}
- />
- )}
-
-
- {isDownloading ? (
-
- {progressPercent > 0 ? `${progressPercent}%` : ''}
-
-
- ) : 'Download'}
-
-
- {showFormats && (
-
-
- Select Quality
- setShowFormats(false)}
- style={{
- background: 'none',
- border: 'none',
- color: 'var(--yt-text-secondary)',
- fontSize: '20px',
- cursor: 'pointer',
- padding: '4px 8px'
- }}
- >
- ×
-
-
-
- {isLoadingFormats ? (
-
-
- Loading...
-
- ) : formats.length === 0 ? (
-
- No formats available
-
- ) : (
- formats.map(f => {
- const height = parseInt(f.resolution) || 0;
- const badge = getQualityBadge(height);
-
- return (
-
handleDownload(f)}
- className="format-item-hover"
- style={{
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'space-between',
- width: '100%',
- padding: '12px 16px',
- backgroundColor: 'transparent',
- border: 'none',
- color: 'var(--yt-text-primary)',
- cursor: 'pointer',
- fontSize: '14px',
- transition: 'background-color 0.15s',
- }}
- >
-
- {badge && (
-
- {badge.label}
-
- )}
- {getQualityLabel(f.resolution)}
-
-
- {formatFileSize(f.filesize) || 'Unknown size'}
-
-
- );
- })
- )}
-
- )}
-
-
- {isDownloading && downloadProgress && (
-
- {downloadProgress}
-
- )}
-
- );
-}
diff --git a/frontend/app/watch/WatchFeed.tsx b/frontend/app/watch/WatchFeed.tsx
deleted file mode 100644
index 19e751d..0000000
--- a/frontend/app/watch/WatchFeed.tsx
+++ /dev/null
@@ -1,77 +0,0 @@
-'use client';
-
-import { useState } from 'react';
-import InfiniteVideoGrid from '../components/InfiniteVideoGrid';
-import { VideoData } from '../constants';
-
-interface Props {
- videoId: string;
- regionLabel: string;
- initialMix: VideoData[]; // Initial 40:40:20 mix data for "All" tab
- initialRelated: VideoData[]; // Initial related data for "Related" tab
- initialSuggestions: VideoData[]; // Initial suggestions data for "For You" tab
-}
-
-const WATCH_TABS = ['All', 'Mix', 'Related', 'For You', 'Trending'];
-
-export default function WatchFeed({ videoId, regionLabel, initialMix, initialRelated, initialSuggestions }: Props) {
- const [activeTab, setActiveTab] = useState('All');
-
- // Determine category id and initial videos based on active tab
- let currentCategory = 'WatchAll';
- let videos = initialMix;
-
- if (activeTab === 'Related') {
- currentCategory = 'WatchRelated';
- videos = initialRelated;
- } else if (activeTab === 'For You') {
- currentCategory = 'WatchForYou';
- videos = initialSuggestions;
- } else if (activeTab === 'Trending') {
- currentCategory = 'Trending';
- // 'Trending' falls back to standard fetchMoreVideos logic which handles normal categories or we can handle it specifically.
- // It's empty initially if missing, the infinite grid will load it.
- videos = [];
- }
-
- return (
-
-
- {WATCH_TABS.map((tab) => {
- const isActive = tab === activeTab;
- return (
- {
- if (tab === 'Mix') {
- window.location.href = `/watch?v=${videoId}&list=RD${videoId}`;
- } else {
- setActiveTab(tab);
- }
- }}
- className={`chip ${isActive ? 'active' : ''}`}
- style={{
- fontSize: '14px',
- whiteSpace: 'nowrap',
- backgroundColor: isActive ? 'var(--foreground)' : 'var(--yt-hover)',
- color: isActive ? 'var(--background)' : 'var(--yt-text-primary)'
- }}
- >
- {tab}
-
- );
- })}
-
-
-
-
-
-
- );
-}
diff --git a/frontend/app/watch/YouTubePlayer.tsx b/frontend/app/watch/YouTubePlayer.tsx
new file mode 100644
index 0000000..7592b6d
--- /dev/null
+++ b/frontend/app/watch/YouTubePlayer.tsx
@@ -0,0 +1,239 @@
+'use client';
+
+import { useEffect, useRef, useState } from 'react';
+import { useRouter } from 'next/navigation';
+import LoadingSpinner from '../components/LoadingSpinner';
+
+declare global {
+ interface Window {
+ YT: any;
+ onYouTubeIframeAPIReady: () => void;
+ }
+}
+
+interface YouTubePlayerProps {
+ videoId: string;
+ title?: string;
+ autoplay?: boolean;
+ onVideoEnd?: () => void;
+ onVideoReady?: () => void;
+}
+
+function PlayerSkeleton() {
+ return (
+
+
+
+ );
+}
+
+export default function YouTubePlayer({
+ videoId,
+ title,
+ autoplay = true,
+ onVideoEnd,
+ onVideoReady
+}: YouTubePlayerProps) {
+ const playerRef = useRef
(null);
+ const playerInstanceRef = useRef(null);
+ const [isApiReady, setIsApiReady] = useState(false);
+ const [isPlayerReady, setIsPlayerReady] = useState(false);
+ const [error, setError] = useState(null);
+ const router = useRouter();
+
+ // Load YouTube IFrame API
+ useEffect(() => {
+ if (window.YT && window.YT.Player) {
+ setIsApiReady(true);
+ return;
+ }
+
+ // Check if script already exists
+ const existingScript = document.querySelector('script[src*="youtube.com/iframe_api"]');
+ if (existingScript) {
+ // Script exists, wait for it to load
+ const checkYT = setInterval(() => {
+ if (window.YT && window.YT.Player) {
+ setIsApiReady(true);
+ clearInterval(checkYT);
+ }
+ }, 100);
+ return () => clearInterval(checkYT);
+ }
+
+ const tag = document.createElement('script');
+ tag.src = 'https://www.youtube.com/iframe_api';
+ tag.async = true;
+ document.head.appendChild(tag);
+
+ window.onYouTubeIframeAPIReady = () => {
+ console.log('YouTube IFrame API ready');
+ setIsApiReady(true);
+ };
+
+ return () => {
+ // Clean up
+ window.onYouTubeIframeAPIReady = () => {};
+ };
+ }, []);
+
+ // Initialize player when API is ready
+ useEffect(() => {
+ if (!isApiReady || !playerRef.current || !videoId) return;
+
+ // Destroy previous player instance if exists
+ if (playerInstanceRef.current) {
+ try {
+ playerInstanceRef.current.destroy();
+ } catch (e) {
+ console.log('Error destroying player:', e);
+ }
+ playerInstanceRef.current = null;
+ }
+
+ try {
+ const player = new window.YT.Player(playerRef.current, {
+ videoId: videoId,
+ playerVars: {
+ autoplay: autoplay ? 1 : 0,
+ controls: 1,
+ rel: 0,
+ modestbranding: 0,
+ playsinline: 1,
+ enablejsapi: 1,
+ origin: window.location.origin,
+ widget_referrer: window.location.href,
+ iv_load_policy: 3,
+ fs: 0,
+ disablekb: 0,
+ color: 'white',
+ },
+ events: {
+ onReady: (event: any) => {
+ console.log('YouTube Player ready for video:', videoId);
+ setIsPlayerReady(true);
+ if (onVideoReady) onVideoReady();
+
+ // Auto-play if enabled
+ if (autoplay) {
+ try {
+ event.target.playVideo();
+ } catch (e) {
+ console.log('Autoplay prevented:', e);
+ }
+ }
+ },
+ onStateChange: (event: any) => {
+ // Video ended
+ if (event.data === window.YT.PlayerState.ENDED) {
+ if (onVideoEnd) {
+ onVideoEnd();
+ }
+ }
+ },
+ onError: (event: any) => {
+ console.error('YouTube Player Error:', event.data);
+ setError(`Failed to load video (Error ${event.data})`);
+ },
+ },
+ });
+
+ playerInstanceRef.current = player;
+ } catch (error) {
+ console.error('Failed to create YouTube player:', error);
+ setError('Failed to initialize video player');
+ }
+
+ return () => {
+ if (playerInstanceRef.current) {
+ try {
+ playerInstanceRef.current.destroy();
+ } catch (e) {
+ console.log('Error cleaning up player:', e);
+ }
+ playerInstanceRef.current = null;
+ }
+ };
+ }, [isApiReady, videoId, autoplay]);
+
+ // Handle video end
+ useEffect(() => {
+ if (!isPlayerReady || !onVideoEnd) return;
+
+ const handleVideoEnd = () => {
+ onVideoEnd();
+ };
+
+ // The onStateChange event handler already handles this
+ }, [isPlayerReady, onVideoEnd]);
+
+ if (error) {
+ return (
+
+
{error}
+
window.open(`https://www.youtube.com/watch?v=${videoId}`, '_blank')}
+ style={{
+ padding: '8px 16px',
+ backgroundColor: '#ff0000',
+ color: '#fff',
+ border: 'none',
+ borderRadius: '4px',
+ cursor: 'pointer',
+ }}
+ >
+ Watch on YouTube
+
+
+ );
+ }
+
+ return (
+
+ {!isPlayerReady && !error &&
}
+
+
+ );
+}
+
+// Utility function to play a video
+export function playVideo(videoId: string) {
+ if (window.YT && window.YT.Player) {
+ // Could create a new player instance or use existing one
+ console.log('Playing video:', videoId);
+ }
+}
+
+// Utility function to pause video
+export function pauseVideo() {
+ // Would need to reference player instance
+}
\ No newline at end of file
diff --git a/frontend/app/watch/page.tsx b/frontend/app/watch/page.tsx
index e56fed7..254f7e5 100644
--- a/frontend/app/watch/page.tsx
+++ b/frontend/app/watch/page.tsx
@@ -1,272 +1,11 @@
import { Suspense } from 'react';
-import VideoPlayer from './VideoPlayer';
-import Link from 'next/link';
-import WatchActions from './WatchActions';
-import SubscribeButton from '../components/SubscribeButton';
-import NextVideoClient from './NextVideoClient';
-import WatchFeed from './WatchFeed';
-import PlaylistPanel from './PlaylistPanel';
-import Comments from './Comments';
-import { API_BASE, VideoData } from '../constants';
-import { cookies } from 'next/headers';
-import { getRelatedVideos, getSuggestedVideos, getSearchVideos } from '../actions';
-import { addRegion, getRandomModifier } from '../utils';
-
-const REGION_LABELS: Record = {
- VN: 'Vietnam',
- US: 'United States',
- JP: 'Japan',
- KR: 'South Korea',
- IN: 'India',
- GB: 'United Kingdom',
- GLOBAL: '',
-};
-
-interface VideoInfo {
- title: string;
- description: string;
- uploader: string;
- channel_id: string;
- view_count: number;
- thumbnail?: string;
-}
-
-async function getVideoInfo(id: string): Promise {
- try {
- const res = await fetch(`${API_BASE}/api/get_stream_info?v=${id}`, { cache: 'no-store' });
- if (!res.ok) return null;
- const data = await res.json();
- return {
- title: data.title || `Video ${id}`,
- description: data.description || '',
- uploader: data.uploader || 'Unknown',
- channel_id: data.channel_id || '',
- view_count: data.view_count || 0,
- thumbnail: data.thumbnail || `https://i.ytimg.com/vi/${id}/maxresdefault.jpg`,
- };
- } catch (e) {
- console.error(e);
- return null;
- }
-}
-
-function formatNumber(num: number): string {
- if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M';
- if (num >= 1000) return (num / 1000).toFixed(0) + 'K';
- return num.toString();
-}
-
-export default async function WatchPage({
- searchParams,
-}: {
- searchParams: Promise<{ [key: string]: string | string[] | undefined }>
-}) {
- const awaitParams = await searchParams;
- const v = awaitParams.v as string;
- const list = awaitParams.list as string;
- const isMix = list?.startsWith('RD');
-
- if (!v) {
- return No video ID provided
;
- }
-
- const info = await getVideoInfo(v);
-
- const cookieStore = await cookies();
- const regionCode = cookieStore.get('region')?.value || 'VN';
- const regionLabel = REGION_LABELS[regionCode] || '';
- const randomMod = getRandomModifier();
-
- // Fetch initial mix
- const promises = [
- getSuggestedVideos(12),
- getRelatedVideos(v, 12),
- getSearchVideos(addRegion("trending", regionLabel) + ' ' + randomMod, 6)
- ];
-
- const [suggestedRes, relatedRes, trendingRes] = await Promise.all(promises);
-
- const interleavedList: VideoData[] = [];
- const seenIds = new Set();
-
- let sIdx = 0, rIdx = 0, tIdx = 0;
- while (sIdx < suggestedRes.length || rIdx < relatedRes.length || tIdx < trendingRes.length) {
- for (let i = 0; i < 2 && sIdx < suggestedRes.length; i++) {
- const vid = suggestedRes[sIdx++];
- if (!seenIds.has(vid.id) && vid.id !== v) { interleavedList.push(vid); seenIds.add(vid.id); }
- }
- for (let i = 0; i < 2 && rIdx < relatedRes.length; i++) {
- const vid = relatedRes[rIdx++];
- if (!seenIds.has(vid.id) && vid.id !== v) { interleavedList.push(vid); seenIds.add(vid.id); }
- }
- for (let i = 0; i < 1 && tIdx < trendingRes.length; i++) {
- const vid = trendingRes[tIdx++];
- if (!seenIds.has(vid.id) && vid.id !== v) { interleavedList.push(vid); seenIds.add(vid.id); }
- }
- }
-
- let initialMix = interleavedList;
- const initialRelated = relatedRes.filter(vid => vid.id !== v);
- const initialSuggestions = suggestedRes.filter(vid => vid.id !== v);
-
- // If not currently inside a mix, inject a Mix Card at the start
- if (!isMix && info) {
- const mixCard: VideoData = {
- id: v,
- title: `Mix - ${info.uploader || 'Auto-generated'}`,
- uploader: info.uploader || 'KV-Tube',
- thumbnail: info.thumbnail || `https://i.ytimg.com/vi/${v}/maxresdefault.jpg`,
- view_count: 0,
- duration: '50+',
- list_id: `RD${v}`,
- is_mix: true
- };
- initialMix.unshift(mixCard);
- }
-
- // Always build a Mix playlist
- let playlistVideos: VideoData[] = [];
- const mixBaseId = isMix ? list.replace('RD', '') : v;
- const mixListId = isMix ? list : `RD${v}`;
- {
- const baseInfo = isMix ? await getVideoInfo(mixBaseId) : info;
-
- // Seed the playlist with the base video
- const DEFAULT_THUMBNAIL = 'https://i.ytimg.com/vi/default/hqdefault.jpg';
- if (baseInfo) {
- playlistVideos.push({
- id: mixBaseId,
- title: baseInfo.title,
- uploader: baseInfo.uploader,
- thumbnail: baseInfo.thumbnail || `https://i.ytimg.com/vi/${mixBaseId}/hqdefault.jpg` || DEFAULT_THUMBNAIL,
- view_count: baseInfo.view_count,
- duration: ''
- });
- }
-
- // Multi-source search to build a rich playlist (15-25 videos)
- const uploaderName = baseInfo?.uploader || '';
- const videoTitle = baseInfo?.title || '';
- const titleKeywords = videoTitle.split(/[\s\-|]+/).filter((w: string) => w.length > 2).slice(0, 4).join(' ');
-
- const mixPromises = [
- uploaderName ? getSearchVideos(uploaderName, 20) : Promise.resolve([]),
- titleKeywords ? getSearchVideos(titleKeywords, 20) : Promise.resolve([]),
- getRelatedVideos(mixBaseId, 20),
- ];
-
- const [byUploader, byTitle, byRelated] = await Promise.all(mixPromises);
- const seenMixIds = new Set(playlistVideos.map(p => p.id));
-
- const sources = [byUploader, byTitle, byRelated];
- let added = 0;
- const maxPlaylist = 50;
-
- let idx = [0, 0, 0];
- while (added < maxPlaylist) {
- let anyAdded = false;
- for (let s = 0; s < sources.length; s++) {
- while (idx[s] < sources[s].length && added < maxPlaylist) {
- const vid = sources[s][idx[s]++];
- if (!seenMixIds.has(vid.id)) {
- seenMixIds.add(vid.id);
- playlistVideos.push({
- ...vid,
- thumbnail: vid.thumbnail || `https://i.ytimg.com/vi/${vid.id}/hqdefault.jpg` || DEFAULT_THUMBNAIL
- });
- added++;
- anyAdded = true;
- break;
- }
- }
- }
- if (!anyAdded) break;
- }
- }
-
- // Determine the next video
- let nextVideoId = '';
- let nextListId: string | undefined = undefined;
-
- if (playlistVideos.length > 0) {
- const currentIndex = playlistVideos.findIndex(p => p.id === v);
- if (currentIndex >= 0 && currentIndex < playlistVideos.length - 1) {
- nextVideoId = playlistVideos[currentIndex + 1].id;
- nextListId = mixListId;
- } else {
- nextVideoId = initialMix.length > 0 && initialMix[0].is_mix ? (initialMix[1]?.id || '') : (initialMix[0]?.id || '');
- }
- } else {
- const firstRealVideo = initialMix.find(vid => !vid.is_mix);
- nextVideoId = firstRealVideo ? firstRealVideo.id : '';
- }
+import ClientWatchPage from './ClientWatchPage';
+import LoadingSpinner from '../components/LoadingSpinner';
+export default function WatchPage() {
return (
-
- {nextVideoId &&
}
-
-
-
-
-
-
- {info?.title || `Video ${v}`}
-
-
- {info && (
-
-
-
-
- {info.uploader}
-
-
-
-
-
-
-
-
-
- )}
-
- {info && (
-
-
- {formatNumber(info.view_count)} views
-
-
- {info.description || 'No description available.'}
-
-
- )}
-
-
- {/* Comments as a separate flex child for responsive reordering */}
-
-
-
-
-
- {playlistVideos.length > 0 && (
-
- )}
-
-
-
+ }>
+
+
);
-}
+}
\ No newline at end of file
diff --git a/frontend/frontend.log b/frontend/frontend.log
new file mode 100644
index 0000000..ad87c9a
--- /dev/null
+++ b/frontend/frontend.log
@@ -0,0 +1,1921 @@
+
+> frontend@0.1.0 dev
+> next dev
+
+▲ Next.js 16.1.6 (Turbopack)
+- Local: http://localhost:3000
+- Network: http://192.168.31.138:3000
+- Environments: .env.local
+
+✓ Starting...
+✓ Ready in 1188ms
+ GET /watch?v=krbtaBr9jNc 200 in 572ms (compile: 273ms, render: 299ms)
+ GET / 200 in 59ms (compile: 35ms, render: 24ms)
+ GET /feed/subscriptions 200 in 61ms (compile: 41ms, render: 20ms)
+ GET /feed/library 200 in 416ms (compile: 349ms, render: 67ms)
+ GET /feed/library 200 in 51ms (compile: 8ms, render: 43ms)
+ GET /feed/library 200 in 127ms (compile: 4ms, render: 122ms)
+ GET /watch?v=sZrIbpwjTwk 200 in 25ms (compile: 6ms, render: 19ms)
+ GET /feed/subscriptions 200 in 81ms (compile: 14ms, render: 68ms)
+ GET /feed/subscriptions 200 in 195ms (compile: 8ms, render: 188ms)
+ GET /feed/subscriptions 200 in 64ms (compile: 9ms, render: 55ms)
+ GET /watch?v=X8dM9elNhAM 200 in 149ms (compile: 122ms, render: 27ms)
+✓ Compiled in 62ms
+✓ Compiled in 42ms
+✓ Compiled in 37ms
+✓ Compiled in 93ms
+ GET /watch?v=X8dM9elNhAM 200 in 441ms (compile: 124ms, render: 316ms)
+ GET / 200 in 30ms (compile: 6ms, render: 24ms)
+ GET / 200 in 39ms (compile: 7ms, render: 32ms)
+ GET /watch?v=OsfAnsMY21M 200 in 34ms (compile: 6ms, render: 28ms)
+✓ Compiled in 53ms
+ GET /watch?v=OsfAnsMY21M 200 in 431ms (compile: 86ms, render: 345ms)
+ GET /watch?v=OsfAnsMY21M 200 in 186ms (compile: 11ms, render: 175ms)
+ GET / 200 in 36ms (compile: 6ms, render: 30ms)
+ GET /feed/subscriptions 200 in 128ms (compile: 98ms, render: 30ms)
+ GET / 200 in 21ms (compile: 4ms, render: 16ms)
+✓ Compiled in 110ms
+✓ Compiled in 49ms
+✓ Compiled in 81ms
+✓ Compiled in 28ms
+ GET /watch?v=KKFubczfTOs 200 in 141ms (compile: 93ms, render: 48ms)
+✓ Compiled in 455ms
+✓ Compiled in 88ms
+ GET /watch?v=KKFubczfTOs 200 in 972ms (compile: 216ms, render: 756ms)
+ GET /watch?v=KKFubczfTOs 200 in 409ms (compile: 106ms, render: 303ms)
+ GET /watch?v=KKFubczfTOs 200 in 184ms (compile: 4ms, render: 180ms)
+ GET /watch?v=KKFubczfTOs 200 in 136ms (compile: 12ms, render: 124ms)
+ GET /watch?v=KKFubczfTOs 200 in 120ms (compile: 5ms, render: 115ms)
+ GET /watch?v=KKFubczfTOs 200 in 102ms (compile: 3ms, render: 99ms)
+ GET /watch?v=KKFubczfTOs 200 in 103ms (compile: 2ms, render: 101ms)
+ GET /watch?v=KKFubczfTOs 200 in 105ms (compile: 3ms, render: 102ms)
+ GET /watch?v=KKFubczfTOs 200 in 105ms (compile: 3ms, render: 101ms)
+ GET /watch?v=KKFubczfTOs 200 in 108ms (compile: 3ms, render: 105ms)
+ GET /watch?v=KKFubczfTOs 200 in 109ms (compile: 3ms, render: 106ms)
+ GET /watch?v=KKFubczfTOs 200 in 106ms (compile: 3ms, render: 103ms)
+ GET /watch?v=KKFubczfTOs 200 in 109ms (compile: 5ms, render: 104ms)
+ GET /watch?v=KKFubczfTOs 200 in 108ms (compile: 5ms, render: 104ms)
+ GET /watch?v=KKFubczfTOs 200 in 117ms (compile: 5ms, render: 112ms)
+ GET /watch?v=KKFubczfTOs 200 in 113ms (compile: 4ms, render: 109ms)
+ GET /watch?v=KKFubczfTOs 200 in 114ms (compile: 4ms, render: 110ms)
+ GET /watch?v=KKFubczfTOs 200 in 114ms (compile: 4ms, render: 110ms)
+ GET /watch?v=KKFubczfTOs 200 in 114ms (compile: 3ms, render: 112ms)
+ GET /watch?v=KKFubczfTOs 200 in 108ms (compile: 4ms, render: 104ms)
+ GET /watch?v=KKFubczfTOs 200 in 106ms (compile: 3ms, render: 103ms)
+ GET /watch?v=KKFubczfTOs 200 in 90ms (compile: 5ms, render: 85ms)
+ GET /watch?v=KKFubczfTOs 200 in 64ms (compile: 3ms, render: 62ms)
+ GET /watch?v=KKFubczfTOs 200 in 47ms (compile: 3ms, render: 44ms)
+ GET /watch?v=KKFubczfTOs 200 in 31ms (compile: 4ms, render: 27ms)
+ GET /watch?v=KKFubczfTOs 200 in 197ms (compile: 79ms, render: 118ms)
+ GET /watch?v=KKFubczfTOs 200 in 107ms (compile: 2ms, render: 105ms)
+ GET /watch?v=KKFubczfTOs 200 in 127ms (compile: 2ms, render: 125ms)
+ GET /watch?v=KKFubczfTOs 200 in 144ms (compile: 3ms, render: 142ms)
+ GET /watch?v=KKFubczfTOs 200 in 168ms (compile: 3ms, render: 166ms)
+ GET /watch?v=KKFubczfTOs 200 in 202ms (compile: 5ms, render: 197ms)
+ GET /watch?v=KKFubczfTOs 200 in 232ms (compile: 5ms, render: 227ms)
+ GET /watch?v=KKFubczfTOs 200 in 522ms (compile: 9ms, render: 514ms)
+ GET /watch?v=KKFubczfTOs 200 in 548ms (compile: 4ms, render: 544ms)
+ GET /watch?v=KKFubczfTOs 200 in 546ms (compile: 8ms, render: 538ms)
+ GET /watch?v=KKFubczfTOs 200 in 527ms (compile: 5ms, render: 522ms)
+ GET /watch?v=KKFubczfTOs 200 in 533ms (compile: 12ms, render: 521ms)
+ GET /watch?v=KKFubczfTOs 200 in 300ms (compile: 50ms, render: 249ms)
+ GET /watch?v=KKFubczfTOs 200 in 258ms (compile: 9ms, render: 248ms)
+ GET /watch?v=KKFubczfTOs 200 in 263ms (compile: 4ms, render: 259ms)
+ GET /watch?v=KKFubczfTOs 200 in 276ms (compile: 7ms, render: 268ms)
+ GET /watch?v=KKFubczfTOs 200 in 275ms (compile: 16ms, render: 259ms)
+ GET /watch?v=KKFubczfTOs 200 in 225ms (compile: 5ms, render: 221ms)
+ GET /watch?v=KKFubczfTOs 200 in 260ms (compile: 8ms, render: 252ms)
+ GET /watch?v=KKFubczfTOs 200 in 216ms (compile: 7ms, render: 208ms)
+ GET /watch?v=KKFubczfTOs 200 in 202ms (compile: 6ms, render: 196ms)
+ GET /watch?v=KKFubczfTOs 200 in 196ms (compile: 8ms, render: 188ms)
+ GET /watch?v=KKFubczfTOs 200 in 167ms (compile: 10ms, render: 157ms)
+ GET /watch?v=KKFubczfTOs 200 in 126ms (compile: 5ms, render: 121ms)
+ GET /watch?v=KKFubczfTOs 200 in 95ms (compile: 7ms, render: 88ms)
+ GET /watch?v=KKFubczfTOs 200 in 58ms (compile: 7ms, render: 51ms)
+ GET /watch?v=KKFubczfTOs 200 in 303ms (compile: 3ms, render: 300ms)
+✓ Compiled in 23ms
+ GET /api/proxy/invidious?path=comments&videoId=KKFubczfTOs&limit=50 200 in 15.0s (compile: 951ms, render: 14.0s)
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+✓ Compiled in 40ms
+ GET /watch?v=KKFubczfTOs 200 in 885ms (compile: 97ms, render: 788ms)
+ GET /api/proxy/invidious?path=video&videoId=KKFubczfTOs 200 in 14.9s (compile: 18ms, render: 14.9s)
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+All Piped instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/piped/route.ts:42:15)
+ 40 |
+ 41 | if (!response.ok) {
+ > 42 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 43 | }
+ 44 |
+ 45 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/piped/route.ts:34:24)
+ 32 | for (const instance of PIPED_INSTANCES) {
+ 33 | try {
+ > 34 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 35 | signal: AbortSignal.timeout(10000),
+ 36 | headers: {
+ 37 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND adminforge.destreams
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'adminforge.destreams'
+ }
+ },
+ SyntaxError: Unexpected token 'P', "Piped has shutdown" is not valid JSON
+ at JSON.parse ()
+ at async GET (app/api/proxy/piped/route.ts:45:20)
+ 43 | }
+ 44 |
+ > 45 | const data = await response.json();
+ | ^
+ 46 | return NextResponse.json(data);
+ 47 | } catch (error: any) {
+ 48 | errors.push(error);
+]
+ GET /api/proxy/piped?path=streams&videoId=KKFubczfTOs 502 in 3.0s (compile: 148ms, render: 2.9s)
+ GET / 200 in 133ms (compile: 98ms, render: 35ms)
+ GET /api/proxy/invidious?path=trending®ion=VN 200 in 2.7s (compile: 11ms, render: 2.7s)
+ GET /api/proxy/invidious?path=search&q=+music&type=video&limit=20 200 in 14.6s (compile: 2ms, render: 14.6s)
+ GET /api/proxy/invidious?path=search&q=music+mix+compilation&type=video&limit=20 200 in 14.6s (compile: 1986µs, render: 14.6s)
+ GET / 200 in 307ms (compile: 3ms, render: 304ms)
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+ GET /api/proxy/invidious?path=trending®ion=VN 502 in 15.5s (compile: 11ms, render: 15.5s)
+ GET /api/proxy/invidious?path=trending®ion=VN 200 in 10.7s (compile: 3ms, render: 10.7s)
+ GET / 200 in 61ms (compile: 7ms, render: 55ms)
+ GET /feed/subscriptions 200 in 123ms (compile: 88ms, render: 35ms)
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+ GET / 200 in 13ms (compile: 2ms, render: 11ms)
+ GET /feed/library 200 in 50ms (compile: 29ms, render: 21ms)
+ GET /watch?v=HXkh7EOqcQ4 200 in 32ms (compile: 5ms, render: 28ms)
+ GET /api/proxy/invidious?path=trending®ion=VN 200 in 14.9s (compile: 104ms, render: 14.8s)
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+ GET /api/proxy/invidious?path=trending®ion=VN 200 in 5.7s (compile: 3ms, render: 5.7s)
+ GET /api/proxy/invidious?path=video&videoId=HXkh7EOqcQ4 200 in 15.0s (compile: 1945µs, render: 15.0s)
+ GET /api/proxy/invidious?path=video&videoId=HXkh7EOqcQ4 200 in 5ms (compile: 1598µs, render: 4ms)
+All Piped instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/piped/route.ts:42:15)
+ 40 |
+ 41 | if (!response.ok) {
+ > 42 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 43 | }
+ 44 |
+ 45 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/piped/route.ts:34:24)
+ 32 | for (const instance of PIPED_INSTANCES) {
+ 33 | try {
+ > 34 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 35 | signal: AbortSignal.timeout(10000),
+ 36 | headers: {
+ 37 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND adminforge.destreams
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'adminforge.destreams'
+ }
+ },
+ SyntaxError: Unexpected token 'P', "Piped has shutdown" is not valid JSON
+ at JSON.parse ()
+ at async GET (app/api/proxy/piped/route.ts:45:20)
+ 43 | }
+ 44 |
+ > 45 | const data = await response.json();
+ | ^
+ 46 | return NextResponse.json(data);
+ 47 | } catch (error: any) {
+ 48 | errors.push(error);
+]
+ GET /api/proxy/piped?path=streams&videoId=HXkh7EOqcQ4 502 in 2.2s (compile: 1589µs, render: 2.2s)
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+All Piped instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/piped/route.ts:42:15)
+ 40 |
+ 41 | if (!response.ok) {
+ > 42 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 43 | }
+ 44 |
+ 45 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/piped/route.ts:34:24)
+ 32 | for (const instance of PIPED_INSTANCES) {
+ 33 | try {
+ > 34 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 35 | signal: AbortSignal.timeout(10000),
+ 36 | headers: {
+ 37 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND adminforge.destreams
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'adminforge.destreams'
+ }
+ },
+ SyntaxError: Unexpected token 'P', "Piped has shutdown" is not valid JSON
+ at JSON.parse ()
+ at async GET (app/api/proxy/piped/route.ts:45:20)
+ 43 | }
+ 44 |
+ > 45 | const data = await response.json();
+ | ^
+ 46 | return NextResponse.json(data);
+ 47 | } catch (error: any) {
+ 48 | errors.push(error);
+]
+ GET /api/proxy/piped?path=streams&videoId=HXkh7EOqcQ4 502 in 1891ms (compile: 5ms, render: 1886ms)
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+ GET / 200 in 24ms (compile: 5ms, render: 19ms)
+ GET / 200 in 459ms (compile: 154ms, render: 304ms)
+ GET / 200 in 327ms (compile: 11ms, render: 316ms)
+ GET / 200 in 259ms (compile: 38ms, render: 221ms)
+ GET / 200 in 154ms (compile: 5ms, render: 150ms)
+ GET / 200 in 135ms (compile: 6ms, render: 129ms)
+ GET / 200 in 141ms (compile: 6ms, render: 135ms)
+ GET / 200 in 149ms (compile: 5ms, render: 143ms)
+ GET / 200 in 135ms (compile: 5ms, render: 130ms)
+ GET / 200 in 117ms (compile: 12ms, render: 105ms)
+ GET / 200 in 98ms (compile: 6ms, render: 91ms)
+ GET / 200 in 96ms (compile: 5ms, render: 91ms)
+ GET / 200 in 98ms (compile: 5ms, render: 94ms)
+ GET / 200 in 103ms (compile: 4ms, render: 99ms)
+ GET / 200 in 112ms (compile: 7ms, render: 105ms)
+ GET / 200 in 147ms (compile: 4ms, render: 143ms)
+ GET / 200 in 176ms (compile: 6ms, render: 170ms)
+ GET / 200 in 184ms (compile: 7ms, render: 177ms)
+ GET / 200 in 161ms (compile: 8ms, render: 154ms)
+ GET / 200 in 133ms (compile: 4ms, render: 129ms)
+ GET / 200 in 112ms (compile: 8ms, render: 103ms)
+ GET / 200 in 113ms (compile: 3ms, render: 110ms)
+ GET / 200 in 108ms (compile: 8ms, render: 101ms)
+ GET / 200 in 104ms (compile: 4ms, render: 100ms)
+ GET / 200 in 73ms (compile: 4ms, render: 69ms)
+ GET / 200 in 52ms (compile: 4ms, render: 48ms)
+ GET /api/proxy/invidious?path=search&q=+music&type=video&limit=20 200 in 15.0s (compile: 3ms, render: 15.0s)
+ GET /api/proxy/invidious?path=search&q=music+mix+compilation&type=video&limit=20 200 in 15.0s (compile: 4ms, render: 15.0s)
+(node:17664) [DEP0060] DeprecationWarning: The `util._extend` API is deprecated. Please use Object.assign() instead.
+(Use `node --trace-deprecation ...` to show where the warning was created)
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+ GET /api/proxy/invidious?path=trending®ion=VN 200 in 15.0s (compile: 7ms, render: 15.0s)
+All Invidious instances failed: [
+ Error: HTTP 502
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ SyntaxError: Unexpected token '<', ")
+ at async GET (app/api/proxy/invidious/route.ts:67:20)
+ 65 | }
+ 66 |
+ > 67 | const data = await response.json();
+ | ^
+ 68 | return NextResponse.json(data);
+ 69 | } catch (error: any) {
+ 70 | errors.push(error);,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ Error: HTTP 403
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();,
+ TypeError: fetch failed
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ [cause]: Error: getaddrinfo ENOTFOUND invidious.fdn.fr
+ at ignore-listed frames {
+ errno: -3008,
+ code: 'ENOTFOUND',
+ syscall: 'getaddrinfo',
+ hostname: 'invidious.fdn.fr'
+ }
+ },
+ Error [TimeoutError]: The operation was aborted due to timeout
+ at async GET (app/api/proxy/invidious/route.ts:56:24)
+ 54 | for (const instance of INVIDIOUS_INSTANCES) {
+ 55 | try {
+ > 56 | const response = await fetch(`${instance}${apiPath}`, {
+ | ^
+ 57 | signal: AbortSignal.timeout(10000),
+ 58 | headers: {
+ 59 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', {
+ code: 23,
+ INDEX_SIZE_ERR: 1,
+ DOMSTRING_SIZE_ERR: 2,
+ HIERARCHY_REQUEST_ERR: 3,
+ WRONG_DOCUMENT_ERR: 4,
+ INVALID_CHARACTER_ERR: 5,
+ NO_DATA_ALLOWED_ERR: 6,
+ NO_MODIFICATION_ALLOWED_ERR: 7,
+ NOT_FOUND_ERR: 8,
+ NOT_SUPPORTED_ERR: 9,
+ INUSE_ATTRIBUTE_ERR: 10,
+ INVALID_STATE_ERR: 11,
+ SYNTAX_ERR: 12,
+ INVALID_MODIFICATION_ERR: 13,
+ NAMESPACE_ERR: 14,
+ INVALID_ACCESS_ERR: 15,
+ VALIDATION_ERR: 16,
+ TYPE_MISMATCH_ERR: 17,
+ SECURITY_ERR: 18,
+ NETWORK_ERR: 19,
+ ABORT_ERR: 20,
+ URL_MISMATCH_ERR: 21,
+ QUOTA_EXCEEDED_ERR: 22,
+ TIMEOUT_ERR: 23,
+ INVALID_NODE_TYPE_ERR: 24,
+ DATA_CLONE_ERR: 25
+ },
+ Error: HTTP 404
+ at GET (app/api/proxy/invidious/route.ts:64:15)
+ 62 |
+ 63 | if (!response.ok) {
+ > 64 | throw new Error(`HTTP ${response.status}`);
+ | ^
+ 65 | }
+ 66 |
+ 67 | const data = await response.json();
+]
+ GET / 200 in 658ms (compile: 42ms, render: 616ms)
+✓ Compiled in 197ms
+ GET / 200 in 854ms (compile: 466ms, render: 388ms)
+ GET / 200 in 317ms (compile: 19ms, render: 298ms)
+ GET / 200 in 338ms (compile: 8ms, render: 329ms)
+ GET / 200 in 310ms (compile: 4ms, render: 306ms)
+ GET / 200 in 327ms (compile: 10ms, render: 317ms)
+ GET / 200 in 314ms (compile: 4ms, render: 309ms)
+ GET / 200 in 345ms (compile: 15ms, render: 329ms)
+ GET / 200 in 336ms (compile: 7ms, render: 330ms)
+ GET / 200 in 402ms (compile: 5ms, render: 397ms)
+ GET / 200 in 442ms (compile: 7ms, render: 435ms)
+ GET / 200 in 506ms (compile: 12ms, render: 494ms)
+ GET / 200 in 567ms (compile: 11ms, render: 556ms)
+ GET / 200 in 567ms (compile: 20ms, render: 547ms)
+ GET / 200 in 515ms (compile: 8ms, render: 508ms)
+ GET / 200 in 441ms (compile: 8ms, render: 433ms)
+ GET / 200 in 388ms (compile: 12ms, render: 376ms)
+ GET / 200 in 285ms (compile: 39ms, render: 247ms)
+ GET / 200 in 214ms (compile: 4ms, render: 210ms)
+ GET / 200 in 154ms (compile: 7ms, render: 147ms)
+ GET / 200 in 124ms (compile: 7ms, render: 118ms)
+ GET / 200 in 76ms (compile: 6ms, render: 69ms)
+ GET / 200 in 687ms (compile: 18ms, render: 670ms)
+ GET / 200 in 467ms (compile: 22ms, render: 445ms)
+ Reload env: .env.local
+ GET / 200 in 395ms (compile: 290ms, render: 106ms)
+✓ Compiled in 4ms
+ GET / 200 in 345ms (compile: 9ms, render: 336ms)
+ GET /feed/subscriptions 200 in 263ms (compile: 199ms, render: 64ms)
+ GET /feed/library 200 in 175ms (compile: 138ms, render: 37ms)
+ GET / 200 in 44ms (compile: 9ms, render: 35ms)
+✓ Compiled in 94ms
+ GET / 200 in 501ms (compile: 104ms, render: 397ms)
+ GET / 200 in 121ms (compile: 35ms, render: 87ms)
+ GET /feed/subscriptions 200 in 111ms (compile: 95ms, render: 16ms)
+ GET /feed/library 200 in 32ms (compile: 7ms, render: 24ms)
+✓ Compiled in 91ms
+ GET /feed/library 200 in 345ms (compile: 96ms, render: 249ms)
+ GET /feed/subscriptions 200 in 23ms (compile: 4ms, render: 19ms)
+ GET /feed/subscriptions 200 in 67ms (compile: 7ms, render: 60ms)
+ GET / 200 in 34ms (compile: 6ms, render: 28ms)
+ GET /feed/subscriptions 200 in 27ms (compile: 3ms, render: 24ms)
+ GET / 200 in 18ms (compile: 6ms, render: 12ms)
+ GET /feed/subscriptions 200 in 26ms (compile: 7ms, render: 19ms)
+✓ Compiled in 56ms
+✓ Compiled in 22ms
+✓ Compiled in 19ms
+✓ Compiled in 18ms
+✓ Compiled in 24ms
+✓ Compiled in 74ms
+ GET /feed/subscriptions 200 in 152ms (compile: 106ms, render: 46ms)
+ GET /feed/subscriptions 200 in 300ms (compile: 3ms, render: 296ms)
+ GET /feed/J 404 in 661ms (compile: 611ms, render: 50ms)
+ GET /feed/subscriptions 200 in 15ms (compile: 4ms, render: 12ms)
+ GET /feed/library 200 in 26ms (compile: 3ms, render: 23ms)
+✓ Compiled in 14ms
+✓ Compiled in 22ms
+✓ Compiled in 81ms
+✓ Compiled in 30ms
+ GET / 200 in 40ms (compile: 10ms, render: 30ms)
+ GET / 200 in 617ms (compile: 32ms, render: 586ms)
+ GET /feed/subscriptions 200 in 43ms (compile: 10ms, render: 32ms)
+ GET /feed/subscriptions 200 in 91ms (compile: 5ms, render: 86ms)
+ GET /feed/J 404 in 180ms (compile: 42ms, render: 137ms)
+ GET /feed/library 200 in 174ms (compile: 113ms, render: 61ms)
+ GET /feed/library 200 in 529ms (compile: 4ms, render: 526ms)
+ GET /feed/subscriptions 200 in 26ms (compile: 4ms, render: 21ms)
+ GET /feed/library 200 in 35ms (compile: 8ms, render: 27ms)
+ GET /feed/library 200 in 29ms (compile: 3ms, render: 25ms)
+ GET /watch?v=HX3UcwUYMjM 200 in 234ms (compile: 178ms, render: 56ms)
+✓ Compiled in 48ms
+ GET /watch?v=CytWHfUVhXs 200 in 216ms (compile: 127ms, render: 89ms)
+✓ Compiled in 71ms
+✓ Compiled in 39ms
+✓ Compiled in 38ms
+✓ Compiled in 27ms
+✓ Compiled in 56ms
+✓ Compiled in 75ms
+ GET /watch?v=CytWHfUVhXs 200 in 313ms (compile: 240ms, render: 73ms)
+ GET /watch?v=CytWHfUVhXs 200 in 434ms (compile: 8ms, render: 426ms)
+✓ Compiled in 34ms
+ GET / 200 in 198ms (compile: 21ms, render: 177ms)
+ GET / 200 in 76ms (compile: 16ms, render: 61ms)
+✓ Compiled in 190ms
+✓ Compiled in 46ms
+✓ Compiled in 80ms
+✓ Compiled in 46ms
+✓ Compiled in 83ms
+✓ Compiled in 48ms
+✓ Compiled in 42ms
+ GET /?category=All 200 in 193ms (compile: 138ms, render: 54ms)
+✓ Compiled in 88ms
+ GET /?category=All 200 in 73ms (compile: 20ms, render: 53ms)
+✓ Compiled in 57ms
+⚠ Fast Refresh had to perform a full reload due to a runtime error.
+✓ Compiled in 78ms
+ GET /?category=All 200 in 1505ms (compile: 383ms, render: 1122ms)
+✓ Compiled in 98ms
+✓ Compiled in 65ms
+✓ Compiled in 51ms
+✓ Compiled in 48ms
+ GET /?category=All 200 in 434ms (compile: 122ms, render: 312ms)
+ GET /watch?v=XBPoRUlgD-0 200 in 152ms (compile: 119ms, render: 33ms)
+ GET /feed/subscriptions 200 in 223ms (compile: 178ms, render: 45ms)
+ GET /feed/J 404 in 287ms (compile: 125ms, render: 162ms)
+ GET /feed/library 200 in 122ms (compile: 95ms, render: 27ms)
+ GET /watch?v=cX-Oqdt7gmc 200 in 30ms (compile: 9ms, render: 21ms)
+ GET / 200 in 31ms (compile: 5ms, render: 26ms)
+ GET /search?q=Xreal 200 in 488ms (compile: 471ms, render: 17ms)
+ GET /search?q=Xreal 200 in 1132ms (compile: 945ms, render: 187ms)
+ GET /search?q=Xreal 200 in 426ms (compile: 12ms, render: 414ms)
+✓ Compiled in 502ms
+✓ Compiled in 259ms
+✓ Compiled in 74ms
+✓ Compiled in 93ms
+ GET /search?q=Xreal 200 in 508ms (compile: 119ms, render: 390ms)
+ GET / 200 in 19ms (compile: 6ms, render: 13ms)
+✓ Compiled in 53ms
+ GET / 200 in 345ms (compile: 126ms, render: 219ms)
+✓ Compiled in 66ms
+⚠ Fast Refresh had to perform a full reload due to a runtime error.
+✓ Compiled in 31ms
+ GET / 200 in 1721ms (compile: 312ms, render: 1409ms)
+✓ Compiled in 28ms
+✓ Compiled in 35ms
+ GET / 200 in 798ms (compile: 239ms, render: 558ms)
+ GET / 200 in 78ms (compile: 10ms, render: 68ms)
+✓ Compiled in 45ms
+ GET / 200 in 396ms (compile: 119ms, render: 277ms)
+✓ Compiled in 49ms
+ GET / 200 in 362ms (compile: 92ms, render: 271ms)
+✓ Compiled in 55ms
+✓ Compiled in 57ms
+ GET / 200 in 309ms (compile: 73ms, render: 236ms)
+ GET / 200 in 33ms (compile: 6ms, render: 27ms)
+ GET / 200 in 30ms (compile: 3ms, render: 27ms)
+✓ Compiled in 36ms
+✓ Compiled in 27ms
+ GET / 200 in 320ms (compile: 88ms, render: 232ms)
+ GET /watch?v=XBPoRUlgD-0 200 in 79ms (compile: 63ms, render: 16ms)
+ GET / 200 in 438ms (compile: 117ms, render: 320ms)
diff --git a/frontend/package.json b/frontend/package.json
index c9ed483..6da0907 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -9,18 +9,12 @@
"lint": "eslint"
},
"dependencies": {
- "@clappr/core": "^0.13.2",
- "@clappr/player": "^0.11.16",
"@fontsource/roboto": "^5.2.9",
- "@vidstack/react": "^1.12.13",
- "artplayer": "^5.3.0",
- "clappr": "^0.3.13",
"hls.js": "^1.6.15",
"next": "16.1.6",
"react": "19.2.3",
"react-dom": "19.2.3",
- "react-icons": "^5.5.0",
- "vidstack": "^1.12.13"
+ "react-icons": "^5.5.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4",
diff --git a/frontend/tmp/check_main_content.js b/frontend/tmp/check_main_content.js
deleted file mode 100644
index 040d9ba..0000000
--- a/frontend/tmp/check_main_content.js
+++ /dev/null
@@ -1 +0,0 @@
-console.log(document.querySelector(".yt-main-content").style.marginLeft); console.log(window.getComputedStyle(document.querySelector(".yt-main-content")).marginLeft);
diff --git a/page.html b/page.html
deleted file mode 100644
index e536c0f..0000000
--- a/page.html
+++ /dev/null
@@ -1,8 +0,0 @@
-KV-Tube
Home Shorts Subscriptions You
\ No newline at end of file
diff --git a/test-api.js b/test-api.js
new file mode 100644
index 0000000..bbc9134
--- /dev/null
+++ b/test-api.js
@@ -0,0 +1,36 @@
+// Test YouTube API key
+const https = require('https');
+
+const API_KEY = 'AIzaSyCn5pHLCpvmaIH5sG2HL_JBwRgfp36oq3g';
+
+function testAPI() {
+ const url = `https://www.googleapis.com/youtube/v3/search?key=${API_KEY}&part=snippet&q=music&type=video&maxResults=1`;
+
+ https.get(url, (res) => {
+ let data = '';
+
+ res.on('data', (chunk) => {
+ data += chunk;
+ });
+
+ res.on('end', () => {
+ console.log('Status Code:', res.statusCode);
+
+ if (res.statusCode === 200) {
+ const response = JSON.parse(data);
+ console.log('✅ API Key is working!');
+ console.log('Items found:', response.items?.length || 0);
+ if (response.items?.length > 0) {
+ console.log('Sample result:', response.items[0].snippet.title);
+ }
+ } else {
+ console.log('❌ API Key failed with status:', res.statusCode);
+ console.log('Response:', data);
+ }
+ });
+ }).on('error', (err) => {
+ console.error('Error:', err.message);
+ });
+}
+
+testAPI();
\ No newline at end of file