forked from 77media/video-flow
兼容人物识别失败
This commit is contained in:
parent
310ea1c49f
commit
7c16179288
@ -352,7 +352,7 @@ export function MediaViewer({
|
|||||||
<GlassIconButton
|
<GlassIconButton
|
||||||
icon={Edit3}
|
icon={Edit3}
|
||||||
tooltip="Edit sketch"
|
tooltip="Edit sketch"
|
||||||
onClick={() => handleEditClick('4', 'final')}
|
onClick={() => handleEditClick('3', 'final')}
|
||||||
/>
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
@ -766,7 +766,7 @@ export function MediaViewer({
|
|||||||
<GlassIconButton
|
<GlassIconButton
|
||||||
icon={Edit3}
|
icon={Edit3}
|
||||||
tooltip="Edit sketch"
|
tooltip="Edit sketch"
|
||||||
onClick={() => handleEditClick('2')}
|
onClick={() => handleEditClick('1')}
|
||||||
/>
|
/>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useRef, useEffect, forwardRef } from "react";
|
import React, { useState, useRef, useEffect, forwardRef } from "react";
|
||||||
import { motion } from "framer-motion";
|
import { motion } from "framer-motion";
|
||||||
import { Sparkles, X, Plus, RefreshCw } from 'lucide-react';
|
import { Sparkles, X, Plus, RefreshCw, Loader2 } from 'lucide-react';
|
||||||
import MainEditor from "./main-editor/MainEditor";
|
import MainEditor from "./main-editor/MainEditor";
|
||||||
import { cn } from "@/public/lib/utils";
|
import { cn } from "@/public/lib/utils";
|
||||||
import { TextToShotAdapter } from "@/app/service/adapter/textToShot";
|
import { TextToShotAdapter } from "@/app/service/adapter/textToShot";
|
||||||
@ -76,8 +76,8 @@ export const CharacterEditor = forwardRef<any, CharacterEditorProps>(({
|
|||||||
whileHover={{ scale: 1.05 }}
|
whileHover={{ scale: 1.05 }}
|
||||||
whileTap={{ scale: 0.95 }}
|
whileTap={{ scale: 0.95 }}
|
||||||
>
|
>
|
||||||
<Sparkles className="w-3.5 h-3.5" />
|
{isOptimizing ? <Loader2 className="w-3.5 h-3.5 animate-spin" /> : <Sparkles className="w-3.5 h-3.5" />}
|
||||||
<span>{isOptimizing ? "优化中..." : "智能优化"}</span>
|
<span>{isOptimizing ? "Optimizing..." : "Optimization"}</span>
|
||||||
</motion.button>
|
</motion.button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -34,7 +34,7 @@ interface EditModalProps {
|
|||||||
const tabs = [
|
const tabs = [
|
||||||
{ id: '0', label: 'Script', icon: FileText },
|
{ id: '0', label: 'Script', icon: FileText },
|
||||||
{ id: '1', label: 'Character', icon: Users },
|
{ id: '1', label: 'Character', icon: Users },
|
||||||
{ id: '2', label: 'Scene', icon: Image },
|
// { id: '2', label: 'Scene', icon: Image },
|
||||||
{ id: '3', label: 'Video', icon: Video },
|
{ id: '3', label: 'Video', icon: Video },
|
||||||
{ id: '4', label: 'Music', icon: Music },
|
{ id: '4', label: 'Music', icon: Music },
|
||||||
// { id: '5', label: '剪辑', icon: Scissors },
|
// { id: '5', label: '剪辑', icon: Scissors },
|
||||||
|
|||||||
@ -109,6 +109,7 @@ export const PersonDetectionScene: React.FC<Props> = ({
|
|||||||
// 处理外部失败状态
|
// 处理外部失败状态
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isScanFailed && scanStatus === 'scanning') {
|
if (isScanFailed && scanStatus === 'scanning') {
|
||||||
|
console.log('roleRecognitionResponse---isScanFailed', isScanFailed);
|
||||||
setScanStatus('failed');
|
setScanStatus('failed');
|
||||||
}
|
}
|
||||||
}, [isScanFailed, scanStatus]);
|
}, [isScanFailed, scanStatus]);
|
||||||
@ -268,12 +269,12 @@ export const PersonDetectionScene: React.FC<Props> = ({
|
|||||||
>
|
>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
{!isShowError ? (
|
{!isShowError ? (
|
||||||
<span className="text-cyan-400 text-sm font-medium tracking-wider">
|
<span className="text-cyan-400 text-sm font-medium tracking-wider whitespace-nowrap">
|
||||||
智能识别中
|
Intelligenting portrait recognition
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="text-red-400 text-sm font-medium tracking-wider">
|
<span className="text-red-400 text-sm font-medium tracking-wider whitespace-nowrap">
|
||||||
{scanStatus === 'timeout' ? '识别超时,请重试' : '识别失败,请重试'}
|
{scanStatus === 'timeout' ? 'Timeout, please try again' : 'Failed, please try again'}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -379,7 +380,7 @@ export const PersonDetectionScene: React.FC<Props> = ({
|
|||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{detections.length === 0 && triggerSuccess && (
|
{detections.length === 0 && triggerSuccess && (
|
||||||
<div className="absolute inset-0 flex items-center justify-center bg-black/40 backdrop-blur-sm">
|
<div className="absolute inset-0 flex items-center justify-center bg-black/40 backdrop-blur-sm">
|
||||||
<span className="text-white text-sm">未识别出人像</span>
|
<span className="text-white text-sm">No portrait detected</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{detections.map((person, index) => {
|
{detections.map((person, index) => {
|
||||||
|
|||||||
@ -52,11 +52,11 @@ export function ReplaceCharacterPanel({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ReplacePanel
|
<ReplacePanel
|
||||||
title="替换新形象"
|
title="Replace the new role"
|
||||||
shots={shots}
|
shots={shots}
|
||||||
item={role}
|
item={role}
|
||||||
showAddToLibrary={showAddToLibrary}
|
showAddToLibrary={showAddToLibrary}
|
||||||
addToLibraryText="新形象同步添加至角色库"
|
addToLibraryText="Add new role to library"
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
onConfirm={onConfirm}
|
onConfirm={onConfirm}
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export function ReplacePanel({
|
|||||||
shots,
|
shots,
|
||||||
item,
|
item,
|
||||||
showAddToLibrary = false,
|
showAddToLibrary = false,
|
||||||
addToLibraryText = "同步添加至库",
|
addToLibraryText = "Add to library",
|
||||||
onClose,
|
onClose,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
}: ReplacePanelProps) {
|
}: ReplacePanelProps) {
|
||||||
@ -122,9 +122,9 @@ export function ReplacePanel({
|
|||||||
|
|
||||||
{/* 提示信息 */}
|
{/* 提示信息 */}
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-2 text-sm text-red-400">
|
<div className="flex items-center gap-2 text-red-400">
|
||||||
<CircleAlert className="w-4 h-4" />
|
<CircleAlert className="w-4 h-4" />
|
||||||
该内容出现在 <span className="text-blue-500">{shots.length}</span> 个分镜中,替换后将影响如下分镜
|
This role appears in <span className="text-blue-500 font-bold">{shots.length}</span> shots, replacing it will affect the following shots.
|
||||||
</div>
|
</div>
|
||||||
{/* <div className="flex items-center gap-2">
|
{/* <div className="flex items-center gap-2">
|
||||||
<input
|
<input
|
||||||
@ -177,7 +177,7 @@ export function ReplacePanel({
|
|||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
<div className="absolute inset-0 bg-black/50 flex items-center justify-center">
|
<div className="absolute inset-0 bg-black/50 flex items-center justify-center">
|
||||||
<div className="text-white text-sm">生成中...</div>
|
<div className="text-white text-sm">Generating...</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -235,13 +235,13 @@ export function ReplacePanel({
|
|||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="px-4 py-2 rounded-lg bg-white/10 text-white hover:bg-white/20 transition-colors"
|
className="px-4 py-2 rounded-lg bg-white/10 text-white hover:bg-white/20 transition-colors"
|
||||||
>
|
>
|
||||||
取消
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={handleConfirm}
|
onClick={handleConfirm}
|
||||||
className="px-4 py-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600 transition-colors"
|
className="px-4 py-2 rounded-lg bg-blue-500 text-white hover:bg-blue-600 transition-colors"
|
||||||
>
|
>
|
||||||
替换
|
Replace
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -70,18 +70,22 @@ export function ShotTabContent({
|
|||||||
}
|
}
|
||||||
setScanState('scanning');
|
setScanState('scanning');
|
||||||
const containerElement = document.getElementById('person-detection-video') as HTMLVideoElement;
|
const containerElement = document.getElementById('person-detection-video') as HTMLVideoElement;
|
||||||
const roleRecognitionResponse = await filterRole(containerElement);
|
try {
|
||||||
console.log('roleRecognitionResponse', roleRecognitionResponse);
|
const roleRecognitionResponse = await filterRole(containerElement);
|
||||||
if (roleRecognitionResponse && roleRecognitionResponse.recognition_result.code === 200) {
|
console.log('roleRecognitionResponse', roleRecognitionResponse);
|
||||||
const recognitionBoxes = calculateRecognitionBoxes(containerElement, roleRecognitionResponse.recognition_result.data.matched_persons);
|
if (roleRecognitionResponse && roleRecognitionResponse.recognition_result.code === 200) {
|
||||||
console.log('recognitionBoxes', recognitionBoxes);
|
const recognitionBoxes = calculateRecognitionBoxes(containerElement, roleRecognitionResponse.recognition_result.data.matched_persons);
|
||||||
setDetections(recognitionBoxes.map((person: any) => ({
|
console.log('recognitionBoxes', recognitionBoxes);
|
||||||
id: person.person_id,
|
setDetections(recognitionBoxes.map((person: any) => ({
|
||||||
name: person.person_id,
|
id: person.person_id,
|
||||||
position: { top: person.top, left: person.left, width: person.width, height: person.height }
|
name: person.person_id,
|
||||||
})));
|
position: { top: person.top, left: person.left, width: person.width, height: person.height }
|
||||||
|
})));
|
||||||
|
} else {
|
||||||
|
setIsScanFailed(true);
|
||||||
|
}
|
||||||
setScanState('detected');
|
setScanState('detected');
|
||||||
} else {
|
} catch (error) {
|
||||||
setIsScanFailed(true);
|
setIsScanFailed(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user