@koda-sl/baker-cli 0.281.0-dev.1f1c09c80 → 0.281.1-dev.1f1c09c80

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.
package/dist/cli.js CHANGED
@@ -32699,9 +32699,17 @@ var Beat = z30.object({
32699
32699
  */
32700
32700
  sound: z30.string().min(1).max(200).optional(),
32701
32701
  /**
32702
- * Set only when this beat's subject is talking to camera. Off by default, and
32703
- * the default is load-bearing: a person visibly speaking under a voice that is
32704
- * not theirs reads as bad dubbing, which is what sank the first cut of this.
32702
+ * Whether this beat's subject is talking to camera.
32703
+ *
32704
+ * Left unset it follows the cast: an ad that cast a presenter, in a shot they are in,
32705
+ * with a line, is that person speaking. Set it to FALSE for the exception — a cutaway,
32706
+ * a product shot, a beat you want a narrator to carry over.
32707
+ *
32708
+ * It used to be opt-in, back when the only route was dubbing and OFF was the safe
32709
+ * default. That inverted the moment on-camera started meaning the video model voices
32710
+ * the clip itself: measured on a real run, a brief that said "talking to camera all the
32711
+ * way through" produced an ad with her face on screen and a narrator cast from a prose
32712
+ * description reading her lines, because nothing set this flag.
32705
32713
  */
32706
32714
  on_camera: z30.boolean().optional(),
32707
32715
  /**
@@ -32948,10 +32956,10 @@ function adSpecCastElements(spec, avatar) {
32948
32956
  }
32949
32957
  ];
32950
32958
  }
32951
- function motionPrompt(beat, isClosingCard, place, physics) {
32959
+ function motionPrompt(beat, toCamera, isClosingCard, place, physics) {
32952
32960
  if (isClosingCard) return BRAND_PLATE;
32953
32961
  const shot = `${beat.show}${place}${physics}`;
32954
- if (beat.on_camera) return shot;
32962
+ if (toCamera) return shot;
32955
32963
  return `${shot} Nobody in frame is speaking: mouths CLOSED and STILL throughout, no talking, no lip movement. Whoever is in shot is looking, reacting or working \u2014 never addressing the camera.`;
32956
32964
  }
32957
32965
  function staticTranscript(spec) {
@@ -32973,11 +32981,16 @@ function staticTranscript(spec) {
32973
32981
  }
32974
32982
  return out;
32975
32983
  }
32984
+ function beatToCamera(spec, beat, isClosingCard) {
32985
+ if (isClosingCard) return false;
32986
+ if (beat.on_camera !== void 0) return beat.on_camera;
32987
+ return Boolean(spec.cast) && beat.cast !== false;
32988
+ }
32976
32989
  function wantsNativeSpeech(spec, closesOnCard) {
32977
32990
  if (!spec.cast || spec.voiceover === false) return false;
32978
32991
  const last = spec.beats.length - 1;
32979
32992
  const speaking = spec.beats.filter((_, i) => !(closesOnCard && i === last));
32980
- return speaking.length > 0 && speaking.every((beat) => beat.on_camera === true && beat.cast !== false);
32993
+ return speaking.length > 0 && speaking.every((beat) => beatToCamera(spec, beat, false) && beat.cast !== false);
32981
32994
  }
32982
32995
  function beatDialogue(spec, beat, window2) {
32983
32996
  if (spec.voiceover === false) return [];
@@ -32986,12 +32999,9 @@ function beatDialogue(spec, beat, window2) {
32986
32999
  line: beat.say,
32987
33000
  start_s: window2.start,
32988
33001
  end_s: window2.end,
32989
- // `on_camera` is the engine's own switch for "this line is narration" — absent, it
32990
- // guesses from who is in frame, which is how a still photograph once got lip-synced.
32991
- // Never true on the closing plate: it is a flat colour card with no one in it, and
32992
- // saying someone is on camera there sent the engine looking for a mouth to lip-sync
32993
- // on a picture that has no person.
32994
- on_camera: beat.on_camera === true && !window2.isClosingCard,
33002
+ // Always stated, never left to the engine: absent, it guesses from who is in frame,
33003
+ // which is how a still photograph once got lip-synced.
33004
+ on_camera: beatToCamera(spec, beat, window2.isClosingCard),
32995
33005
  // Naming the CAST as speaker is the other half of what sends this beat down the
32996
33006
  // native path. Left unnamed, the speaker defaults to "voiceover" — a narrator, who is
32997
33007
  // by definition never on camera — so every beat took the dubbed path: a clip generated
@@ -33044,7 +33054,7 @@ function adSpecToBlueprint(spec) {
33044
33054
  isClosingCard,
33045
33055
  nativeSpeech
33046
33056
  }),
33047
- motion_prompt: motionPrompt(beat, isClosingCard, place, physics),
33057
+ motion_prompt: motionPrompt(beat, beatToCamera(spec, beat, isClosingCard), isClosingCard, place, physics),
33048
33058
  start_frame_prompt: isClosingCard ? BRAND_PLATE : `${beat.show}${place}${physics}`
33049
33059
  };
33050
33060
  });