forked from 77media/video-flow
推进
This commit is contained in:
parent
87efe72eeb
commit
f55724a545
@ -221,21 +221,21 @@ export const useImageStoryServiceHook = (): UseImageStoryService => {
|
||||
return charactersAnalysis.map((character) => {
|
||||
console.log('character', character)
|
||||
// 如果已经有头像URL,直接返回
|
||||
if (character.avatarUrl) {
|
||||
if (character.crop_url) {
|
||||
return {
|
||||
name: character.role_name,
|
||||
url: character.avatarUrl,
|
||||
url: character.crop_url,
|
||||
};
|
||||
}
|
||||
|
||||
// 异步生成头像URL
|
||||
generateAvatarFromRegion(character, activeImageUrl);
|
||||
// // 异步生成头像URL
|
||||
// generateAvatarFromRegion(character, activeImageUrl);
|
||||
|
||||
return {
|
||||
name: character.role_name,
|
||||
url: "", // 初始为空,异步生成完成后会更新
|
||||
};
|
||||
});
|
||||
// return {
|
||||
// name: character.role_name,
|
||||
// url: "", // 初始为空,异步生成完成后会更新
|
||||
// };
|
||||
}).filter(Boolean) as { name: string; url: string }[];
|
||||
}, [charactersAnalysis, activeImageUrl, generateAvatarFromRegion]);
|
||||
/**
|
||||
* 上传图片并分析
|
||||
|
||||
@ -35,7 +35,7 @@ import StarterKit from "@tiptap/starter-kit";
|
||||
import { HighlightTextExtension } from "@/components/ui/main-editor/HighlightText";
|
||||
import Placeholder from "@tiptap/extension-placeholder";
|
||||
import { createMovieProjectV1 } from "@/api/video_flow";
|
||||
import { useLoadScriptText } from "@/app/service/domain/service";
|
||||
import { useLoadScriptText, useUploadFile } from "@/app/service/domain/service";
|
||||
|
||||
// 自定义音频播放器样式
|
||||
const customAudioPlayerStyles = `
|
||||
@ -556,7 +556,7 @@ export function ChatInputBox() {
|
||||
|
||||
// 调用创建剧集API
|
||||
const episodeResponse = await createMovieProjectV1(episodeData);
|
||||
console.log('episodeResponse', episodeResponse);
|
||||
console.log("episodeResponse", episodeResponse);
|
||||
if (episodeResponse.code !== 0) {
|
||||
console.error(`创建剧集失败: ${episodeResponse.message}`);
|
||||
alert(`创建剧集失败: ${episodeResponse.message}`);
|
||||
@ -704,11 +704,11 @@ export function ChatInputBox() {
|
||||
</Tooltip>
|
||||
|
||||
{/* 图片故事弹窗 */}
|
||||
<PhotoStoryModal
|
||||
isOpen={isPhotoStoryModalOpen}
|
||||
onClose={() => setIsPhotoStoryModalOpen(false)}
|
||||
configOptions={configOptions}
|
||||
/>
|
||||
<PhotoStoryModal
|
||||
isOpen={isPhotoStoryModalOpen}
|
||||
onClose={() => setIsPhotoStoryModalOpen(false)}
|
||||
configOptions={configOptions}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 右侧Action按钮 */}
|
||||
@ -762,7 +762,6 @@ const ActionButton = ({
|
||||
<button
|
||||
name="text"
|
||||
className="w-full h-full opacity-90 rounded-xl bg-black flex items-center justify-center"
|
||||
|
||||
>
|
||||
{isCreating ? <Loader2 className="w-5 h-5 animate-spin" /> : icon}
|
||||
</button>
|
||||
@ -1042,9 +1041,10 @@ const PhotoStoryModal = ({
|
||||
uploadAndAnalyzeImage,
|
||||
setCharactersAnalysis,
|
||||
originalUserDescription,
|
||||
actionMovie
|
||||
actionMovie,
|
||||
} = useImageStoryServiceHook();
|
||||
const { loadingText } = useLoadScriptText(isLoading);
|
||||
const { uploadFile } = useUploadFile();
|
||||
// 重置状态
|
||||
const handleClose = () => {
|
||||
resetImageStory();
|
||||
@ -1072,13 +1072,13 @@ const PhotoStoryModal = ({
|
||||
}
|
||||
|
||||
// 调用actionMovie接口
|
||||
const episodeResponse = await actionMovie(
|
||||
const episodeResponse = await actionMovie(
|
||||
String(User.id),
|
||||
configOptions.mode as "auto" | "manual",
|
||||
configOptions.resolution as "720p" | "1080p" | "4k",
|
||||
configOptions.language
|
||||
);
|
||||
if(!episodeResponse) return
|
||||
if (!episodeResponse) return;
|
||||
let episodeId = episodeResponse.project_id;
|
||||
// let episodeId = '9c34fcc4-c8d8-44fc-879e-9bd56f608c76';
|
||||
router.push(`/create/work-flow?episodeId=${episodeId}`);
|
||||
@ -1096,7 +1096,7 @@ const PhotoStoryModal = ({
|
||||
footer={null}
|
||||
width="80%"
|
||||
style={{ maxWidth: "1000px", marginTop: "10vh" }}
|
||||
className="photo-story-modal"
|
||||
className="photo-story-modal bg-white/[0.08] backdrop-blur-[20px] [&_.ant-modal-content]:bg-white/[0.00]"
|
||||
closeIcon={
|
||||
<div className="w-6 h-6 bg-white/10 rounded-full flex items-center justify-center hover:bg-white/20 transition-colors">
|
||||
<span className="text-white/70 text-lg leading-none flex items-center justify-center">
|
||||
@ -1114,7 +1114,7 @@ const PhotoStoryModal = ({
|
||||
Movie Generation from Image
|
||||
</h2>
|
||||
</div>
|
||||
<div className="w-full bg-white/[0.05] border border-white/[0.1] rounded-xl p-4 mt-2">
|
||||
<div className="w-full bg-white/[0.04] border border-white/[0.1] rounded-xl p-4 mt-2">
|
||||
<div className="flex items-start gap-4">
|
||||
{/* 左侧:图片上传 */}
|
||||
<div className="flex-shrink-0">
|
||||
@ -1164,7 +1164,7 @@ const PhotoStoryModal = ({
|
||||
key={`${avatar.name}-${index}`}
|
||||
className="flex flex-col items-center"
|
||||
>
|
||||
<div className="relative w-14 h-14 rounded-sm overflow-hidden bg-white/[0.05] border border-white/[0.1] mb-2 group">
|
||||
<div className="relative w-14 h-14 rounded-sm overflow-hidden bg-white/[0.05] border border-white/[0.1] mb-2 group cursor-pointer">
|
||||
<img
|
||||
src={avatar.url}
|
||||
alt={avatar.name}
|
||||
@ -1194,7 +1194,10 @@ const PhotoStoryModal = ({
|
||||
// 从故事内容中删除该角色的所有标签和引用
|
||||
const updatedStory = storyContent
|
||||
.replace(
|
||||
new RegExp(`<role[^>]*>${avatar.name}<\/role>`, "g"),
|
||||
new RegExp(
|
||||
`<role[^>]*>${avatar.name}<\/role>`,
|
||||
"g"
|
||||
),
|
||||
""
|
||||
)
|
||||
.replace(
|
||||
@ -1211,6 +1214,61 @@ const PhotoStoryModal = ({
|
||||
<Trash2 className="w-2.5 h-2.5" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
{/* 上传新图片按钮 - 悬停时显示 */}
|
||||
<Tooltip
|
||||
title="Click to upload new image for this character"
|
||||
placement="top"
|
||||
>
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
// 创建隐藏的文件输入框
|
||||
const input = document.createElement("input");
|
||||
input.type = "file";
|
||||
input.accept = "image/*";
|
||||
input.style.display = "none";
|
||||
|
||||
input.onchange = async (event) => {
|
||||
const target =
|
||||
event.target as HTMLInputElement;
|
||||
const file = target.files?.[0];
|
||||
if (file) {
|
||||
try {
|
||||
// 使用七牛云上传
|
||||
const newImageUrl = await uploadFile(
|
||||
file
|
||||
);
|
||||
|
||||
// 更新角色分析中的图片URL
|
||||
setCharactersAnalysis((prev) =>
|
||||
prev.map((char) =>
|
||||
char.role_name === avatar.name
|
||||
? { ...char, crop_url: newImageUrl }
|
||||
: char
|
||||
)
|
||||
);
|
||||
|
||||
// 清理临时元素
|
||||
document.body.removeChild(input);
|
||||
} catch (error) {
|
||||
console.error("上传图片失败:", error);
|
||||
// 清理临时元素
|
||||
if (document.body.contains(input)) {
|
||||
document.body.removeChild(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 添加到DOM并触发点击
|
||||
document.body.appendChild(input);
|
||||
input.click();
|
||||
}}
|
||||
className="absolute inset-0 bg-black/20 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex items-center justify-center"
|
||||
>
|
||||
<Upload className="w-4 h-4 text-white" />
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div className="relative group">
|
||||
<input
|
||||
@ -1236,7 +1294,7 @@ const PhotoStoryModal = ({
|
||||
{hasAnalyzed && potentialGenres.length > 0 && (
|
||||
<div className="flex-shrink-0 animate-in fade-in-0 slide-in-from-right-4 duration-300">
|
||||
<div className="flex gap-2">
|
||||
{[ ...potentialGenres].map((genre) => (
|
||||
{[...potentialGenres].map((genre) => (
|
||||
<button
|
||||
key={genre}
|
||||
onClick={() => updateStoryType(genre)}
|
||||
@ -1255,7 +1313,9 @@ const PhotoStoryModal = ({
|
||||
</div>
|
||||
{/* 原始用户描述的展示 */}
|
||||
{originalUserDescription && (
|
||||
<div className="mt-2 text-sm text-white/30 italic">Your Provided Text:{originalUserDescription}</div>
|
||||
<div className="mt-2 text-sm text-white/30 italic">
|
||||
Your Provided Text:{originalUserDescription}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex items-start gap-4 mt-2 relative">
|
||||
|
||||
@ -292,7 +292,7 @@ export function ThumbnailGrid({
|
||||
className={`w-full h-full object-cover transition-all duration-300 select-none ${
|
||||
(!taskObject.shot_sketch.data[index]) ? 'filter blur-sm opacity-60' : ''
|
||||
}`}
|
||||
src={taskObject.shot_sketch.data[index] ? taskObject.shot_sketch.data[index].url : video.urls[0]}
|
||||
src={taskObject.shot_sketch.data[index] ? taskObject.shot_sketch.data[index].url : video.urls?.[0] || ''}
|
||||
alt={`Thumbnail ${index + 1}`}
|
||||
draggable="false"
|
||||
/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user