修复观影室weblive跳转
This commit is contained in:
@@ -154,7 +154,6 @@ export default function WatchRoomPage() {
|
||||
if (!currentRoom || isOwner) return;
|
||||
|
||||
const handlePlayChange = (state: any) => {
|
||||
console.log('[WatchRoom] Member following owner - play:change event');
|
||||
if (state.type === 'play') {
|
||||
const params = new URLSearchParams({
|
||||
id: state.videoId,
|
||||
@@ -171,9 +170,17 @@ export default function WatchRoomPage() {
|
||||
};
|
||||
|
||||
const handleLiveChange = (state: any) => {
|
||||
console.log('[WatchRoom] Member following owner - live:change event');
|
||||
if (state.type === 'live') {
|
||||
router.push(`/live?id=${state.channelId}`);
|
||||
// 判断是否为 weblive 格式(channelUrl 包含 platform:roomId)
|
||||
if (state.channelUrl && state.channelUrl.includes(':')) {
|
||||
// weblive 格式,导航到 web-live 页面
|
||||
// channelId 是 sourceKey,channelUrl 是 platform:roomId
|
||||
const [platform, roomId] = state.channelUrl.split(':');
|
||||
router.push(`/web-live?platform=${platform}&roomId=${roomId}`);
|
||||
} else {
|
||||
// 普通 live 格式,导航到 live 页面
|
||||
router.push(`/live?id=${state.channelId}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -264,7 +271,15 @@ export default function WatchRoomPage() {
|
||||
if (state.searchTitle) params.set('stitle', state.searchTitle);
|
||||
router.push(`/play?${params.toString()}`);
|
||||
} else if (state.type === 'live') {
|
||||
router.push(`/live?id=${state.channelId}`);
|
||||
// 判断是否为 weblive 格式(channelUrl 包含 platform:roomId)
|
||||
if (state.channelUrl && state.channelUrl.includes(':')) {
|
||||
// weblive 格式,导航到 web-live 页面
|
||||
const [platform, roomId] = state.channelUrl.split(':');
|
||||
router.push(`/web-live?platform=${platform}&roomId=${roomId}`);
|
||||
} else {
|
||||
// 普通 live 格式,导航到 live 页面
|
||||
router.push(`/live?id=${state.channelId}`);
|
||||
}
|
||||
}
|
||||
}}
|
||||
className="px-6 py-2 bg-white text-blue-600 font-medium rounded-lg hover:bg-white/90 transition-colors whitespace-nowrap"
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
'use client';
|
||||
|
||||
import { AlertTriangle,Radio } from 'lucide-react';
|
||||
import { useRouter, useSearchParams } from 'next/navigation';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
|
||||
import { useWebLiveSync } from '@/hooks/useWebLiveSync';
|
||||
|
||||
import PageLayout from '@/components/PageLayout';
|
||||
import { useWatchRoomContextSafe } from '@/components/WatchRoomProvider';
|
||||
|
||||
let Artplayer: any = null;
|
||||
let Hls: any = null;
|
||||
let flvjs: any = null;
|
||||
|
||||
export default function WebLivePage() {
|
||||
const searchParams = useSearchParams();
|
||||
const router = useRouter();
|
||||
const artRef = useRef<HTMLDivElement | null>(null);
|
||||
const artPlayerRef = useRef<any>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -28,6 +32,8 @@ export default function WebLivePage() {
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [selectedPlatform, setSelectedPlatform] = useState<string | null>(null);
|
||||
const [isWebLiveEnabled, setIsWebLiveEnabled] = useState<boolean | null>(null);
|
||||
const [librariesLoaded, setLibrariesLoaded] = useState(false);
|
||||
const hasAutoLoadedRef = useRef(false); // 防止重复自动加载
|
||||
|
||||
// 观影室同步功能
|
||||
const webLiveSync = useWebLiveSync({
|
||||
@@ -52,9 +58,14 @@ export default function WebLivePage() {
|
||||
document.head.appendChild(meta);
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
import('artplayer').then(mod => { Artplayer = mod.default; });
|
||||
import('hls.js').then(mod => { Hls = mod.default; });
|
||||
import('flv.js').then(mod => { flvjs = mod.default; });
|
||||
// 异步加载所有必需的库
|
||||
Promise.all([
|
||||
import('artplayer').then(mod => { Artplayer = mod.default; }),
|
||||
import('hls.js').then(mod => { Hls = mod.default; }),
|
||||
import('flv.js').then(mod => { flvjs = mod.default; })
|
||||
]).then(() => {
|
||||
setLibrariesLoaded(true);
|
||||
});
|
||||
|
||||
// 检查网络直播功能是否启用
|
||||
const runtimeConfig = (window as any).RUNTIME_CONFIG;
|
||||
@@ -93,6 +104,41 @@ export default function WebLivePage() {
|
||||
}
|
||||
};
|
||||
|
||||
// 当 sources 加载完成后,检查 URL 参数并自动加载对应的频道
|
||||
useEffect(() => {
|
||||
if (!sources || sources.length === 0) return;
|
||||
if (!librariesLoaded) return; // 等待库加载完成
|
||||
|
||||
// 直接从 searchParams 读取,而不是从 useState
|
||||
const needLoadPlatform = searchParams.get('platform');
|
||||
const needLoadRoomId = searchParams.get('roomId');
|
||||
|
||||
if (!needLoadPlatform || !needLoadRoomId) {
|
||||
hasAutoLoadedRef.current = false; // 重置标志
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否已经加载了这个频道
|
||||
if (currentSource?.platform === needLoadPlatform && currentSource?.roomId === needLoadRoomId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 防止重复加载
|
||||
if (hasAutoLoadedRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
hasAutoLoadedRef.current = true;
|
||||
|
||||
// 查找匹配的 source
|
||||
const foundSource = sources.find(s => s.platform === needLoadPlatform && s.roomId === needLoadRoomId);
|
||||
if (foundSource) {
|
||||
handleSourceClick(foundSource);
|
||||
} else {
|
||||
hasAutoLoadedRef.current = false; // 重置标志以便重试
|
||||
}
|
||||
}, [sources, librariesLoaded, searchParams]);
|
||||
|
||||
function m3u8Loader(video: HTMLVideoElement, url: string) {
|
||||
if (!Hls) return;
|
||||
const hls = new Hls({ debug: false, enableWorker: true, lowLatencyMode: true });
|
||||
@@ -212,12 +258,31 @@ export default function WebLivePage() {
|
||||
setIsVideoLoading(true);
|
||||
setErrorMessage(null);
|
||||
setStreamInfo(null);
|
||||
|
||||
// 更新 URL 参数
|
||||
const newSearchParams = new URLSearchParams(searchParams.toString());
|
||||
newSearchParams.set('platform', source.platform);
|
||||
newSearchParams.set('roomId', source.roomId);
|
||||
router.replace(`/web-live?${newSearchParams.toString()}`);
|
||||
|
||||
try {
|
||||
const res = await fetch(`/api/web-live/stream?platform=${source.platform}&roomId=${source.roomId}`);
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
setVideoUrl(data.url);
|
||||
setOriginalVideoUrl(data.originalUrl || data.url);
|
||||
|
||||
// 等待 DOM 渲染完成后再设置 videoUrl
|
||||
const waitForDom = () => {
|
||||
if (artRef.current) {
|
||||
setVideoUrl(data.url);
|
||||
setOriginalVideoUrl(data.originalUrl || data.url);
|
||||
} else {
|
||||
requestAnimationFrame(waitForDom);
|
||||
}
|
||||
};
|
||||
|
||||
// 使用 requestAnimationFrame 等待下一帧
|
||||
requestAnimationFrame(waitForDom);
|
||||
|
||||
// 保存主播信息
|
||||
if (data.name || data.title) {
|
||||
setStreamInfo({
|
||||
|
||||
Reference in New Issue
Block a user