From 983b35f91441d782b2f7e97c75c23bb3e8691342 Mon Sep 17 00:00:00 2001 From: callmeyan Date: Mon, 16 Dec 2024 19:50:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=92=AD=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/video/video-list-item.tsx | 2 +- src/pages/live/index.tsx | 79 +++++++++++++++++------- src/service/api/live.ts | 5 +- src/types/api.d.ts | 8 ++- 4 files changed, 66 insertions(+), 28 deletions(-) diff --git a/src/components/video/video-list-item.tsx b/src/components/video/video-list-item.tsx index ec647f3..b74522f 100644 --- a/src/components/video/video-list-item.tsx +++ b/src/components/video/video-list-item.tsx @@ -51,7 +51,7 @@ export const VideoListItem = ( className={`video-item-info flex gap-2 flex-1 bg-gray-100 h-[80px] overflow-hidden rounded-lg p-3 shadow-blue-500 ${active ? 'video-item-shadow' : ''}`}>
{video.title || video.video_title}
- {video.video_title}/ + {video.video_title}/
diff --git a/src/pages/live/index.tsx b/src/pages/live/index.tsx index af456fa..34abbb6 100644 --- a/src/pages/live/index.tsx +++ b/src/pages/live/index.tsx @@ -1,17 +1,18 @@ -import React, {useEffect, useState} from "react"; -import {Button, message, Modal} from "antd"; +import React, {useEffect, useRef, useState} from "react"; +import {Button, Modal} from "antd"; import {SortableContext, arrayMove} from '@dnd-kit/sortable'; import {DndContext} from "@dnd-kit/core"; import {VideoListItem} from "@/components/video/video-list-item.tsx"; import {deleteByIds, getList, modifyOrder, playState} from "@/service/api/live.ts"; -import styles from './style.module.scss' -import {set} from "lodash"; import {showErrorToast, showToast} from "@/components/message.ts"; import ButtonBatch from "@/components/button-batch.tsx"; +import FlvJs from "flv.js"; +const cache: { flvPlayer?: FlvJs.Player } = {} export default function LiveIndex() { + const videoRef = useRef(null) const [videoData, setVideoData] = useState([]) const [modal, contextHolder] = Modal.useModal() const [checkedIdArray, setCheckedIdArray] = useState([]) @@ -54,12 +55,57 @@ export default function LiveIndex() { // 找到对应video item 并显示在视图可见区域 showVideoItem(activeIndex) } + const playVideo = (video: LiveVideoInfo, state: LiveState) => { + if (videoRef.current && video.video_oss_url) { + const playedTime = Date.now() / 1000 >> 0 - state.start_time + if (playedTime < 0 || playedTime > video.video_duration) { // 已播放时间大于总时长了 + initPlayingState() // 重新获取播放状态 + return; + } + if (/mp4$/i.test(video.video_oss_url)) { + videoRef.current!.src = video.video_oss_url + videoRef.current!.currentTime = playedTime + videoRef.current!.play() + return; + } + if (FlvJs.isSupported()) { + + // 已经有播放实例 则销毁 + if (cache.flvPlayer) { + cache.flvPlayer.pause() + cache.flvPlayer.unload() + } + cache.flvPlayer = FlvJs.createPlayer({ + type: 'flv', + url: video.video_oss_url + }) + + cache.flvPlayer.on('ended', () => { + //activeToNext() + initPlayingState() + }) + cache.flvPlayer.attachMediaElement(videoRef.current!) + cache.flvPlayer.load() + cache.flvPlayer.currentTime = playedTime + cache.flvPlayer.play() + } + } + } const initPlayingState = (videoList?: LiveVideoInfo[] | null) => { const list = videoList || videoData || [] - playState().then(ret => { - setState({ - activeIndex: list.findIndex(v => v.id === ret.id) - }) + playState().then(state => { + const video = list.find(v => v.id === state.id) + if (video) { + activeToNext(list.findIndex(v => v.id === state.id)) + playVideo(video, state) + } else { + setState({activeIndex: -1}) + setTimeout(() => { + initPlayingState() + }, 5000) + } + + }); } const loadList = () => { @@ -74,8 +120,8 @@ export default function LiveIndex() { useEffect(loadList, []) const processDeleteVideo = async (ids: number[]) => { - deleteByIds(ids).then(()=>{ - showToast('删除成功!','success') + deleteByIds(ids).then(() => { + showToast('删除成功!', 'success') loadList() }).catch(showErrorToast) } @@ -115,6 +161,8 @@ export default function LiveIndex() {
数字人直播间
+ {/**/}
@@ -155,22 +203,11 @@ export default function LiveIndex() { const {active, over} = e; if (over && active.id !== over.id) { let oldIndex = -1, newIndex = -1; - // const originArr = [...videoData] setVideoData((items) => { oldIndex = items.findIndex(s => s.id == active.id); newIndex = items.findIndex(s => s.id == over.id); return arrayMove(items, oldIndex, newIndex); }); - // modal.confirm({ - // title: '提示', - // content: '是否要移动到指定位置', - // onCancel: () => { - // setVideoData(originArr); - // }, - // onOk: () => { - // setVideoData([...videoData]) - // } - // }) } }}> diff --git a/src/service/api/live.ts b/src/service/api/live.ts index ed09fba..23d14a3 100644 --- a/src/service/api/live.ts +++ b/src/service/api/live.ts @@ -1,10 +1,7 @@ import {post} from "@/service/request.ts"; export function playState() { - return post<{ - id: number; - start_time?: number; - }>({url: '/room/playing'}) + return post({url: '/room/playing'}) } export function getList() { diff --git a/src/types/api.d.ts b/src/types/api.d.ts index 1f7968b..3a53c41 100644 --- a/src/types/api.d.ts +++ b/src/types/api.d.ts @@ -83,7 +83,7 @@ declare interface ListCrawlerNewsItem extends BasicArticleInfo { declare interface VideoInfo { id: number; title: string; - cover?: string; + cover: string; oss_video_url: string; duration: number; article_id: number; @@ -94,10 +94,14 @@ declare interface LiveVideoInfo { id: number; video_id: number; video_title: string; - cover_url: string; + cover: string; video_duration: number; video_oss_url: string; status: number; order_no: string; } +declare interface LiveState{ + id: number; + start_time?: number; +}