import React, { useState, useRef, useCallback, useEffect } from 'react'; import { View, Text, StyleSheet, TouchableOpacity, TouchableWithoutFeedback, Modal, Platform, useWindowDimensions, } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; interface Props { hlsUrl: string; isLive: boolean; // false → show offline placeholder } const HIDE_DELAY = 3000; const HEADERS = { Referer: 'https://live.bilibili.com', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', }; export function LivePlayer({ hlsUrl, isLive }: Props) { const { width: SCREEN_W, height: SCREEN_H } = useWindowDimensions(); const VIDEO_H = SCREEN_W * 0.5625; if (Platform.OS === 'web') { return ( 请在手机端观看直播 ); } if (!isLive || !hlsUrl) { return ( 暂未开播 ); } return ; } function NativeLivePlayer({ hlsUrl, screenW, screenH, videoH, }: { hlsUrl: string; screenW: number; screenH: number; videoH: number; }) { // Lazy import to avoid web bundle issues const Video = require('react-native-video').default; const [showControls, setShowControls] = useState(true); const [paused, setPaused] = useState(false); const [isFullscreen, setIsFullscreen] = useState(false); const [buffering, setBuffering] = useState(true); const hideTimer = useRef | null>(null); const resetHideTimer = useCallback(() => { if (hideTimer.current) clearTimeout(hideTimer.current); hideTimer.current = setTimeout(() => setShowControls(false), HIDE_DELAY); }, []); useEffect(() => { resetHideTimer(); return () => { if (hideTimer.current) clearTimeout(hideTimer.current); }; }, []); const handleTap = useCallback(() => { setShowControls(prev => { if (!prev) { resetHideTimer(); return true; } if (hideTimer.current) clearTimeout(hideTimer.current); return false; }); }, [resetHideTimer]); const containerStyle = isFullscreen ? { width: screenH, height: screenW } : { width: screenW, height: videoH }; const videoContent = (