shiveshnavin commited on
Commit
520fa9c
·
1 Parent(s): 07361d6

With Next scene in cur scene as background

Browse files
package.json CHANGED
@@ -15,8 +15,8 @@
15
  "preview": "remotion studio --log=verbose",
16
  "preinstall": "cd common-utils && npm run build",
17
  "build:utils": "cd common-utils && npm run build && cd .. && npm install ./common-utils",
18
- "render-build:igreels": "remotion render --audio-codec mp3 --image-format=jpeg --enable-multi-process-on-linux --quality=70 --concurrency 1 --gl=angle --browser-executable /usr/bin/chromium-browser IGReelComposition",
19
- "render-build": "remotion $npm_config_target --audio-codec mp3 --image-format=jpeg --enable-multi-process-on-linux --quality=70 --timeout 60000 --concurrency 4 --gl=angle --browser-executable /usr/bin/chromium-browser $npm_config_composition",
20
  "render-still": "remotion still --image-format=jpeg SemibitCompositionPoster ",
21
  "render-image": "remotion still --image-format=jpeg --concurrency 1 $npm_config_composition $npm_config_output",
22
  "render-images": "remotion render --enable-multiprocess-on-linux --sequence --image-format=jpeg $npm_config_composition $npm_config_output",
 
15
  "preview": "remotion studio --log=verbose",
16
  "preinstall": "cd common-utils && npm run build",
17
  "build:utils": "cd common-utils && npm run build && cd .. && npm install ./common-utils",
18
+ "render-build:igreels": "remotion render --audio-codec mp3 --image-format=jpeg --enable-multi-process-on-linux --quality=70 --concurrency 1 --gl=vulkan IGReelComposition",
19
+ "render-build": "remotion $npm_config_target --audio-codec mp3 --image-format=jpeg --enable-multi-process-on-linux --quality=70 --timeout 60000 --concurrency 1 --gl=angle --browser-executable /usr/bin/chromium-browser $npm_config_composition",
20
  "render-still": "remotion still --image-format=jpeg SemibitCompositionPoster ",
21
  "render-image": "remotion still --image-format=jpeg --concurrency 1 $npm_config_composition $npm_config_output",
22
  "render-images": "remotion render --enable-multiprocess-on-linux --sequence --image-format=jpeg $npm_config_composition $npm_config_output",
