mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-15 06:12:18 +00:00
Merge pull request #518 from storytold/feature/page/video_transfer
Feature/page/video transfer
This commit is contained in:
12 files changed
+161
-100
No files matched your search
@@ -11,6 +11,7 @@ import './styles.scss';
|
||||
export interface VideoFakeyouProps{
|
||||
wrapperClassName?: string;
|
||||
controls?:boolean;
|
||||
muted?:boolean;
|
||||
className?:string;
|
||||
src?:string;
|
||||
mediaToken?: string;
|
||||
@@ -23,6 +24,7 @@ type Ref = HTMLVideoElement;
|
||||
const VideoFakeyou = forwardRef<Ref, VideoFakeyouProps>(({
|
||||
wrapperClassName,
|
||||
controls,
|
||||
muted,
|
||||
className,
|
||||
src,
|
||||
mediaToken,
|
||||
@@ -43,10 +45,11 @@ const VideoFakeyou = forwardRef<Ref, VideoFakeyouProps>(({
|
||||
|
||||
if (mediaLink){
|
||||
return (
|
||||
<div {...{ ...makeClass("fy-video vh50",wrapperClassName) }}>
|
||||
<div {...{ ...makeClass("fy-video",wrapperClassName) }}>
|
||||
{label && <Label label={label}/>}
|
||||
<video
|
||||
controls={controls}
|
||||
muted={muted}
|
||||
ref={ref}
|
||||
key={mediaToken}
|
||||
{...{
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
&.fit-content {
|
||||
height: fit-content;
|
||||
}
|
||||
&.vh50{
|
||||
height: 50vh;
|
||||
}
|
||||
|
||||
video, .video-overlay {
|
||||
border-radius: .5rem;
|
||||
width: 100%;
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import React, {
|
||||
memo,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useLayoutEffect,
|
||||
useState,
|
||||
useRef,
|
||||
PointerEvent
|
||||
PointerEvent,
|
||||
} from "react";
|
||||
import {
|
||||
faPlay,
|
||||
faPause,
|
||||
faGripDots
|
||||
faGripDots,
|
||||
faVolume,
|
||||
faVolumeSlash,
|
||||
} from "@fortawesome/pro-solid-svg-icons"
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
@@ -19,79 +21,53 @@ import {
|
||||
} from "components/common";
|
||||
import { VideoFakeyouProps } from "../VideoFakeyou/VideoFakeyou";
|
||||
|
||||
import { QuickTrimData, TrimStates, PlaybarStates } from "./types";
|
||||
import { formatSecondsToHHMMSSCS } from "./helpers";
|
||||
import './styles.scss'
|
||||
|
||||
function roundTo2Dec(floaty:number){
|
||||
return Math.round(floaty*100)/100;
|
||||
}
|
||||
function fractionToPercentage(fraction:number){
|
||||
return roundTo2Dec(fraction * 100);
|
||||
}
|
||||
function formatSecondsToHHMMSS(seconds:number){
|
||||
if(seconds < 3600)
|
||||
return new Date(seconds * 1000).toISOString().substring(14, 19)
|
||||
else
|
||||
return new Date(seconds * 1000).toISOString().slice(11, 19);
|
||||
}
|
||||
|
||||
export type QuickTrimType = {
|
||||
trimStartSeconds: number;
|
||||
trimEndSeconds: number;
|
||||
}
|
||||
|
||||
interface VideoQuickTrimProps extends VideoFakeyouProps{
|
||||
onSelect: (val: QuickTrimType)=>void;
|
||||
onSelect: (values: QuickTrimData)=>void;
|
||||
}
|
||||
|
||||
type TrimState = {
|
||||
isScrubbingTrim: boolean;
|
||||
trimDuration: number;
|
||||
trimStart: number;
|
||||
trimEnd: number;
|
||||
maxDuration: number;
|
||||
}
|
||||
const initialTrimState = {
|
||||
const trimOptions: { [key: string]: number } = {
|
||||
"3s": 3,
|
||||
"5s": 5,
|
||||
"10s": 10,
|
||||
"15s" : 15,
|
||||
};
|
||||
|
||||
const initialTrimState:TrimStates = {
|
||||
isScrubbingTrim: false,
|
||||
trimDuration: 3,
|
||||
trimStart: 0,
|
||||
trimEnd: 0,
|
||||
maxDuration: 0,
|
||||
}
|
||||
type PlaybarState = {
|
||||
playbarWidth: number;
|
||||
timeCursorOffset: number;
|
||||
}
|
||||
const initialPlaybarState = {
|
||||
|
||||
const initialPlaybarState:PlaybarStates = {
|
||||
playbarWidth: 0,
|
||||
timeCursorOffset: 0,
|
||||
}
|
||||
|
||||
export default function VideoQuickTrim({
|
||||
export default memo(function VideoQuickTrim({
|
||||
onSelect,
|
||||
...rest
|
||||
}: VideoQuickTrimProps){
|
||||
console.log("Rerender!!");
|
||||
|
||||
const trimOptions: { [key: string]: number } = {
|
||||
"3s": 3,
|
||||
"5s": 5,
|
||||
"10s": 10,
|
||||
"15s" : 15,
|
||||
"20s" : 20,
|
||||
};
|
||||
console.log("VideoQuickTrim Rerender!!");
|
||||
|
||||
const videoRef = useRef<HTMLVideoElement | null>(null);
|
||||
const playbarRef = useRef<HTMLDivElement | null>(null);
|
||||
const trimZoneRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [{playbarWidth, timeCursorOffset}, setPlaybarState] = useState<PlaybarState>(initialPlaybarState);
|
||||
const [{playbarWidth, timeCursorOffset}, setPlaybarState] = useState<PlaybarStates>(initialPlaybarState);
|
||||
const [playpause, setPlaypause] = useState<'playing'|'paused'|'stopped'>('paused');
|
||||
const [isMuted, setIsMuted] = useState<boolean>(false);
|
||||
const [{
|
||||
trimStart,
|
||||
trimEnd,
|
||||
// trimEnd,
|
||||
trimDuration,
|
||||
isScrubbingTrim,
|
||||
}, setTrimState] = useState<TrimState>(initialTrimState);
|
||||
}, setTrimState] = useState<TrimStates>(initialTrimState);
|
||||
|
||||
|
||||
|
||||
@@ -137,15 +113,13 @@ export default function VideoQuickTrim({
|
||||
setTrimState((curr)=>({
|
||||
...curr,
|
||||
trimDuration: trimOptions[selected],
|
||||
trimEnd: curr.trimStart+ trimOptions[selected],
|
||||
trimEnd: trimStart+ trimOptions[selected],
|
||||
}))
|
||||
}
|
||||
useEffect(()=>{
|
||||
onSelect({
|
||||
trimStartSeconds: trimStart,
|
||||
trimEndSeconds: trimEnd,
|
||||
trimEndSeconds: trimStart+ trimOptions[selected],
|
||||
});
|
||||
},[trimStart, trimEnd, onSelect]);
|
||||
}
|
||||
|
||||
const handlePlaypause = ()=>{
|
||||
if (playpause === 'paused' || playpause === 'stopped'){
|
||||
@@ -156,11 +130,13 @@ export default function VideoQuickTrim({
|
||||
setPlaypause('paused');
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="fy-video-quicktrim">
|
||||
<div className="video-wrapper">
|
||||
<VideoFakeyou
|
||||
controls={false}
|
||||
muted={isMuted}
|
||||
ref={videoRefCallback}
|
||||
{...rest}
|
||||
/>
|
||||
@@ -175,7 +151,6 @@ export default function VideoQuickTrim({
|
||||
icon={faPause} size="8x"
|
||||
/>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>{/* END of Video Wrapper */}
|
||||
<div className="playbar" ref={playbarRefCallback}>
|
||||
@@ -207,9 +182,9 @@ export default function VideoQuickTrim({
|
||||
}}
|
||||
onPointerMove={(e: PointerEvent<HTMLDivElement>)=>{
|
||||
if(trimZoneRef.current && playbarRef.current && isScrubbingTrim){
|
||||
console.log(fractionToPercentage(
|
||||
(e.clientX - trimZoneRef.current.getBoundingClientRect().left) / (playbarRef.current.getBoundingClientRect().width)
|
||||
) + "%");
|
||||
// console.log(fractionToPercentage(
|
||||
// (e.clientX - trimZoneRef.current.getBoundingClientRect().left) / (playbarRef.current.getBoundingClientRect().width)
|
||||
// ) + "%");
|
||||
}
|
||||
}}
|
||||
>
|
||||
@@ -221,12 +196,29 @@ export default function VideoQuickTrim({
|
||||
<div className="d-flex w-100 justify-content-between mt-3 flex-wrap">
|
||||
<div className="playpause-external d-flex align-items-center flex-wrap mb-2">
|
||||
<Button
|
||||
className="button-playpause"
|
||||
icon={playpause === 'playing' ? faPause : faPlay}
|
||||
variant="secondary"
|
||||
onClick={handlePlaypause}
|
||||
/>
|
||||
<div className="playtime ms-3">
|
||||
<p>{`${formatSecondsToHHMMSS(videoRef.current?.currentTime || 0)} / ${formatSecondsToHHMMSS(videoRef.current?.duration || 0)}`}</p>
|
||||
<Button
|
||||
className="button-mute"
|
||||
icon={isMuted ? faVolumeSlash : faVolume}
|
||||
variant="secondary"
|
||||
onClick={()=>setIsMuted((curr)=>(!curr))}
|
||||
/>
|
||||
<div className="playtime ms-2 d-flex">
|
||||
<span >
|
||||
<p>
|
||||
{`${formatSecondsToHHMMSSCS(videoRef.current?.currentTime || 0)}`}
|
||||
</p>
|
||||
</span>
|
||||
<div>/</div>
|
||||
<span>
|
||||
<p>
|
||||
{`${formatSecondsToHHMMSSCS(videoRef.current?.duration || 0)}`}
|
||||
</p>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<SelectionBubbles
|
||||
@@ -236,4 +228,4 @@ export default function VideoQuickTrim({
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
export function roundTo2Dec(floaty:number){
|
||||
return Math.round(floaty*100)/100;
|
||||
}
|
||||
export function fractionToPercentage(fraction:number){
|
||||
return roundTo2Dec(fraction * 100);
|
||||
}
|
||||
export function formatSecondsToHHMMSSCS(seconds:number){
|
||||
//example of the ISO String: 1970-01-01T00:01:40.774Z
|
||||
const isoString = new Date(seconds * 1000).toISOString();
|
||||
if(seconds > 3600)
|
||||
return isoString.substring(11, 19) + "." + isoString.substring(20, 22)
|
||||
else
|
||||
return isoString.substring(14, 19) + "." + isoString.substring(20, 22);
|
||||
}
|
||||
@@ -1 +1,5 @@
|
||||
export { default } from './VideoQuickTrim';
|
||||
import VideoQuickTrim from './VideoQuickTrim'
|
||||
import { QuickTrimData } from './types';
|
||||
|
||||
export type { QuickTrimData };
|
||||
export default VideoQuickTrim;
|
||||
@@ -11,6 +11,9 @@ $playbar-height: 2rem;
|
||||
border-left: $panel-inner-border 1px solid;
|
||||
border-right: $panel-inner-border 1px solid;
|
||||
}
|
||||
.fy-video{
|
||||
height: 500px;
|
||||
}
|
||||
.playpause-overlay{
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
@@ -70,4 +73,26 @@ $playbar-height: 2rem;
|
||||
height: $playbar-height;
|
||||
background-color: $white;
|
||||
}
|
||||
.playpause-external{
|
||||
.button-playpause{
|
||||
width: 55px;
|
||||
height: 40px;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.button-mute{
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.playtime{
|
||||
span{
|
||||
width: 60px;
|
||||
}
|
||||
div{
|
||||
width: 10px;
|
||||
margin-left: 3px;
|
||||
margin-right: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
//For integration into other components
|
||||
export type QuickTrimData = {
|
||||
trimStartSeconds: number;
|
||||
trimEndSeconds: number;
|
||||
}
|
||||
|
||||
// INTERNALS
|
||||
export type TrimStates = {
|
||||
isScrubbingTrim: boolean;
|
||||
trimDuration: number;
|
||||
trimStart: number;
|
||||
trimEnd: number;
|
||||
maxDuration: number;
|
||||
}
|
||||
|
||||
export type PlaybarStates = {
|
||||
playbarWidth: number;
|
||||
timeCursorOffset: number;
|
||||
}
|
||||
@@ -48,6 +48,7 @@ import TintSpinner from "./TintSpinner";
|
||||
import VideoBasic from "./VideoBasic";
|
||||
import VideoFakeyou from "./VideoFakeyou";
|
||||
import VideoInput from "./VideoInput";
|
||||
// import VideoQuickTrim, {QuickTrimType} from "./VideoQuickTrim";
|
||||
import SelectionBubbles from "./SelectionBubbles";
|
||||
import Scene3D from "./Scene3D";
|
||||
|
||||
@@ -109,6 +110,7 @@ export {
|
||||
VideoBasic,
|
||||
VideoFakeyou,
|
||||
VideoInput,
|
||||
// VideoQuickTrim,
|
||||
SelectionBubbles,
|
||||
Scene3D,
|
||||
};
|
||||
+24
-20
@@ -9,16 +9,17 @@ type CNPreset =
|
||||
|
||||
const defaultPreset = {
|
||||
cnCanny: 0,
|
||||
cnDepth: 0.7,
|
||||
cnDepth: 0,
|
||||
cnLineArtAnime: 0.7,
|
||||
cnLineArtRealistic: 0.7,
|
||||
cnLineArtRealistic: 0,
|
||||
cnLipsStrength: 0,
|
||||
cnOpenPose: 0.7,
|
||||
cnPipeFace: 0.7,
|
||||
cnSparseScribble: 0.7,
|
||||
cnSoftEdge: 0.7,
|
||||
cnOpenPose: 1,
|
||||
cnPipeFace: 0,
|
||||
cnSparseScribble: 0,
|
||||
cnSoftEdge: 1,
|
||||
cnRegularSteps: 20,
|
||||
}
|
||||
|
||||
const closeupPreset = {
|
||||
cnCanny: 0,
|
||||
cnDepth: 0,
|
||||
@@ -29,20 +30,22 @@ const closeupPreset = {
|
||||
cnPipeFace: 0,
|
||||
cnSparseScribble: 0.7,
|
||||
cnSoftEdge: 0.7,
|
||||
cnRegularSteps: 30,
|
||||
cnRegularSteps: 20,
|
||||
}
|
||||
|
||||
const halfbodyPreset = {
|
||||
cnCanny: 0,
|
||||
cnDepth: 0,
|
||||
cnLineArtAnime: 0.7,
|
||||
cnLineArtRealistic: 0,
|
||||
cnLipsStrength: 0,
|
||||
cnOpenPose: 0.5,
|
||||
cnOpenPose: 0.7,
|
||||
cnPipeFace: 0,
|
||||
cnSparseScribble: 0.7,
|
||||
cnSoftEdge: 0.7,
|
||||
cnRegularSteps: 30,
|
||||
cnSparseScribble: 0,
|
||||
cnSoftEdge: 1,
|
||||
cnRegularSteps: 20,
|
||||
}
|
||||
|
||||
const fullbodyPreset = {
|
||||
cnCanny: 0,
|
||||
cnDepth: 0,
|
||||
@@ -51,21 +54,22 @@ const fullbodyPreset = {
|
||||
cnLipsStrength: 0,
|
||||
cnOpenPose: 1,
|
||||
cnPipeFace: 0,
|
||||
cnSparseScribble: 0.7,
|
||||
cnSoftEdge: 0.7,
|
||||
cnRegularSteps: 30,
|
||||
cnSparseScribble: 0,
|
||||
cnSoftEdge: 1,
|
||||
cnRegularSteps: 20,
|
||||
}
|
||||
|
||||
const landscapePreset = {
|
||||
cnCanny: 0.7,
|
||||
cnDepth: 0.7,
|
||||
cnCanny: 0,
|
||||
cnDepth: 0.4,
|
||||
cnLineArtAnime: 0.7,
|
||||
cnLineArtRealistic: 0,
|
||||
cnLipsStrength: 0,
|
||||
cnOpenPose: 0,
|
||||
cnPipeFace: 0,
|
||||
cnSparseScribble: 0.7,
|
||||
cnSoftEdge: 0.7,
|
||||
cnRegularSteps: 30,
|
||||
cnSparseScribble: 0,
|
||||
cnSoftEdge: 1,
|
||||
cnRegularSteps: 20,
|
||||
}
|
||||
|
||||
const typogPreset = {
|
||||
@@ -78,7 +82,7 @@ const typogPreset = {
|
||||
cnPipeFace: 0,
|
||||
cnSparseScribble: 0,
|
||||
cnSoftEdge: 0.7,
|
||||
cnRegularSteps: 30,
|
||||
cnRegularSteps: 20,
|
||||
}
|
||||
|
||||
export type {
|
||||
|
||||
+2
-2
@@ -8,9 +8,9 @@ const initialValues = {
|
||||
//video Settings
|
||||
width: 1024,
|
||||
height: 1024,
|
||||
maxDuration: 2,
|
||||
maxDuration: 3,
|
||||
trimStart: 0,
|
||||
trimEnd: 5,
|
||||
trimEnd: 3,
|
||||
|
||||
//Presents
|
||||
workflowConfig: "weight_99tz2nzbp5x9v55gqn5ekj1sd",
|
||||
|
||||
+9
-9
@@ -4,12 +4,11 @@ import { useParams, useHistory } from "react-router-dom";
|
||||
|
||||
import {
|
||||
Button,
|
||||
// Label,
|
||||
Panel,
|
||||
NumberSliderV2,
|
||||
TextArea,
|
||||
VideoFakeyou
|
||||
} from "components/common";
|
||||
import VideoQuickTrim, {QuickTrimData} from 'components/common/VideoQuickTrim';
|
||||
|
||||
import EnqueueVideoStyleTransfer from "@storyteller/components/src/api/video_styleTransfer";
|
||||
|
||||
@@ -25,7 +24,6 @@ import {
|
||||
import SectionAdvanceOptions from "./sectionAdvanceOptions";
|
||||
|
||||
|
||||
|
||||
export default function PageVSTApp({
|
||||
debug, t, pageState, dispatchPageState, parentPath
|
||||
}: {
|
||||
@@ -52,7 +50,6 @@ export default function PageVSTApp({
|
||||
width?: number;
|
||||
height?: number;
|
||||
maxDuration?: number;
|
||||
// trim?: number;
|
||||
} = {};
|
||||
// if (ve.videoWidth && ve.videoHeight) {
|
||||
// const aspectRatio = ve.videoWidth/ve.videoHeight
|
||||
@@ -108,10 +105,14 @@ export default function PageVSTApp({
|
||||
<Panel className="mb-4 p-4">
|
||||
<div className="row g-3 mb-4">
|
||||
<div className="col-12 col-md-6">
|
||||
<VideoFakeyou
|
||||
label={t("video.label.original")}
|
||||
<VideoQuickTrim
|
||||
// label={t("video.label.original")}
|
||||
mediaToken={vstValues.fileToken}
|
||||
ref={videoRef}
|
||||
// ref={videoRef}
|
||||
onSelect={(val:QuickTrimData)=>handleOnChange({
|
||||
trimStart: val.trimStartSeconds,
|
||||
trimEnd: val.trimEndSeconds
|
||||
})}
|
||||
onResponse={(res)=>{
|
||||
dispatchPageState({
|
||||
type: 'loadFileSuccess',
|
||||
@@ -175,14 +176,13 @@ export default function PageVSTApp({
|
||||
<NavLink to={`${parentPath}`}>
|
||||
<Button
|
||||
label={t("button.cancel")}
|
||||
// onClick={handleGenerate}
|
||||
variant="primary"
|
||||
/>
|
||||
</NavLink>
|
||||
<Button
|
||||
label="Fake Gen"
|
||||
onClick={handleFakeGen}
|
||||
variant="primary"
|
||||
variant="secondary"
|
||||
/>
|
||||
<Button
|
||||
label={t("button.enqueue")}
|
||||
|
||||
+4
-4
@@ -39,7 +39,7 @@ export default function SectionAdvanceOptions({
|
||||
onChange: (val:{[key: string]: number|string|boolean|undefined})=>void
|
||||
}){
|
||||
|
||||
const [preset, pickPreset] = useState<CNPreset>('custom')
|
||||
const [preset, pickPreset] = useState<CNPreset>('default')
|
||||
function handlePreset(newPreset: CNPreset){
|
||||
switch (newPreset){
|
||||
case 'closeup':
|
||||
@@ -234,10 +234,10 @@ export default function SectionAdvanceOptions({
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row g-3 p-3">
|
||||
{/* <div className="row g-3 p-3">
|
||||
<div className="col-md-6">
|
||||
<NumberSliderV2 {...{
|
||||
min: 1, max: 64, step: 30,
|
||||
min: 1, max: 64, step: 1,
|
||||
initialValue: vstVal.cnRegularSteps,
|
||||
label: "Regular Steps",
|
||||
thumbTip: "Regular Steps",
|
||||
@@ -247,7 +247,7 @@ export default function SectionAdvanceOptions({
|
||||
}
|
||||
}}/>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className="d-flex p-3 justify-content-end">
|
||||
<Button
|
||||
icon={faRotateLeft}
|
||||
|
||||
Reference in new issue
Block a user