From 7cb5ba7182c734bef9a891f774099bc927d280d1 Mon Sep 17 00:00:00 2001 From: zhangyang8 Date: Fri, 17 Jul 2026 16:43:05 +0800 Subject: [PATCH] feat: Gate video clip linkage --- .../components/annotatedList/index.tsx | 19 +++++++++++---- .../videoAnnotate/videoClipTool/index.tsx | 6 ++++- .../src/components/videoPlayer/index.tsx | 24 +++++++++++++++---- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/packages/lb-components/src/components/videoAnnotate/videoClipTool/components/annotatedList/index.tsx b/packages/lb-components/src/components/videoAnnotate/videoClipTool/components/annotatedList/index.tsx index b40d3704..0871e70b 100644 --- a/packages/lb-components/src/components/videoAnnotate/videoClipTool/components/annotatedList/index.tsx +++ b/packages/lb-components/src/components/videoAnnotate/videoClipTool/components/annotatedList/index.tsx @@ -144,7 +144,14 @@ const VideoClipAnnotatedItem = ({ const VideoClipAnnotatedList = (props: { toolInstance: any }) => { const { toolInstance } = props - const { selectedID, result, videoPlayer, clipStatus, updateSelectedSliceTimeProperty } = toolInstance?.exportContext || {} + const { + selectedID, + result, + videoPlayer, + clipStatus, + updateSelectedSliceTimeProperty, + linkageConfigurable, + } = toolInstance?.exportContext || {} const [_, forceRender] = useState(0); const listRef = useRef(null); @@ -171,12 +178,14 @@ const VideoClipAnnotatedList = (props: { toolInstance: any }) => { [result, _], ); const handleItemClick = (timeSliceProps: IVideoTimeSlice) => { - skipScrollRef.current = true; + if (linkageConfigurable) { + skipScrollRef.current = true; + } toolInstance.exportContext.onSelectedTimeSlice(timeSliceProps); }; useLayoutEffect(() => { - if (!selectedID || !listRef.current) { + if (!linkageConfigurable || !selectedID || !listRef.current) { return; } if (skipScrollRef.current) { @@ -187,7 +196,7 @@ const VideoClipAnnotatedList = (props: { toolInstance: any }) => { if (index >= 0) { listRef.current.children[index]?.scrollIntoView({ block: 'nearest' }); } - }, [selectedID, _, resultList]); + }, [linkageConfigurable, selectedID, _, resultList]); if (!toolInstance?.exportContext) { return null @@ -195,7 +204,7 @@ const VideoClipAnnotatedList = (props: { toolInstance: any }) => { return (
{t('AnnotatedList')}
- + {resultList?.map((timeSliceProps: IVideoTimeSlice, index: number) => ( { removeTimeSlice: this.removeTimeSlice, updateSelectedSliceTimeProperty: this.updateSelectedSliceTimeProperty, extraResult: this.state.extraResult, + linkageConfigurable: this.props.config?.linkageConfigurable === true, }; } public fns: Map = new Map(); @@ -511,7 +512,9 @@ class VideoClipTool extends React.Component { this.setState({ currentTime: time, }); - this.selectTimeSliceByTime(time); + if (this.props.config?.linkageConfigurable === true) { + this.selectTimeSliceByTime(time); + } }; /** 根据时间查找片段 */ @@ -623,6 +626,7 @@ class VideoClipTool extends React.Component { toggleClipStatus={this.toggleClipStatus} addTime={this.addTime} updateCurrentTime={this.updateCurrentTime} + syncTimeOnPlay={this.props.config?.linkageConfigurable === true} /> {}, }); -const PER_INTERVAL = 300; +const PER_INTERVAL_DEFAULT = 50; +const PER_INTERVAL_SYNC = 300; const PER_FORWARD = 0.1; const PLAYBACK_RATES = [0.1, 0.2, 0.3, 0.4, 0.5, 1, 1.5, 2, 4, 6, 8, 16]; @@ -72,6 +73,8 @@ interface IVideoPlayerProps { toggleClipStatus?: () => void; drawLayerSlot?: any; updateCurrentTime?: (time: number) => void; + /** 开启后播放过程持续同步 currentTime(具身联动) */ + syncTimeOnPlay?: boolean; } interface IVideoPlayerState { @@ -209,26 +212,37 @@ export class VideoPlayer extends React.Component { + const syncTimeOnPlay = this.props.syncTimeOnPlay === true; + const interval = syncTimeOnPlay ? PER_INTERVAL_SYNC : PER_INTERVAL_DEFAULT; this.timeInterval = window.setInterval(() => { if (this.videoElm) { try { if (this.videoElm?.buffered.length > 0) { const buffered = this.videoElm?.buffered.end(0); - this.setState({ buffered }); + if (syncTimeOnPlay) { + this.setState({ buffered }); + } else { + this.setState({ + currentTime: decimalReserved(this.videoElm?.currentTime, 1), + buffered, + }); + } + } + if (syncTimeOnPlay) { + this.props.updateCurrentTime?.(decimalReserved(this.videoElm?.currentTime, 1)); } - this.props.updateCurrentTime?.(decimalReserved(this.videoElm?.currentTime, 1)); } catch (error) { console.error(error); } } - }, PER_INTERVAL); + }, interval); }; public resetVideoData = () => {