From 8e41b9c07bd14b31bfe90dab665382d88bd1147c Mon Sep 17 00:00:00 2001 From: callmeyan Date: Tue, 24 Dec 2024 00:02:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=92=AD=E6=94=BE=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/video/player.tsx | 4 ++ src/pages/live/index.tsx | 31 ++++++++++----- src/pages/video/index.tsx | 68 ++++++++++++++++++++------------- src/util/strings.ts | 4 ++ 4 files changed, 70 insertions(+), 37 deletions(-) diff --git a/src/components/video/player.tsx b/src/components/video/player.tsx index 54cfd4f..b0126bf 100644 --- a/src/components/video/player.tsx +++ b/src/components/video/player.tsx @@ -21,6 +21,7 @@ type Props = { url?: string; cover?: string; showControls?: boolean; className?: string; poster?: string; onChange?: (state: State) => void; + onProgress?: (current:number,duration:number) => void; muted?: boolean; } export type PlayerInstance = { @@ -84,6 +85,9 @@ export const Player = React.forwardRef((props, ref) => { player.on('ended', () => { setState({end: true, playing: false, error: false}) }) + player.on('timeupdate', () => { + props.onProgress?.(player.currentTime(), player.duration()) + }) player.on('error', () => { setState({end: false, playing: false, error: true}) }) diff --git a/src/pages/live/index.tsx b/src/pages/live/index.tsx index e8d148f..c40c09c 100644 --- a/src/pages/live/index.tsx +++ b/src/pages/live/index.tsx @@ -32,7 +32,8 @@ export default function LiveIndex() { muted: true, showToTop: false, checkedAll: false, - originSort:'' + originSort: '', + playProgress: 0 }) const activeIndex = useRef(state.activeIndex) useEffect(() => { @@ -114,7 +115,7 @@ export default function LiveIndex() { // console.log('origin list', res.list.map(s => s.id)) setVideoData(() => (res.list || [])) setState({ - originSort: res.list?res.list.map(s => s.id).join(','):'' + originSort: res.list ? res.list.map(s => s.id).join(',') : '' }) setCheckedIdArray([]) }); @@ -138,7 +139,7 @@ export default function LiveIndex() { return; } const newSort = videoData.map(s => s.id).join(',') - if(newSort == state.originSort){ + if (newSort == state.originSort) { setEditable(false) return; } @@ -149,10 +150,10 @@ export default function LiveIndex() { onOk: () => { //showToast('编辑成功!!!', 'info'); modifyOrder(videoData.map(s => s.id)).then(() => { - showToast('已完成直播队列的修改!','success') + showToast('已完成直播队列的修改!', 'success') setEditable(false) }).catch(() => { - showToast('调整视频顺序失败,请重试!','warning') + showToast('调整视频顺序失败,请重试!', 'warning') }) }, onCancel: () => { @@ -178,8 +179,11 @@ export default function LiveIndex() { const currentTotalDuration = useMemo(() => { if (state.activeIndex == -1 || !videoData || videoData.length == 0) return 0; // 计算总时长 - return videoData.filter((_,index)=>(index <= state.activeIndex)).reduce((sum, v) => sum + Math.ceil(v.video_duration / 1000), 0); - }, [videoData]) + return videoData + .filter((_, index) => (index < state.activeIndex)) + .reduce((sum, v) => sum + Math.ceil(v.video_duration / 1000), 0) + state.playProgress + ; + }, [videoData, state.playProgress]) const currentSelectedId = useMemo(() => { if (state.activeIndex < 0 || state.activeIndex >= videoData.length) return []; @@ -192,12 +196,18 @@ export default function LiveIndex() {
- {formatDuration(currentTotalDuration)} / {formatDuration(totalDuration)} + 视频时长: {formatDuration(currentTotalDuration)} / {formatDuration(totalDuration)}
- + { + setState({playProgress: progress}) + }} + />
@@ -241,7 +251,8 @@ export default function LiveIndex() { setState({showToTop: top > 30})} - onCallback={()=>{}} + onCallback={() => { + }} >
{ diff --git a/src/pages/video/index.tsx b/src/pages/video/index.tsx index 7e91721..914e822 100644 --- a/src/pages/video/index.tsx +++ b/src/pages/video/index.tsx @@ -16,18 +16,23 @@ import ButtonToTop from "@/components/scoller/button-to-top.tsx"; import InfiniteScroller, {InfiniteScrollerRef} from "@/components/scoller/infinite-scroller.tsx"; import {IconDelete} from "@/components/icons"; import {useLocation} from "react-router-dom"; +import {playState} from "@/service/api/live.ts"; export default function VideoIndex() { const [editId, setEditId] = useState(-1) const loc = useLocation() const [videoData, setVideoData] = useState([]) const player = useRef(null) - const scrollerRef = useRef(null) + const scrollerRef = useRef(null) const [state, setState] = useSetState({ checkedAll: false, playingIndex: -1, showToTop: false, - showStatePos: false + showStatePos: false, + playState: { + current: -1, + total: -1 + } }) const [checkedIdArray, setCheckedIdArray] = useState([]) @@ -50,19 +55,19 @@ export default function VideoIndex() { // 播放视频 const playVideo = (video: VideoInfo, playingIndex: number) => { - if(state.playingIndex == playingIndex){ + if (state.playingIndex == playingIndex) { player.current?.pause(); setState({playingIndex: -1}) return; } - if(video.status == VideoStatus.Generating ) return; - setState({playingIndex}) - player.current?.play('https://staticplus.gachafun.com/ai-collect/composite_video/2024-12-17/1186196465916190720.flv',30) + if (video.status == VideoStatus.Generating) return; + // setState({playingIndex}) + // player.current?.play('https://staticplus.gachafun.com/ai-collect/composite_video/2024-12-17/1186196465916190720.flv', 30) // - // if (video.oss_video_url && video.status !== 1) { - // setState({playingIndex}) - // player.current?.play(video.oss_video_url, 0) - // } + if (video.oss_video_url && video.status !== 1) { + setState({playingIndex}) + player.current?.play(video.oss_video_url, 0) + } } // 处理全选 const handleAllCheckedChange = () => { @@ -71,35 +76,35 @@ export default function VideoIndex() { checkedAll: !state.checkedAll }) } - const handleModifySort = (items:VideoInfo[]) => { + const handleModifySort = (items: VideoInfo[]) => { modifyOrder(items.map(s => s.id)).then(() => { - showToast('调整视频顺序成功!','success') - }).catch(()=>{ + showToast('调整视频顺序成功!', 'success') + }).catch(() => { loadList(); - showToast('调整视频顺序失败,请重试!','warning') + showToast('调整视频顺序失败,请重试!', 'warning') }) } // useEffect(loadList, []) const totalDuration = useMemo(() => { if (!videoData || videoData.length == 0) return 0; - if(state.playingIndex == -1 || state.playingIndex >= videoData.length) return 0 - const v= videoData[state.playingIndex] as VideoInfo; + if (state.playingIndex == -1 || state.playingIndex >= videoData.length) return 0 + const v = videoData[state.playingIndex] as VideoInfo; return Math.ceil(v.duration / 1000) // 计算总时长 //return videoData.reduce((sum, v) => sum + Math.ceil(v.duration / 1000), 0); - }, [videoData,state.playingIndex]) + }, [videoData, state.playingIndex]) - useEffect(()=>{ - if(loc.state == 'push-success' && !state.showStatePos && videoData.length && scrollerRef.current){ + useEffect(() => { + if (loc.state == 'push-success' && !state.showStatePos && videoData.length && scrollerRef.current) { const generatingItem = document.querySelector(`.list-item-state-${VideoStatus.Generating}`) - if(generatingItem){ + if (generatingItem) { generatingItem.scrollIntoView({behavior: 'smooth'}) setState({showStatePos: true}) } } - },[videoData,scrollerRef]) + }, [videoData, scrollerRef]) const processDeleteVideo = async (ids: Id[]) => { deleteByIds(ids).then(() => { showToast('删除成功!', 'success') @@ -116,12 +121,21 @@ export default function VideoIndex() { { + console.log(state) if (state.end || state.error) setState({playingIndex: -1}) }} + onProgress={(current, duration) => { + setState({ + playState: { + current: current, + total: duration + } + }) + }} className="w-[360px] h-[640px] bg-white"/>
-
视频时长: {formatDuration(totalDuration)}
+
{formatDuration(state.playState.current)} / {formatDuration(state.playState.total)}
@@ -132,7 +146,7 @@ export default function VideoIndex() { 全选 {/**/} - handleAllCheckedChange()} /> + handleAllCheckedChange()}/>
@@ -145,7 +159,7 @@ export default function VideoIndex() {
- setState({showToTop: top > 30})}> + setState({showToTop: top > 30})}> { videoData.length == 0 ?
:
@@ -191,7 +205,7 @@ export default function VideoIndex() { return newArr; }) }} - onItemClick={ () => playVideo(v, index)} + onItemClick={() => playVideo(v, index)} onRemove={() => processDeleteVideo([v.id])} onEdit={v.status == VideoStatus.Generating ? undefined : () => { setEditId(v.article_id) @@ -208,7 +222,7 @@ export default function VideoIndex() {
- scrollerRef.current?.scrollToPosition(0)}/> + scrollerRef.current?.scrollToPosition(0)}/> {checkedIdArray.length > 0 && 批量删除 - + }
diff --git a/src/util/strings.ts b/src/util/strings.ts index 759015a..7954ab1 100644 --- a/src/util/strings.ts +++ b/src/util/strings.ts @@ -90,6 +90,10 @@ export function calcContentLengthLikeWord(str:string) { // 将时长转换成 时:分:秒 export function formatDuration(duration: number) { + if(duration < 0 || isNaN(duration)){ + return '00:00:00'; + } + duration = Math.ceil(duration); const hour = Math.floor(duration / 3600); const minute = Math.floor((duration - hour * 3600) / 60); const second = duration - hour * 3600 - minute * 60;