Spaces:
Runtime error
Runtime error
| import { AbsoluteFill, Audio, spring, staticFile, useCurrentFrame, useVideoConfig } from 'remotion'; | |
| import { MediaBackground } from './MediaBackground'; | |
| import React from 'react' | |
| import { GlowingStroke } from '../anims/GlowingStrike'; | |
| import { SequentialSceneData } from './SequentialScene'; | |
| import { loadFont } from "@remotion/google-fonts/MontserratAlternates"; | |
| import { Animated, Move } from 'remotion-animated'; | |
| import ForegroundGrid from './ForegroundGrid'; | |
| import { loadFont } from "@remotion/google-fonts/Raleway"; | |
| import { Transcript } from 'common-utils'; | |
| function adjustFontSize(text: string, fullFont: number, minFontSizeDef): number { | |
| const wordCount = text.split(' ').length; | |
| const charCount = text.length | |
| minFontSizeDef = minFontSizeDef || 60 | |
| let minFontSize; | |
| if (charCount < 750) { | |
| minFontSize = minFontSizeDef; | |
| } | |
| else if (charCount < 1000) { | |
| minFontSize = minFontSizeDef - 20 | |
| } | |
| else { | |
| minFontSize = 20; | |
| } | |
| return Math.max(fullFont - (wordCount), minFontSize) | |
| } | |
| export const SectionTextWithBG: React.FC<SequentialSceneData> = (props: Transcript) => { | |
| var { text, subtitles, durationInSecs, textColor = '#fff', duration, direction = 'left', bgImagePaths, audioPath, commulativeDurationStartSec, | |
| title, pointers, emphasisOnImage, durationInSecs, rootProps } = props | |
| const videoConfig = useVideoConfig(); | |
| const { fps, width, height } = useVideoConfig(); | |
| const { fontFamily } = loadFont("normal", { | |
| ignoreTooManyRequestsWarning: true | |
| }); | |
| const frame = useCurrentFrame(); | |
| let textBgColor = textColor; | |
| let textFontColor = "#fff"; | |
| const totalChars = text.length | |
| var aggFrames = 0 | |
| text = text.trim() | |
| if (text.startsWith(".")) { | |
| text = text.replace(".", "") | |
| } | |
| const sentenceMap = (subtitles || text.split('.').map((t) => { | |
| let charCount = text.length | |
| let expectedDurationSec = durationInSecs * (charCount / totalChars) | |
| return { | |
| text: t, | |
| expectedDurationSec: expectedDurationSec | |
| } | |
| }) | |
| ).map(({ text, expectedDurationSec }) => { | |
| let expectedDurationFrames = expectedDurationSec * fps | |
| aggFrames = aggFrames + expectedDurationFrames | |
| expectedDurationFrames = Math.floor(expectedDurationFrames) | |
| return { | |
| text: text.trim(), | |
| expectedDurationSec, | |
| expectedDurationFrames, | |
| startFrame: Math.max(0, aggFrames - expectedDurationFrames), | |
| endFrame: Math.max(0, aggFrames + Math.max(0, 1 * Math.max(1, (frame / (60 * fps)))) * fps), | |
| } | |
| }); | |
| let wps = rootProps?.meta?.speaker?.wps | |
| const [heightOfGlow, setheightOfGlow] = React.useState(0) | |
| const [widthOfGlow, setwidthOfGlow] = React.useState(0) | |
| const ref = React.useRef(null) | |
| React.useEffect(() => { | |
| setheightOfGlow(ref.current.clientHeight) | |
| setwidthOfGlow(ref.current.clientWidth) | |
| }) | |
| var curSentence = { text: undefined } | |
| for (let index = 0; index < sentenceMap.length; index++) { | |
| const { startFrame, endFrame } = sentenceMap[index]; | |
| if (startFrame <= frame && endFrame >= frame) { | |
| curSentence = sentenceMap[index] | |
| break | |
| } | |
| curSentence = { text: undefined } | |
| } | |
| if (pointers?.length > 6) { | |
| pointers = pointers?.slice(0, 6) | |
| } | |
| let opacity = (title?.length > 0 && pointers?.length > 0) ? 0.7 : 0 | |
| return ( | |
| <MediaBackground | |
| emphasisOnImage={emphasisOnImage || false} | |
| direction={direction} | |
| duration={duration} | |
| bgImagePaths={bgImagePaths} | |
| opacity={opacity} | |
| > | |
| <AbsoluteFill> | |
| <Audio volume={1.0} src={staticFile(audioPath)} /> | |
| </AbsoluteFill> | |
| { | |
| (title?.length > 0 && pointers?.length > 0) && ( | |
| <ForegroundGrid {...props} curSentence={curSentence} direction={direction == 'left' ? 'right' : 'left'} /> | |
| ) | |
| } | |
| <h1 | |
| style={{ | |
| paddingBottom: 40, | |
| paddingTop: 80, | |
| borderRadius: 10, | |
| overflow: 'hidden', | |
| // background: "#0000003A", | |
| fontFamily: fontFamily, | |
| fontWeight: 'bold', | |
| fontSize: adjustFontSize(text, emphasisOnImage ? 40 : 100, emphasisOnImage ? 40 : 60), | |
| textAlign: 'center', | |
| position: 'absolute', | |
| }} | |
| > | |
| <GlowingStroke | |
| style={{ | |
| marginBottom: 50 | |
| }} | |
| width={widthOfGlow} | |
| height={heightOfGlow} | |
| radius={30} | |
| color1={textColor} | |
| color2={textColor} | |
| offset={55} | |
| /> | |
| <div | |
| ref={ref} | |
| style={{ | |
| padding: 20, | |
| // backgroundColor: emphasisOnImage ? '#000000AA' : '#0000006A', borderRadius: 10, overflow: 'hidden', | |
| }} | |
| > | |
| {curSentence.text?.length > 0 && <span | |
| key={curSentence.text} | |
| className='text-3xl tracking-wide text-black-stroke text-red-fill' | |
| style={{ | |
| // backgroundColor: textBgColor, borderRadius: 10, overflow: 'hidden', | |
| paddingLeft: 10, | |
| paddingRight: 10, | |
| padding: 5, | |
| color: textFontColor, | |
| marginLeft: 10, | |
| marginRight: 10, | |
| transform: `scale(${spring({ | |
| fps: videoConfig.fps, | |
| frame: frame, | |
| config: { | |
| damping: 100, | |
| stiffness: 200, | |
| mass: 0.5, | |
| }, | |
| })})`, | |
| display: 'inline-block', | |
| }} | |
| > | |
| {curSentence.text} | |
| </span> | |
| } | |
| </div> | |
| </h1> | |
| </MediaBackground > | |
| ); | |
| }; | |