mulmocast 2.1.1 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -144,7 +144,11 @@ const addTransitionEffects = (ffmpegContext, captionedVideoId, context, transiti
144
144
  }
145
145
  // Transition happens at the start of this beat
146
146
  const startAt = beatTimestamps[beatIndex] - 0.05; // 0.05 is to avoid flickering
147
- const duration = transition.duration;
147
+ // Limit transition duration to be no longer than either beat's duration
148
+ const prevBeatDuration = context.studio.beats[beatIndex - 1].duration ?? 1;
149
+ const currentBeatDuration = context.studio.beats[beatIndex].duration ?? 1;
150
+ const maxDuration = Math.min(prevBeatDuration, currentBeatDuration) * 0.9; // Use 90% to leave some margin
151
+ const duration = Math.min(transition.duration, maxDuration);
148
152
  const outputVideoId = `trans_${beatIndex}_o`;
149
153
  const processedVideoId = `${transitionVideoId}_f`;
150
154
  if (transition.type === "fade") {
@@ -185,11 +189,11 @@ const addTransitionEffects = (ffmpegContext, captionedVideoId, context, transiti
185
189
  // Cannot apply wipe without first frame
186
190
  return prevVideoId;
187
191
  }
188
- // Use xfade offset instead of trimming to avoid framerate issues
189
- // The static frames are created with proper duration, use offset to start transition at the right time
190
- const prevBeatDuration = context.studio.beats[beatIndex - 1].duration ?? 0;
191
- const xfadeOffset = prevBeatDuration - duration;
192
- // Apply xfade with explicit pixel format
192
+ // For wipe transitions, use offset=0 so transition starts immediately and completes within duration
193
+ // This ensures 0-100% wipe happens exactly during the transition duration
194
+ const xfadeOffset = 0;
195
+ // Apply xfade with offset=0 for complete 0-100% transition
196
+ // Both input videos should be at least duration seconds long (ensured by static frame generation)
193
197
  const xfadeOutputId = `${transitionVideoId}_xfade`;
194
198
  ffmpegContext.filterComplex.push(`[${transitionVideoId}]format=yuv420p[${transitionVideoId}_fmt]`);
195
199
  ffmpegContext.filterComplex.push(`[${nextVideoId}]format=yuv420p[${nextVideoId}_fmt]`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mulmocast",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "lib/index.node.js",
@@ -74,7 +74,7 @@
74
74
  "homepage": "https://github.com/receptron/mulmocast-cli#readme",
75
75
  "dependencies": {
76
76
  "@google-cloud/text-to-speech": "^6.4.0",
77
- "@google/genai": "^1.30.0",
77
+ "@google/genai": "^1.32.0",
78
78
  "@graphai/anthropic_agent": "^2.0.12",
79
79
  "@graphai/browserless_agent": "^2.0.1",
80
80
  "@graphai/gemini_agent": "^2.0.1",
@@ -94,11 +94,11 @@
94
94
  "dotenv": "^17.2.3",
95
95
  "fluent-ffmpeg": "^2.1.3",
96
96
  "graphai": "^2.0.16",
97
- "jsdom": "^27.2.0",
97
+ "jsdom": "^27.3.0",
98
98
  "marked": "^17.0.1",
99
99
  "mulmocast-vision": "^1.0.8",
100
100
  "ora": "^9.0.0",
101
- "puppeteer": "^24.32.0",
101
+ "puppeteer": "^24.32.1",
102
102
  "replicate": "^1.4.0",
103
103
  "yaml": "^2.8.2",
104
104
  "yargs": "^18.0.0",
@@ -117,7 +117,7 @@
117
117
  "prettier": "^3.7.4",
118
118
  "tsx": "^4.21.0",
119
119
  "typescript": "^5.9.3",
120
- "typescript-eslint": "^8.48.1"
120
+ "typescript-eslint": "^8.49.0"
121
121
  },
122
122
  "engines": {
123
123
  "node": ">=20.0.0"