Spaces:
Running
Running
Commit ·
99ead46
1
Parent(s): 6ccadcf
Added animas
Browse files- .gitignore +2 -0
- package.json +1 -1
- scripts/cut_center.sh +37 -0
- scripts/transparent.sh +3 -0
- src/RenderUtils.ts +7 -0
- src/ig-reel/IGReelComposition.tsx +9 -3
- src/ig-reel/IGSimpleScene.tsx +53 -6
- src/ig-reel/styles.module.css +3 -0
- src/subtitles/excited_Subtitles.tsx +57 -0
- src/subtitles/general_Subtitles.tsx +11 -10
.gitignore
CHANGED
|
@@ -1,7 +1,9 @@
|
|
| 1 |
node_modules
|
| 2 |
dist
|
| 3 |
.DS_Store
|
|
|
|
| 4 |
.env
|
|
|
|
| 5 |
@@export_177ba1326b.zip
|
| 6 |
# Ignore the output video from Git but not videos you import into src/.
|
| 7 |
out/**
|
|
|
|
| 1 |
node_modules
|
| 2 |
dist
|
| 3 |
.DS_Store
|
| 4 |
+
*.mp4
|
| 5 |
.env
|
| 6 |
+
*.exe
|
| 7 |
@@export_177ba1326b.zip
|
| 8 |
# Ignore the output video from Git but not videos you import into src/.
|
| 9 |
out/**
|
package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
| 11 |
"extract32": "set MODIFY_FILES=1 && node app.js",
|
| 12 |
"extract": "MODIFY_FILES=1 && node app.js",
|
| 13 |
"preview": "remotion studio",
|
| 14 |
-
"render-build:igreels": "remotion render --image-format=jpeg --quality=70 --gl=angle IGReelComposition",
|
| 15 |
"render-build": "remotion render --image-format=jpeg --quality=70 --gl=angle ",
|
| 16 |
"render-still": "remotion still --image-format=jpeg SemibitCompositionPoster ",
|
| 17 |
"upgrade": "remotion upgrade",
|
|
|
|
| 11 |
"extract32": "set MODIFY_FILES=1 && node app.js",
|
| 12 |
"extract": "MODIFY_FILES=1 && node app.js",
|
| 13 |
"preview": "remotion studio",
|
| 14 |
+
"render-build:igreels": "remotion render --image-format=jpeg --enable-multi-process-on-linux --quality=70 --gl=angle IGReelComposition",
|
| 15 |
"render-build": "remotion render --image-format=jpeg --quality=70 --gl=angle ",
|
| 16 |
"render-still": "remotion still --image-format=jpeg SemibitCompositionPoster ",
|
| 17 |
"upgrade": "remotion upgrade",
|
scripts/cut_center.sh
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
|
| 3 |
+
# Input video file
|
| 4 |
+
input_file="input_video.mp4"
|
| 5 |
+
|
| 6 |
+
# Output video file
|
| 7 |
+
output_file="output_video.mp4"
|
| 8 |
+
|
| 9 |
+
# Target aspect ratio (e.g., 9:16)
|
| 10 |
+
target_aspect_ratio="9:16"
|
| 11 |
+
|
| 12 |
+
# Get the dimensions of the input video
|
| 13 |
+
video_info=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 "$input_file")
|
| 14 |
+
width=$(echo "$video_info" | cut -d ',' -f 1)
|
| 15 |
+
height=$(echo "$video_info" | cut -d ',' -f 2)
|
| 16 |
+
|
| 17 |
+
# Calculate the target width based on the target aspect ratio and height
|
| 18 |
+
IFS=':' read -ra target_ratio <<< "$target_aspect_ratio"
|
| 19 |
+
target_height=$((height))
|
| 20 |
+
target_width=$((height * target_ratio[0] / target_ratio[1]))
|
| 21 |
+
|
| 22 |
+
# Make sure the dimensions are even
|
| 23 |
+
if [ $((target_width % 2)) -ne 0 ]; then
|
| 24 |
+
target_width=$((target_width + 1))
|
| 25 |
+
fi
|
| 26 |
+
if [ $((target_height % 2)) -ne 0 ]; then
|
| 27 |
+
target_height=$((target_height + 1))
|
| 28 |
+
fi
|
| 29 |
+
|
| 30 |
+
# Calculate the cropping parameters to center the video
|
| 31 |
+
crop_x=$(( (width - target_width) / 2 ))
|
| 32 |
+
crop_y=0 # Center vertically
|
| 33 |
+
|
| 34 |
+
# Use FFmpeg to crop and resize the video
|
| 35 |
+
./ffmpeg -i "$input_file" -vf "crop=$target_width:$target_height:$crop_x:$crop_y" -c:a copy -s "${target_width}x${target_height}" -y "$output_file"
|
| 36 |
+
|
| 37 |
+
echo "Video cropped, resized, and saved as $output_file"
|
scripts/transparent.sh
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
ffmpeg -i ig-reels-next.mp4 -vf chromakey=black overlay.webm
|
| 2 |
+
ffmpeg -i ig-reels-next.mp4 -c:v libvpx -vf "colorkey=0x000000:0.1:0.1,format=yuva420p,scale=1280:720" -auto-alt-ref 0 -y overlay.webm
|
| 3 |
+
# ffmpeg -loop 1 -i green.jpg -c:v libx264 -t 15 -pix_fmt yuv420p -vf scale=1080:1920 green.mp4
|
src/RenderUtils.ts
CHANGED
|
@@ -18,6 +18,13 @@ function levenshteinDistance(str1: string, str2: string) {
|
|
| 18 |
}
|
| 19 |
export class RenderUtils {
|
| 20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
public static splitArrayIntoChunks(arr, chunkSize) {
|
| 22 |
const chunkedArr = [];
|
| 23 |
for (let i = 0; i < arr.length; i += chunkSize) {
|
|
|
|
| 18 |
}
|
| 19 |
export class RenderUtils {
|
| 20 |
|
| 21 |
+
public static hashCode(s) {
|
| 22 |
+
return s.split("").reduce(function (a, b) {
|
| 23 |
+
a = ((a << 5) - a) + b.charCodeAt(0);
|
| 24 |
+
return a & a;
|
| 25 |
+
}, 0);
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
public static splitArrayIntoChunks(arr, chunkSize) {
|
| 29 |
const chunkedArr = [];
|
| 30 |
for (let i = 0; i < arr.length; i += chunkSize) {
|
src/ig-reel/IGReelComposition.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
| 1 |
-
|
|
|
|
| 2 |
import React from 'react'
|
| 3 |
import { loadFont } from "@remotion/google-fonts/MontserratAlternates";
|
| 4 |
import { Series } from "remotion";
|
|
@@ -7,14 +8,19 @@ import { IGScene } from './IGSimpleScene';
|
|
| 7 |
|
| 8 |
export const IGReelComposition: React.FC = (props) => {
|
| 9 |
const { fontFamily } = loadFont();
|
| 10 |
-
let { contents, meta } = props
|
| 11 |
|
| 12 |
|
|
|
|
| 13 |
return (
|
| 14 |
<AbsoluteFill style={{
|
| 15 |
background: 'black'
|
| 16 |
}}>
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
<Series>
|
| 19 |
{
|
| 20 |
contents.map((scriptItem, i) => {
|
|
|
|
| 1 |
+
//@ts-nocheck
|
| 2 |
+
import { AbsoluteFill, Audio, Img, staticFile } from 'remotion';
|
| 3 |
import React from 'react'
|
| 4 |
import { loadFont } from "@remotion/google-fonts/MontserratAlternates";
|
| 5 |
import { Series } from "remotion";
|
|
|
|
| 8 |
|
| 9 |
export const IGReelComposition: React.FC = (props) => {
|
| 10 |
const { fontFamily } = loadFont();
|
| 11 |
+
let { contents, meta, bgMusic } = props
|
| 12 |
|
| 13 |
|
| 14 |
+
let bgMusicPath = staticFile(bgMusic || '')
|
| 15 |
return (
|
| 16 |
<AbsoluteFill style={{
|
| 17 |
background: 'black'
|
| 18 |
}}>
|
| 19 |
+
{
|
| 20 |
+
bgMusic && (
|
| 21 |
+
<Audio loop fade volume={0.05} src={bgMusicPath} />
|
| 22 |
+
)
|
| 23 |
+
}
|
| 24 |
<Series>
|
| 25 |
{
|
| 26 |
contents.map((scriptItem, i) => {
|
src/ig-reel/IGSimpleScene.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
//@ts-nocheck
|
| 2 |
-
import { AbsoluteFill, Img, staticFile, Audio, useCurrentFrame } from 'remotion';
|
| 3 |
import React, { useEffect, useState } from 'react'
|
| 4 |
import { loadFont } from "@remotion/google-fonts/MontserratAlternates";
|
| 5 |
import { Series } from "remotion";
|
|
@@ -7,6 +7,9 @@ import { RenderUtils } from '../RenderUtils';
|
|
| 7 |
import { Transcript } from '../OriginalManuscriptModel'
|
| 8 |
import axios from 'axios';
|
| 9 |
import GeneralSubtitles from '../subtitles/general_Subtitles';
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
export const IGScene: React.FC<any> = (props: {
|
| 12 |
script: any,
|
|
@@ -97,16 +100,60 @@ export const IGScene: React.FC<any> = (props: {
|
|
| 97 |
let curSecond: Number = frame / fps
|
| 98 |
let word = findCurrentWord(curSecond, subtitles)
|
| 99 |
let group = findCurrentGroupByTime(curSecond, groups)
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
let audioPath = RenderUtils.getFileName(item?.audioFullPath)
|
| 102 |
|
|
|
|
| 103 |
return (
|
| 104 |
<AbsoluteFill className='relative'>
|
| 105 |
-
<Audio volume={1
|
| 106 |
-
|
| 107 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
<div className='absolute inset-0'>
|
| 109 |
-
<
|
| 110 |
</div>
|
| 111 |
</AbsoluteFill >
|
| 112 |
);
|
|
|
|
| 1 |
//@ts-nocheck
|
| 2 |
+
import { AbsoluteFill, Img, staticFile, Audio, useCurrentFrame, Video } from 'remotion';
|
| 3 |
import React, { useEffect, useState } from 'react'
|
| 4 |
import { loadFont } from "@remotion/google-fonts/MontserratAlternates";
|
| 5 |
import { Series } from "remotion";
|
|
|
|
| 7 |
import { Transcript } from '../OriginalManuscriptModel'
|
| 8 |
import axios from 'axios';
|
| 9 |
import GeneralSubtitles from '../subtitles/general_Subtitles';
|
| 10 |
+
import ExcitedSubtitles from '../subtitles/excited_Subtitles';
|
| 11 |
+
import _ from 'lodash';
|
| 12 |
+
import './styles.module.css'
|
| 13 |
|
| 14 |
export const IGScene: React.FC<any> = (props: {
|
| 15 |
script: any,
|
|
|
|
| 100 |
let curSecond: Number = frame / fps
|
| 101 |
let word = findCurrentWord(curSecond, subtitles)
|
| 102 |
let group = findCurrentGroupByTime(curSecond, groups)
|
| 103 |
+
|
| 104 |
+
let displayMedia = (item?.imageAbsPaths || [])[0]
|
| 105 |
+
|
| 106 |
+
if (!_.isEmpty(item?.imageAbsPaths)) {
|
| 107 |
+
let frameOffest = 0
|
| 108 |
+
for (let i = 0; i < item?.imageAbsPaths.length; i++) {
|
| 109 |
+
const media = item.imageAbsPaths[i];
|
| 110 |
+
media.startFrame = frameOffest
|
| 111 |
+
if (media.durationSec == undefined) {
|
| 112 |
+
media.durationSec = durationInSeconds
|
| 113 |
+
}
|
| 114 |
+
media.durationFrames = media.durationSec * fps
|
| 115 |
+
media.endFrame = frameOffest + media.durationFrames
|
| 116 |
+
frameOffest = frameOffest + media.durationFrames
|
| 117 |
+
if (frame > media.startFrame && frame < media.endFrame) {
|
| 118 |
+
displayMedia = media
|
| 119 |
+
}
|
| 120 |
+
}
|
| 121 |
+
}
|
| 122 |
+
|
| 123 |
+
let bgMediaPath = staticFile(displayMedia?.path || '')
|
| 124 |
let audioPath = RenderUtils.getFileName(item?.audioFullPath)
|
| 125 |
|
| 126 |
+
|
| 127 |
return (
|
| 128 |
<AbsoluteFill className='relative'>
|
| 129 |
+
<Audio volume={1} src={staticFile(audioPath)} />
|
| 130 |
+
{
|
| 131 |
+
displayMedia && (
|
| 132 |
+
displayMedia.type == 'video' ? (
|
| 133 |
+
<div style={{
|
| 134 |
+
position: 'relative',
|
| 135 |
+
height: '100%', width: '100%'
|
| 136 |
+
|
| 137 |
+
}}>
|
| 138 |
+
<Video playbackRate={0.5} volume={0} style={{
|
| 139 |
+
background: '#fff',
|
| 140 |
+
position: 'absolute',
|
| 141 |
+
height: '100%', width: '100%'
|
| 142 |
+
}} src={bgMediaPath} />
|
| 143 |
+
|
| 144 |
+
<Video className="transparent" playbackRate={0.5} volume={0} style={{
|
| 145 |
+
position: 'absolute',
|
| 146 |
+
background: `linear-gradient(45deg, rgba(0, 0, 0, .1) 25%, transparent 0), linear-gradient(135deg, rgba(0, 0, 0, .1) 25%, transparent 0), linear-gradient(45deg, transparent 75%, rgba(0, 0, 0, .1) 0), linear-gradient(135deg, transparent 75%, rgba(0, 0, 0, .1) 0), #fff;`,
|
| 147 |
+
height: '100%', width: '100%',
|
| 148 |
+
}} src={staticFile('assets/overlay.webm')} />
|
| 149 |
+
</div>
|
| 150 |
+
) : (
|
| 151 |
+
<Img className='absolute inset-0 w-full h-full object-cover' style={{ height: '100%', width: '100%' }} src={bgMediaPath} />
|
| 152 |
+
)
|
| 153 |
+
)
|
| 154 |
+
}
|
| 155 |
<div className='absolute inset-0'>
|
| 156 |
+
<ExcitedSubtitles position='center' group={group} word={word} />
|
| 157 |
</div>
|
| 158 |
</AbsoluteFill >
|
| 159 |
);
|
src/ig-reel/styles.module.css
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.transparent {
|
| 2 |
+
background: linear-gradient(45deg, rgba(0, 0, 0, .1) 25%, transparent 0), linear-gradient(135deg, rgba(0, 0, 0, .1) 25%, transparent 0), linear-gradient(45deg, transparent 75%, rgba(0, 0, 0, .1) 0), linear-gradient(135deg, transparent 75%, rgba(0, 0, 0, .1) 0), #fff;
|
| 3 |
+
}
|
src/subtitles/excited_Subtitles.tsx
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
//@ts-nocheck
|
| 2 |
+
import React, { useEffect, useState } from 'react'
|
| 3 |
+
import * as SubtitleFont from "@remotion/google-fonts/Montserrat";
|
| 4 |
+
import { AbsoluteFill, Img, interpolate, interpolateColors, Series, spring, useCurrentFrame, useVideoConfig, random } from "remotion";
|
| 5 |
+
import { Group, Word } from '../ig-reel/Types';
|
| 6 |
+
import _, { words } from 'lodash'
|
| 7 |
+
import GeneralSubtitles from './general_Subtitles';
|
| 8 |
+
import { RenderUtils } from '../RenderUtils';
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
const ExcitedSubtitles: React.FC<{ group: Group, word: Word, position: 'start' | 'center' | 'end' }> = ({
|
| 12 |
+
word, group }) => {
|
| 13 |
+
|
| 14 |
+
let { fontFamily } = SubtitleFont.loadFont("normal", {
|
| 15 |
+
weights: ['900']
|
| 16 |
+
})
|
| 17 |
+
|
| 18 |
+
let frame = useCurrentFrame()
|
| 19 |
+
let rotation = 0
|
| 20 |
+
if (group && group.words) {
|
| 21 |
+
let sent = group.words.map(w => w.word).join(" ")
|
| 22 |
+
const randomNumber = RenderUtils.hashCode(sent)
|
| 23 |
+
let last2 = randomNumber % 100
|
| 24 |
+
if (last2 < 50) {
|
| 25 |
+
rotation = (-5)
|
| 26 |
+
} else {
|
| 27 |
+
rotation = (5)
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
let getHighlightStyle = (frame, wdStartFrame, wdEndFrame) => {
|
| 32 |
+
const color = interpolateColors(frame - wdStartFrame, [0, 1], ["#fff", "#00EF00"]);
|
| 33 |
+
|
| 34 |
+
return {
|
| 35 |
+
color: color,
|
| 36 |
+
opacity: 1,
|
| 37 |
+
borderStyle: 'solid',
|
| 38 |
+
};
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
return (
|
| 42 |
+
<div style={{
|
| 43 |
+
width: '100%', height: '100%',
|
| 44 |
+
|
| 45 |
+
}}>
|
| 46 |
+
<GeneralSubtitles style={{
|
| 47 |
+
transform: `rotate(${rotation}deg)`,
|
| 48 |
+
justifyContent: 'center',
|
| 49 |
+
alignContent: 'center'
|
| 50 |
+
}}
|
| 51 |
+
wordFont={fontFamily}
|
| 52 |
+
getHighlightStyle={getHighlightStyle}
|
| 53 |
+
word={word} group={group} position="end" />
|
| 54 |
+
</div>
|
| 55 |
+
);
|
| 56 |
+
};
|
| 57 |
+
export default ExcitedSubtitles
|
src/subtitles/general_Subtitles.tsx
CHANGED
|
@@ -1,19 +1,21 @@
|
|
| 1 |
//@ts-nocheck
|
| 2 |
import React, { useEffect, useState } from 'react'
|
| 3 |
-
import * as
|
| 4 |
import { AbsoluteFill, Img, interpolate, interpolateColors, Series, spring, useCurrentFrame, useVideoConfig } from "remotion";
|
| 5 |
import { Group, Word } from '../ig-reel/Types';
|
| 6 |
import _ from 'lodash'
|
| 7 |
|
| 8 |
|
| 9 |
const GeneralSubtitles: React.FC<{ group: Group, word: Word, position: 'start' | 'center' | 'end' }> = ({
|
|
|
|
| 10 |
getHighlightStyle,
|
| 11 |
group,
|
| 12 |
word: curWord,
|
|
|
|
| 13 |
fontSize = '6em',
|
| 14 |
position = 'end' }) => {
|
| 15 |
|
| 16 |
-
let { fontFamily } =
|
| 17 |
weights: ['900']
|
| 18 |
})
|
| 19 |
|
|
@@ -46,7 +48,7 @@ const GeneralSubtitles: React.FC<{ group: Group, word: Word, position: 'start' |
|
|
| 46 |
padding: '0.2rem 1.5rem',
|
| 47 |
};
|
| 48 |
if (!getHighlightStyle) {
|
| 49 |
-
getHighlightStyle = (
|
| 50 |
return {
|
| 51 |
opacity: opacityMult,
|
| 52 |
background: color,
|
|
@@ -59,25 +61,24 @@ const GeneralSubtitles: React.FC<{ group: Group, word: Word, position: 'start' |
|
|
| 59 |
};
|
| 60 |
}
|
| 61 |
}
|
| 62 |
-
let highlightStyle = getHighlightStyle(
|
| 63 |
|
| 64 |
|
| 65 |
return (
|
| 66 |
<div
|
| 67 |
className="min-h-screen"
|
| 68 |
-
style={{
|
| 69 |
display: 'flex',
|
| 70 |
flexDirection: 'column',
|
| 71 |
-
background: '#000',
|
| 72 |
height: '100%',
|
| 73 |
fontSize: fontSize || '10em',
|
| 74 |
justifyContent: position,
|
| 75 |
-
}}
|
| 76 |
>
|
| 77 |
|
| 78 |
<div
|
| 79 |
className="p-6 rounded-lg"
|
| 80 |
-
style={{
|
| 81 |
paddingRight: '10%',
|
| 82 |
paddingLeft: '10%',
|
| 83 |
paddingBottom: '20%',
|
|
@@ -87,7 +88,7 @@ const GeneralSubtitles: React.FC<{ group: Group, word: Word, position: 'start' |
|
|
| 87 |
display: 'flex',
|
| 88 |
flexWrap: 'wrap', // Add flex-wrap to allow multiple lines
|
| 89 |
maxWidth: '100%', // Add max-width to restrict width to screen size
|
| 90 |
-
}}
|
| 91 |
>
|
| 92 |
{/*
|
| 93 |
<span style={baseStyle}>
|
|
@@ -107,7 +108,7 @@ const GeneralSubtitles: React.FC<{ group: Group, word: Word, position: 'start' |
|
|
| 107 |
key={index}
|
| 108 |
style={{
|
| 109 |
...wordStyle,
|
| 110 |
-
fontFamily
|
| 111 |
}}
|
| 112 |
>
|
| 113 |
{word?.word?.toUpperCase()}
|
|
|
|
| 1 |
//@ts-nocheck
|
| 2 |
import React, { useEffect, useState } from 'react'
|
| 3 |
+
import * as SubtitleFont from "@remotion/google-fonts/Lato";
|
| 4 |
import { AbsoluteFill, Img, interpolate, interpolateColors, Series, spring, useCurrentFrame, useVideoConfig } from "remotion";
|
| 5 |
import { Group, Word } from '../ig-reel/Types';
|
| 6 |
import _ from 'lodash'
|
| 7 |
|
| 8 |
|
| 9 |
const GeneralSubtitles: React.FC<{ group: Group, word: Word, position: 'start' | 'center' | 'end' }> = ({
|
| 10 |
+
style,
|
| 11 |
getHighlightStyle,
|
| 12 |
group,
|
| 13 |
word: curWord,
|
| 14 |
+
wordFont,
|
| 15 |
fontSize = '6em',
|
| 16 |
position = 'end' }) => {
|
| 17 |
|
| 18 |
+
let { fontFamily } = SubtitleFont.loadFont("normal", {
|
| 19 |
weights: ['900']
|
| 20 |
})
|
| 21 |
|
|
|
|
| 48 |
padding: '0.2rem 1.5rem',
|
| 49 |
};
|
| 50 |
if (!getHighlightStyle) {
|
| 51 |
+
getHighlightStyle = (frame, wdStartFrame, wdEndFrame) => {
|
| 52 |
return {
|
| 53 |
opacity: opacityMult,
|
| 54 |
background: color,
|
|
|
|
| 61 |
};
|
| 62 |
}
|
| 63 |
}
|
| 64 |
+
let highlightStyle = getHighlightStyle(frame, wdStartFrame, wdEndFrame)
|
| 65 |
|
| 66 |
|
| 67 |
return (
|
| 68 |
<div
|
| 69 |
className="min-h-screen"
|
| 70 |
+
style={Object.assign({
|
| 71 |
display: 'flex',
|
| 72 |
flexDirection: 'column',
|
|
|
|
| 73 |
height: '100%',
|
| 74 |
fontSize: fontSize || '10em',
|
| 75 |
justifyContent: position,
|
| 76 |
+
}, {})}
|
| 77 |
>
|
| 78 |
|
| 79 |
<div
|
| 80 |
className="p-6 rounded-lg"
|
| 81 |
+
style={Object.assign({
|
| 82 |
paddingRight: '10%',
|
| 83 |
paddingLeft: '10%',
|
| 84 |
paddingBottom: '20%',
|
|
|
|
| 88 |
display: 'flex',
|
| 89 |
flexWrap: 'wrap', // Add flex-wrap to allow multiple lines
|
| 90 |
maxWidth: '100%', // Add max-width to restrict width to screen size
|
| 91 |
+
}, style)}
|
| 92 |
>
|
| 93 |
{/*
|
| 94 |
<span style={baseStyle}>
|
|
|
|
| 108 |
key={index}
|
| 109 |
style={{
|
| 110 |
...wordStyle,
|
| 111 |
+
fontFamily: wordFont || fontFamily
|
| 112 |
}}
|
| 113 |
>
|
| 114 |
{word?.word?.toUpperCase()}
|