shiveshnavin commited on
Commit
99ead46
·
1 Parent(s): 6ccadcf

Added animas

Browse files
.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
- import { AbsoluteFill, Img, staticFile } from 'remotion';
 
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
- let bgImage = staticFile(item?.imageAbsPaths[0]?.path || '')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  let audioPath = RenderUtils.getFileName(item?.audioFullPath)
102
 
 
103
  return (
104
  <AbsoluteFill className='relative'>
105
- <Audio volume={1.0} src={staticFile(audioPath)} />
106
- <Img className='absolute inset-0 w-full h-full object-cover' style={{ height: '100%', width: '100%' }} src={bgImage}>
107
- </Img>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  <div className='absolute inset-0'>
109
- <GeneralSubtitles position='center' group={group} word={word} />
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 Montserrat 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
  getHighlightStyle,
11
  group,
12
  word: curWord,
 
13
  fontSize = '6em',
14
  position = 'end' }) => {
15
 
16
- let { fontFamily } = Montserrat.loadFont("normal", {
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 = (opacityMult, sizeMult) => {
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(opacityMult, sizeMult)
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()}