From e1617cf4e2fb138accc7a2c8b505434e1d473c89 Mon Sep 17 00:00:00 2001 From: lihqi <455711093@qq.com> Date: Wed, 23 Oct 2024 10:14:44 +0800 Subject: [PATCH] fix(lb-components): Convert dirty audio data to normal data --- .../src/components/audioAnnotate/index.tsx | 89 +++++++++++-------- .../audioAnnotate/utils/dataTransform.ts | 48 +++++++++- .../audioPlayer/useAudioSegment/index.tsx | 6 +- packages/lb-components/src/index.tsx | 3 + 4 files changed, 102 insertions(+), 44 deletions(-) diff --git a/packages/lb-components/src/components/audioAnnotate/index.tsx b/packages/lb-components/src/components/audioAnnotate/index.tsx index 9cea35a9e..1fa8fcec3 100644 --- a/packages/lb-components/src/components/audioAnnotate/index.tsx +++ b/packages/lb-components/src/components/audioAnnotate/index.tsx @@ -36,6 +36,8 @@ import ToggleTagModeASvg from '@/assets/annotation/audio/tagA.svg'; import ClipSvg from '@/assets/annotation/audio/clip.svg'; import ClipASvg from '@/assets/annotation/audio/clipA.svg'; import { isImageValue } from '@/utils/audio'; +import AudioDataTransform from './utils/dataTransform'; +import { useMemoizedFn } from 'ahooks'; const { EAudioToolName } = cTool; const EKeyCode = cKeyCode.default; @@ -350,10 +352,20 @@ const AudioAnnotate: React.FC = (props) => { const { toolInstanceRef } = useCustomToolInstance({ basicInfo }); const [loading, setLoading] = useState(true); - const [result, setResult] = useState(null); + const [result, _setResult] = useState(null); const [duration, setDuration] = useState(0); const [valid, setValid] = useState(true); + // Convert dirty data to normal data + const setResult = (data: any) => { + if (!data) { + return; + } + const fixedData = AudioDataTransform.fixData(data); + + _setResult(fixedData); + }; + useEffect(() => { setLoading(true); }, [imgIndex]); @@ -511,55 +523,53 @@ const AudioAnnotate: React.FC = (props) => { setDuration(duration); }; - const removeRegion = (id: string) => { - setResult((result: any) => ({ - ...result, + const removeRegion = useMemoizedFn((id: string) => { + setResult({ + ...(result || {}), regions: (result?.regions || []).filter((item: any) => item.id !== id), - })); - }; + }); + }); - const updateRegion = (region: IAudioTimeSlice) => { - setResult((result: any) => { - const currentRegions: IAudioTimeSlice[] = result?.regions ?? []; - const { id } = region; - const currentRegion = currentRegions.find((item: IAudioTimeSlice) => item.id === id); - if (currentRegion) { - return { - ...result, - regions: currentRegions.map((item: IAudioTimeSlice) => { - if (id === item.id) { - return { - ...item, - ...region, - }; - } - return item; - }), - }; - } else { - return { - ...result, - regions: [...currentRegions, region], - }; - } + const updateRegion = useMemoizedFn((region: IAudioTimeSlice) => { + const currentRegions: IAudioTimeSlice[] = result?.regions ?? []; + const { id } = region; + const currentRegion = currentRegions.find((item: IAudioTimeSlice) => item.id === id); + + let newRegions = []; + if (currentRegion) { + newRegions = currentRegions.map((item: IAudioTimeSlice) => { + if (id === item.id) { + return { + ...item, + ...region, + }; + } + return item; + }); + } else { + newRegions = [...currentRegions, region]; + } + + setResult({ + ...result, + regions: newRegions, }); - }; + }); const updateText = (val: string, key: string) => { - setResult((result: any) => ({ + const newResult = { ...result, value: { ...result.value, [key]: val, }, - })); + }; + setResult(newResult); }; const updateTagResult = (tagResult: any) => { - setResult((result: any) => ({ - ...result, - tag: tagResult, - })); + const newResult = { ...result, tag: tagResult }; + setResult(newResult); }; const updateResult = (result: any) => { @@ -567,12 +577,13 @@ const AudioAnnotate: React.FC = (props) => { }; const clearResult = () => { - setResult((result: any) => ({ + const newResult = { ...result, value: getInitValue(), tag: {}, regions: [], - })); + }; + setResult(newResult); EventBus.emit('clearRegions'); }; diff --git a/packages/lb-components/src/components/audioAnnotate/utils/dataTransform.ts b/packages/lb-components/src/components/audioAnnotate/utils/dataTransform.ts index 757a29a2f..ca8fd9551 100644 --- a/packages/lb-components/src/components/audioAnnotate/utils/dataTransform.ts +++ b/packages/lb-components/src/components/audioAnnotate/utils/dataTransform.ts @@ -7,7 +7,20 @@ import { IAudioTimeSlice, ITextConfigItem } from '@labelbee/lb-utils'; import _ from 'lodash'; -export default class DataTransform { +function traverseObject(obj: any, callback: (key: any, value: any, item: any) => void) { + if (typeof obj === 'object' && obj !== null) { + for (let key in obj) { + if (obj.hasOwnProperty(key)) { + callback(key, obj[key], obj); + if (typeof obj[key] === 'object' && obj[key] !== null) { + traverseObject(obj[key], callback); + } + } + } + } +} + +export default class AudioDataTransform { // clip tool get text by config public static getClipTextByConfig = ( region: IAudioTimeSlice, @@ -17,7 +30,7 @@ export default class DataTransform { const newRegion = _.cloneDeep(region); clipTextList.forEach((i, index) => { // index === 0: Compatible with old data - const defaultValue = i?.default ?? '' + const defaultValue = i?.default ?? ''; if (index === 0) { Object.assign(newRegion, { text: isDefault ? defaultValue : region[i.key] }); } else { @@ -26,4 +39,35 @@ export default class DataTransform { }); return newRegion; }; + + public static fixData = (data: any) => { + const result: any = {}; + + // 只保留一个值的 key + const uniqueKeys = ['id', 'sourceID']; + // 需要合并的数组或对象的 key + const needMergeKeys = ['value', 'tag', 'regions']; + // number类型的key + const needAddKeys = ['preDiffCount']; + + traverseObject(data, (key, value) => { + if (uniqueKeys.includes(key) && !result[key]) { + result[key] = value; + return; + } + if (needMergeKeys.includes(key)) { + if (Array.isArray(value)) { + result[key] = [...(result[key] ?? []), ...value]; + return; + } + result[key] = { ...(result[key] ?? {}), ...value }; + return; + } + if (needAddKeys.includes(key) && value >= 0) { + result[key] = value; + return; + } + }); + return result; + }; } diff --git a/packages/lb-components/src/components/audioPlayer/useAudioSegment/index.tsx b/packages/lb-components/src/components/audioPlayer/useAudioSegment/index.tsx index afebdd088..7b5e4c4e7 100644 --- a/packages/lb-components/src/components/audioPlayer/useAudioSegment/index.tsx +++ b/packages/lb-components/src/components/audioPlayer/useAudioSegment/index.tsx @@ -11,7 +11,7 @@ import { useAudioClipStore } from '@/components/audioAnnotate/audioContext'; import { useEventListener, useMemoizedFn } from 'ahooks'; import { ISetSelectedRegionParams } from '..'; import { IAudioTimeSlice } from '@labelbee/lb-utils'; -import DataTransform from '@/components/audioAnnotate/utils/dataTransform'; +import AudioDataTransform from '@/components/audioAnnotate/utils/dataTransform'; const EKeyCode = cKeyCode.default; interface IProps { @@ -69,14 +69,14 @@ const useAudioSegment = (props: IProps) => { return; } const current = regionMap[id]; - const newData = DataTransform.getClipTextByConfig(current, clipTextList); + const newData = AudioDataTransform.getClipTextByConfig(current, clipTextList); const targetLeft = { ...newData, id: waveRef.current?.util.getId('segment_'), end: time, subAttribute: current.subAttribute ?? {}, }; - const clearText = DataTransform.getClipTextByConfig(current, clipTextList, true); + const clearText = AudioDataTransform.getClipTextByConfig(current, clipTextList, true); const targetRight = { ...clearText, id: waveRef.current?.util.getId('segment_'), diff --git a/packages/lb-components/src/index.tsx b/packages/lb-components/src/index.tsx index 7c1115de2..c1ee1641e 100644 --- a/packages/lb-components/src/index.tsx +++ b/packages/lb-components/src/index.tsx @@ -34,6 +34,8 @@ import { ToolStyleProvider } from './hooks/useToolStyle'; import { LoadFileAndFileData } from './store/annotation/reducer'; import useToolConfigStore from '@/store/toolConfig'; import { LLMMultiWheelSourceView } from './components/LLMMultiWheelView'; +import AudioDataTransform from './components/audioAnnotate/utils/dataTransform'; + export const store = configureStore(); @@ -108,6 +110,7 @@ export { generatePointCloudBoxRects, SubAttributeList, useToolConfigStore, + AudioDataTransform, }; export * from './constant';