src/Compositions.tsx CHANGED
@@ -59,7 +59,7 @@ export const Compositions: React.FC = () => {
59
  Script.transcript
60
  .sort((t, u) => t.index - u.index)
61
  // .filter(item => (item.audioCaptionFile != undefined))
62
- // .slice(0, 2)
63
  .map((section, idx, array) => {
64
  section.index = section.index || idx;
65
  var { text, duration: durationMilis, offset, mediaAbsPaths, mediaAbsPaths, audioFullPath, title, pointers } = section
 
59
  Script.transcript
60
  .sort((t, u) => t.index - u.index)
61
  // .filter(item => (item.audioCaptionFile != undefined))
62
+ .slice(0, 2)
63
  .map((section, idx, array) => {
64
  section.index = section.index || idx;
65
  var { text, duration: durationMilis, offset, mediaAbsPaths, mediaAbsPaths, audioFullPath, title, pointers } = section
src/RenderUtils.ts CHANGED
@@ -1,4 +1,7 @@
 
 
1
  import { random, staticFile, useCurrentFrame } from "remotion";
 
2
 
3
 
4
  function levenshteinDistance(str1: string, str2: string) {
@@ -19,6 +22,38 @@ function levenshteinDistance(str1: string, str2: string) {
19
  }
20
  export class RenderUtils {
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  public static tryStaticFile(file: string) {
23
  try {
24
  return staticFile(file);
 
1
+ import { Transcript } from "common-utils";
2
+ import _ from "lodash";
3
  import { random, staticFile, useCurrentFrame } from "remotion";
4
+ import { DisplayMedia } from "./ig-reel/IGSimpleScene";
5
 
6
 
7
  function levenshteinDistance(str1: string, str2: string) {
 
22
  }
23
  export class RenderUtils {
24
 
25
+ public static calculateDisplayMedia(
26
+ item: Transcript,
27
+ durationInSeconds: number,
28
+ frame: number,
29
+ fps: number) {
30
+ let currentDisplayMedia: DisplayMedia = (item?.mediaAbsPaths as any || [])[0]
31
+ if (!_.isEmpty(item?.mediaAbsPaths)) {
32
+ let frameOffest = 0
33
+ for (let i = 0; i < item?.mediaAbsPaths.length; i++) {
34
+ const media: DisplayMedia = item.mediaAbsPaths[i] as any;
35
+ if (!media) {
36
+ return undefined
37
+ }
38
+ media.idx = i
39
+ media.startFrame = frameOffest
40
+ if (media.durationSec == undefined) {
41
+ media.durationSec = durationInSeconds / (item?.mediaAbsPaths.length)
42
+ if (i == item.mediaAbsPaths.length - 1) {
43
+ media.durationSec = durationInSeconds
44
+ }
45
+ }
46
+ media.durationFrames = media.durationSec * fps
47
+ media.endFrame = frameOffest + media.durationFrames
48
+ frameOffest = frameOffest + media.durationFrames
49
+ if (frame > media.startFrame && frame < media.endFrame) {
50
+ currentDisplayMedia = media
51
+ }
52
+ }
53
+
54
+ }
55
+ return currentDisplayMedia
56
+ }
57
  public static tryStaticFile(file: string) {
58
  try {
59
  return staticFile(file);
src/ig-reel/IGMediaRender.tsx CHANGED
@@ -9,11 +9,15 @@ import { RenderUtils } from "../RenderUtils";
9
 
10
 
11
  export function IGMediaRender(props: { curZoom: number, displayMedia: DisplayMedia, offThreadVideo?: boolean }) {
 
12
  let displayMedia: DisplayMedia = props.displayMedia
 
 
 
13
  let bgMediaPath = staticFile(displayMedia?.path || '')
14
  let curZoom = props.curZoom
15
  let transitionsByMood = Transitions.filter(t => t.mood?.indexOf("happy") > -1)
16
- let transition = RenderUtils.randomElement(transitionsByMood, `x-${displayMedia.idx * displayMedia.durationFrames}`)
17
  // transition.file = 'assets/effects/effect_sky.webm'
18
 
19
  return (
 
9
 
10
 
11
  export function IGMediaRender(props: { curZoom: number, displayMedia: DisplayMedia, offThreadVideo?: boolean }) {
12
+
13
  let displayMedia: DisplayMedia = props.displayMedia
14
+ if (displayMedia == undefined) {
15
+ return null
16
+ }
17
  let bgMediaPath = staticFile(displayMedia?.path || '')
18
  let curZoom = props.curZoom
19
  let transitionsByMood = Transitions.filter(t => t.mood?.indexOf("happy") > -1)
20
+ let transition = RenderUtils.randomElement(transitionsByMood, `x-${displayMedia?.idx * displayMedia.durationFrames}`)
21
  // transition.file = 'assets/effects/effect_sky.webm'
22
 
23
  return (
src/ig-reel/IGReelComposition.tsx CHANGED
@@ -1,5 +1,5 @@
1
  //@ts-nocheck
2
- import { AbsoluteFill, Audio, Easing, Img, interpolate, staticFile, useCurrentFrame } from 'remotion';
3
  import React from 'react'
4
  import { loadFont } from "@remotion/google-fonts/MontserratAlternates";
5
  import { Series } from "remotion";
@@ -10,6 +10,8 @@ import { VideoSplash } from '../anims/VideoSplash';
10
  import Transitions from '../../public/assets/transitions.json'
11
  import { RenderUtils } from '../RenderUtils';
12
  import IG2LineMotivationalScene from './IG2LineMotivationalScene';
 
 
13
 
14
  export const IGReelComposition: React.FC = (props: OriginalManuscript) => {
15
  const { fontFamily } = loadFont();
@@ -47,7 +49,7 @@ export const IGReelComposition: React.FC = (props: OriginalManuscript) => {
47
 
48
  <TransitionSeries>
49
  {
50
- transcripts.map((scriptItem: Transcript, i) => {
51
  let { durationInSeconds } = scriptItem
52
  let durationInFrames = meta.fps * durationInSeconds
53
  let template = scriptItem.extras?.template
@@ -65,13 +67,31 @@ export const IGReelComposition: React.FC = (props: OriginalManuscript) => {
65
  item={scriptItem} />
66
  )
67
  }
 
 
68
  return (
69
  <>
70
- <TransitionSeries.Sequence durationInFrames={durationInFrames}>
 
 
 
71
 
72
  {Component}
73
 
74
  </TransitionSeries.Sequence>
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  </>
76
  )
77
  })
 
1
  //@ts-nocheck
2
+ import { AbsoluteFill, Audio, Easing, Freeze, Img, interpolate, staticFile, useCurrentFrame } from 'remotion';
3
  import React from 'react'
4
  import { loadFont } from "@remotion/google-fonts/MontserratAlternates";
5
  import { Series } from "remotion";
 
10
  import Transitions from '../../public/assets/transitions.json'
11
  import { RenderUtils } from '../RenderUtils';
12
  import IG2LineMotivationalScene from './IG2LineMotivationalScene';
13
+ import { IGMediaRender } from './IGMediaRender';
14
+ import { Pan } from '../anims/Pan';
15
 
16
  export const IGReelComposition: React.FC = (props: OriginalManuscript) => {
17
  const { fontFamily } = loadFont();
 
49
 
50
  <TransitionSeries>
51
  {
52
+ transcripts.map((scriptItem: Transcript, i, array) => {
53
  let { durationInSeconds } = scriptItem
54
  let durationInFrames = meta.fps * durationInSeconds
55
  let template = scriptItem.extras?.template
 
67
  item={scriptItem} />
68
  )
69
  }
70
+ const easeInOutExp = Easing.inOut(Easing.bezier(0.8, 0.22, 0.96, 0.65));
71
+
72
  return (
73
  <>
74
+ <TransitionSeries.Sequence
75
+ key={`seq-${i}`}
76
+ premountFor={Math.round(meta.fps * 0.8)} // mount ~0.8s earlier; tweak as needed
77
+ durationInFrames={durationInFrames}>
78
 
79
  {Component}
80
 
81
  </TransitionSeries.Sequence>
82
+ {
83
+ (i < array.length - 1) && (
84
+ <TransitionSeries.Transition
85
+ durationInFrames={30}
86
+ transitionComponent={({ progress, ...props }) => {
87
+ return (
88
+ <Pan {...props} progress={easeInOutExp(progress)} />
89
+ )
90
+ }}
91
+ />
92
+ )
93
+ }
94
+
95
  </>
96
  )
97
  })
src/ig-reel/IGSimpleScene.tsx CHANGED
@@ -89,35 +89,6 @@ export const GenerateWordGroupRanges = function (audioCaptionFile: string, setSu
89
  })
90
  }
91
 
92
- export function calculateDisplayMedia(
93
- item: Transcript,
94
- durationInSeconds: number,
95
- frame: number,
96
- fps: number) {
97
- let currentDisplayMedia: DisplayMedia = (item?.mediaAbsPaths as any || [])[0]
98
- if (!_.isEmpty(item?.mediaAbsPaths)) {
99
- let frameOffest = 0
100
- for (let i = 0; i < item?.mediaAbsPaths.length; i++) {
101
- const media: DisplayMedia = item.mediaAbsPaths[i] as any;
102
- media.idx = i
103
- media.startFrame = frameOffest
104
- if (media.durationSec == undefined) {
105
- media.durationSec = durationInSeconds / (item?.mediaAbsPaths.length)
106
- if (i == item.mediaAbsPaths.length - 1) {
107
- media.durationSec = durationInSeconds
108
- }
109
- }
110
- media.durationFrames = media.durationSec * fps
111
- media.endFrame = frameOffest + media.durationFrames
112
- frameOffest = frameOffest + media.durationFrames
113
- if (frame > media.startFrame && frame < media.endFrame) {
114
- currentDisplayMedia = media
115
- }
116
- }
117
-
118
- }
119
- return currentDisplayMedia
120
- }
121
 
122
  export const IGSimpleScene: React.FC<any> = (props: {
123
  script: OriginalManuscript,
@@ -138,11 +109,9 @@ export const IGSimpleScene: React.FC<any> = (props: {
138
  const itemIdx = item.index;
139
  const isLastScene = script.transcript[script.transcript?.length - 1]?.index == itemIdx
140
  const nextScene = script.transcript.find(i => i.index == itemIdx + 1);
141
- let nextSceneMedia0 = nextScene?.mediaAbsPaths as any as DisplayMedia;
142
-
143
-
144
  if (nextSceneMedia0) {
145
- nextSceneMedia0 = calculateDisplayMedia(nextScene as Transcript, durationInSeconds, frame, fps)
146
  }
147
  useEffect(() => {
148
  if (audioCaptionFile)
@@ -167,7 +136,7 @@ export const IGSimpleScene: React.FC<any> = (props: {
167
  let word = RenderUtils.findCurrentWord(curSecond, subtitles!!)
168
  let group: Group = RenderUtils.findCurrentGroupByTime(curSecond, groups)
169
 
170
- let currentDisplayMedia: DisplayMedia = calculateDisplayMedia(item, durationInSeconds, frame, fps)
171
 
172
 
173
 
@@ -185,11 +154,12 @@ export const IGSimpleScene: React.FC<any> = (props: {
185
  duration = item.durationInSeconds * fps
186
  }
187
  chunk.push((
188
- <TransitionSeries.Sequence durationInFrames={duration}>
189
  <IGMediaRender offThreadVideo={true} curZoom={curZoom} displayMedia={displayMedia} />
190
  </TransitionSeries.Sequence>
191
  ))
192
- if (i < item?.mediaAbsPaths.length - 1 || true) {
 
193
 
194
  let animsObj = {
195
  // CircularWipe, Slide,LinearWipe, // Not work
@@ -210,6 +180,7 @@ export const IGSimpleScene: React.FC<any> = (props: {
210
  //@ts-ignore
211
  Anim = animsObj[animFromTranscript]
212
  }
 
213
 
214
  if (!isLastScene && (item.transition_type?.includes('geometrial') || animFromTranscript || item.transition_type == undefined)) {
215
  chunk.push((
@@ -231,10 +202,11 @@ export const IGSimpleScene: React.FC<any> = (props: {
231
  // console.log('currentDisplayMedia?.endFrame', frame, currentDisplayMedia?.endFrame)
232
  return (
233
  <AbsoluteFill style={{
 
234
  width: '100%',
235
  height: '100%',
236
  }} className='relative'>
237
- <Audio volume={1} loop src={staticFile(speechPath as string)} />
238
  {
239
  nextSceneMedia0 && (
240
  <TransitionSeries.Sequence durationInFrames={itemDurationInFrames}>
@@ -253,7 +225,7 @@ export const IGSimpleScene: React.FC<any> = (props: {
253
 
254
  {
255
  (item.transition_type?.includes("graphical")) && !isLastScene &&
256
- currentDisplayMedia?.idx > -1 && (
257
  (item?.mediaAbsPaths as any)?.map((displayMedia: DisplayMedia) => {
258
  let transitionsByMood = Transitions.filter(t => (t?.mood?.indexOf("happy") || -1) > -1)
259
  let transition = RenderUtils.randomElement(transitionsByMood, `x-${displayMedia.idx * displayMedia.durationFrames}`)
 
89
  })
90
  }
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  export const IGSimpleScene: React.FC<any> = (props: {
94
  script: OriginalManuscript,
 
109
  const itemIdx = item.index;
110
  const isLastScene = script.transcript[script.transcript?.length - 1]?.index == itemIdx
111
  const nextScene = script.transcript.find(i => i.index == itemIdx + 1);
112
+ let nextSceneMedia0 = undefined;//nextScene?.mediaAbsPaths as any as DisplayMedia | undefined;
 
 
113
  if (nextSceneMedia0) {
114
+ nextSceneMedia0 = RenderUtils.calculateDisplayMedia(nextScene as Transcript, durationInSeconds, frame, fps)
115
  }
116
  useEffect(() => {
117
  if (audioCaptionFile)
 
136
  let word = RenderUtils.findCurrentWord(curSecond, subtitles!!)
137
  let group: Group = RenderUtils.findCurrentGroupByTime(curSecond, groups)
138
 
139
+ let currentDisplayMedia: DisplayMedia | undefined = RenderUtils.calculateDisplayMedia(item, durationInSeconds, frame, fps)
140
 
141
 
142
 
 
154
  duration = item.durationInSeconds * fps
155
  }
156
  chunk.push((
157
+ <TransitionSeries.Sequence key={`x-${i}`} durationInFrames={duration}>
158
  <IGMediaRender offThreadVideo={true} curZoom={curZoom} displayMedia={displayMedia} />
159
  </TransitionSeries.Sequence>
160
  ))
161
+ // Only show in schene media transitions if there are more than one media
162
+ if (i < item?.mediaAbsPaths.length - 1) {
163
 
164
  let animsObj = {
165
  // CircularWipe, Slide,LinearWipe, // Not work
 
180
  //@ts-ignore
181
  Anim = animsObj[animFromTranscript]
182
  }
183
+ Anim = Pan
184
 
185
  if (!isLastScene && (item.transition_type?.includes('geometrial') || animFromTranscript || item.transition_type == undefined)) {
186
  chunk.push((
 
202
  // console.log('currentDisplayMedia?.endFrame', frame, currentDisplayMedia?.endFrame)
203
  return (
204
  <AbsoluteFill style={{
205
+ backgroundColor: RenderUtils.randomElement(['red', 'blue', 'green', 'orange', 'yellow', 'cyan'], `x-${itemIdx}`),
206
  width: '100%',
207
  height: '100%',
208
  }} className='relative'>
209
+ <Audio volume={1} src={staticFile(speechPath as string)} />
210
  {
211
  nextSceneMedia0 && (
212
  <TransitionSeries.Sequence durationInFrames={itemDurationInFrames}>
 
225
 
226
  {
227
  (item.transition_type?.includes("graphical")) && !isLastScene &&
228
+ (currentDisplayMedia?.idx || -1) > -1 && (
229
  (item?.mediaAbsPaths as any)?.map((displayMedia: DisplayMedia) => {
230
  let transitionsByMood = Transitions.filter(t => (t?.mood?.indexOf("happy") || -1) > -1)
231
  let transition = RenderUtils.randomElement(transitionsByMood, `x-${displayMedia.idx * displayMedia.durationFrames}`)