import React, { useState, useRef, useEffect } from 'react'; import { View, StyleSheet, Text, Platform, Modal, StatusBar, useWindowDimensions } from 'react-native'; // expo-screen-orientation requires a dev build; gracefully degrade in Expo Go let ScreenOrientation: typeof import('expo-screen-orientation') | null = null; try { ScreenOrientation = require('expo-screen-orientation'); } catch {} import { NativeVideoPlayer, type NativeVideoPlayerRef } from './NativeVideoPlayer'; import type { PlayUrlResponse, DanmakuItem } from '../services/types'; interface Props { playData: PlayUrlResponse | null; qualities: { qn: number; desc: string }[]; currentQn: number; onQualityChange: (qn: number) => void; bvid?: string; cid?: number; danmakus?: DanmakuItem[]; onTimeUpdate?: (t: number) => void; } export function VideoPlayer({ playData, qualities, currentQn, onQualityChange, bvid, cid, danmakus, onTimeUpdate }: Props) { const [fullscreen, setFullscreen] = useState(false); const { width, height } = useWindowDimensions(); const VIDEO_HEIGHT = width * 0.5625; const needsRotation = !ScreenOrientation && fullscreen; const lastTimeRef = useRef(0); const portraitRef = useRef(null); const handleEnterFullscreen = async () => { if (Platform.OS !== 'web') await ScreenOrientation?.lockAsync(ScreenOrientation.OrientationLock.LANDSCAPE_RIGHT); setFullscreen(true); }; const handleExitFullscreen = async () => { // 退出全屏:同步进度,竖屏一律暂停 portraitRef.current?.seek(lastTimeRef.current); portraitRef.current?.setPaused(true); setFullscreen(false); if (Platform.OS !== 'web') await ScreenOrientation?.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT_UP); }; useEffect(() => { return () => { if (Platform.OS !== 'web') ScreenOrientation?.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT_UP); }; }, []); if (!playData) { return ( 视频加载中... ); } if (Platform.OS === 'web') { const url = playData.durl?.[0]?.url ?? ''; return ( ); } return ( <> {/* Portrait player: always mounted, force-paused while fullscreen is active */} { lastTimeRef.current = t; onTimeUpdate?.(t); }} /> ); } const styles = StyleSheet.create({ placeholder: { justifyContent: 'center', alignItems: 'center' }, placeholderText: { color: '#fff', fontSize: 14 }, });