mirror of
https://gh-proxy.org/https://github.com/tiajinsha/JKVideo
synced 2026-07-08 07:28:37 +08:00
feat: 直播小窗播放(PiP)功能
- 新增 store/liveStore.ts:Zustand store,存储小窗直播状态(roomId/title/cover/hlsUrl) - 新增 components/LiveMiniPlayer.tsx:可拖动悬浮迷你直播播放器 - 原生端实际播放 HLS 流(react-native-video,有声) - Web 端降级展示封面图 + LIVE 徽标 - LIVE 红点徽标 + 标题条底部 - 关闭按钮(×)和点击进入直播间 - HLS 出错时自动关闭(onError → clearLive) - 视频 MiniPlayer 激活时自动上移避免重叠 - _layout.tsx:全局挂载 <LiveMiniPlayer /> - live/[roomId].tsx:顶部栏添加小窗按钮(browsers-outline) - 仅直播中且有流地址时显示,离线时占位保持 title 居中 - 点击后 setLive + router.back(),返回首页继续看直播 - 进入同房间时自动 clearLive() 避免双播
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useState } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
@@ -18,6 +18,7 @@ import DanmakuList from "../../components/DanmakuList";
|
||||
import { formatCount } from "../../utils/format";
|
||||
import { proxyImageUrl } from "../../utils/imageUrl";
|
||||
import { useTheme } from "../../utils/theme";
|
||||
import { useLiveStore } from "../../store/liveStore";
|
||||
|
||||
type Tab = "intro" | "danmaku";
|
||||
|
||||
@@ -36,6 +37,15 @@ export default function LiveDetailScreen() {
|
||||
const qualities = stream?.qualities ?? [];
|
||||
const currentQn = stream?.qn ?? 0;
|
||||
|
||||
const { roomId: miniRoomId, setLive, clearLive } = useLiveStore();
|
||||
|
||||
// 进入该直播间时,若小窗正在播放同一房间,清除小窗避免双播
|
||||
useEffect(() => {
|
||||
if (miniRoomId === id) {
|
||||
clearLive();
|
||||
}
|
||||
}, [id, miniRoomId]);
|
||||
|
||||
const actualRoomId = room?.roomid ?? id;
|
||||
const { danmakus, giftCounts } = useLiveDanmaku(isLive ? actualRoomId : 0);
|
||||
|
||||
@@ -49,6 +59,19 @@ export default function LiveDetailScreen() {
|
||||
<Text style={[styles.topTitle, { color: theme.text }]} numberOfLines={1}>
|
||||
{room?.title ?? "直播间"}
|
||||
</Text>
|
||||
{isLive && hlsUrl ? (
|
||||
<TouchableOpacity
|
||||
style={styles.pipBtn}
|
||||
onPress={() => {
|
||||
setLive(id, room?.title ?? '', room?.keyframe ?? '', hlsUrl);
|
||||
router.back();
|
||||
}}
|
||||
>
|
||||
<Ionicons name="browsers-outline" size={22} color={theme.text} />
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<View style={styles.pipBtn} />
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* Player */}
|
||||
@@ -177,6 +200,7 @@ const styles = StyleSheet.create({
|
||||
borderBottomWidth: StyleSheet.hairlineWidth,
|
||||
},
|
||||
backBtn: { padding: 4 },
|
||||
pipBtn: { padding: 4, width: 32, alignItems: 'center' },
|
||||
topTitle: {
|
||||
flex: 1,
|
||||
fontSize: 15,
|
||||
|
||||
Reference in New Issue
Block a user