Folge 8: gesungenes Laternenlied (Suno, DE/ES/FR je zweimal) mit Mitlesetext statt gesprochenem Vers; Schattenspiel mit den Higgsfield-Posen noa_B_hand-hase/-igel, Schatten von Noas Hand projiziert; Pino verdeckt die Laterne nicht mehr
Liedausschnitte: public/musik/folge08/laternenlied-<sprache>.mp3 (VPS /shared/youtube/musik/folge08/) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
dd319aa03d
commit
79cd9459dc
3 changed files with 104 additions and 38 deletions
71
remotion/src/folge08/laternenlied.ts
Normal file
71
remotion/src/folge08/laternenlied.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
import {SPRACHE, type Sprache} from '../baukasten/sprache';
|
||||||
|
import type {LiedZeile} from '../lieder/karaoke';
|
||||||
|
|
||||||
|
// Laternenlied (Suno, eine Fassung mit DE, ES und FR nacheinander, 644eb1d0…, siehe
|
||||||
|
// drehbuecher/lieder/suno-auswahl.md). Je Sprache ist der Abschnitt mit der zweimal gesungenen Strophe
|
||||||
|
// ausgeschnitten nach public/musik/folge08/laternenlied-<sprache>.mp3 (auf −14 LUFS, weich ein- und
|
||||||
|
// ausgeblendet). Wortzeiten am 06.11.2026 mit faster-whisper gemessen, hier relativ zum Schnittanfang.
|
||||||
|
|
||||||
|
type Lied = {datei: string; dauer: number; zeilen: LiedZeile[]};
|
||||||
|
|
||||||
|
// Wortzeiten im ganzen Lied → relativ zum Schnittanfang
|
||||||
|
const ab = (start: number, zeilen: string[]): LiedZeile[] =>
|
||||||
|
zeilen.map((z) =>
|
||||||
|
z
|
||||||
|
.split(' ')
|
||||||
|
.map((w) => {
|
||||||
|
const [text, t] = w.split('@');
|
||||||
|
return `${text}@${(Number(t) - start).toFixed(2)}`;
|
||||||
|
})
|
||||||
|
.join(' '),
|
||||||
|
);
|
||||||
|
|
||||||
|
const LIEDER: Record<Sprache, Lied> = {
|
||||||
|
// Schnitt 9,0–34,0 s
|
||||||
|
de: {
|
||||||
|
datei: 'musik/folge08/laternenlied-de.mp3',
|
||||||
|
dauer: 25.0,
|
||||||
|
zeilen: ab(9.0, [
|
||||||
|
'Mein@10.96 kleines@11.34 Licht,@12.06 so@12.4 rund@12.84 und@13.16 warm,@13.52',
|
||||||
|
'ich@13.96 trag@14.16 es@14.56 durch@14.9 den@15.26 Garten.@15.68',
|
||||||
|
'Der@16.74 Mond@17.0 schaut@17.24 schon,@17.64 die@18.02 Sterne@18.44 auch,@18.94',
|
||||||
|
'die@19.4 wollen@19.88 auf@20.38 uns@20.84 warten.@21.18',
|
||||||
|
'Mein@22.36 kleines@22.6 Licht,@23.24 so@23.62 rund@23.98 und@24.36 warm,@24.66',
|
||||||
|
'ich@25.14 trag@25.34 es@25.74 durch@26.06 den@26.4 Garten.@26.76',
|
||||||
|
'Der@27.8 Mond@28.18 schaut@28.42 schon,@28.82 die@29.2 Sterne@29.6 auch,@30.1',
|
||||||
|
'die@30.58 wollen@30.96 auf@31.56 uns@32.04 warten.@32.36',
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
// Schnitt 43,4–67,2 s
|
||||||
|
es: {
|
||||||
|
datei: 'musik/folge08/laternenlied-es.mp3',
|
||||||
|
dauer: 23.8,
|
||||||
|
zeilen: ab(43.4, [
|
||||||
|
'Mi@44.6 farolito@45.04 redondo,@46.04',
|
||||||
|
'lo@47.2 llevo@47.62 por@48.06 el@48.52 jardín.@48.8',
|
||||||
|
'La@50.3 luna@50.5 y@51.0 las@51.25 estrellas@51.9',
|
||||||
|
'nos@52.6 esperan@53.08 por@53.95 allí.@54.38',
|
||||||
|
'Mi@55.3 farolito@56.05 redondo,@57.17',
|
||||||
|
'lo@58.32 llevo@58.75 por@59.2 el@59.66 jardín.@60.04',
|
||||||
|
'La@61.5 luna@61.68 y@62.18 las@62.43 estrellas@63.07',
|
||||||
|
'nos@63.82 esperan@64.26 por@65.1 allí.@65.62',
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
// Schnitt 76,8–101,2 s
|
||||||
|
fr: {
|
||||||
|
datei: 'musik/folge08/laternenlied-fr.mp3',
|
||||||
|
dauer: 24.4,
|
||||||
|
zeilen: ab(76.8, [
|
||||||
|
'Ma@78.36 lanterne@78.78 est@79.4 ronde@79.82 et@80.26 chaude,@80.58',
|
||||||
|
'je@81.22 la@81.44 porte@81.96 au@82.34 grand@82.6 jardin.@82.82',
|
||||||
|
'Lune@83.7 et@84.16 étoiles,@84.74 tout@85.36 là-haut,@85.64',
|
||||||
|
"elles@86.94 m'attendent@87.1 en@88.04 chemin.@88.4",
|
||||||
|
'Ma@89.7 lanterne@89.92 est@90.4 ronde@90.74 et@91.28 chaude,@91.62',
|
||||||
|
'je@92.24 la@92.62 porte@93.12 au@93.44 grand@93.74 jardin.@93.96',
|
||||||
|
'Lune@95.14 et@95.52 étoiles,@95.84 tout@96.5 là-haut,@96.84',
|
||||||
|
"elles@98.08 m'attendent@98.24 en@99.24 chemin.@99.6",
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LATERNENLIED = LIEDER[SPRACHE];
|
||||||
|
|
@ -6,11 +6,14 @@ import {Blende, Vignette, atmen, kamFahrt} from '../baukasten/helfer';
|
||||||
import {Funkeln} from '../baukasten/natur';
|
import {Funkeln} from '../baukasten/natur';
|
||||||
import {BODEN} from '../baukasten/orte';
|
import {BODEN} from '../baukasten/orte';
|
||||||
import {Untertitel} from '../baukasten/untertitel';
|
import {Untertitel} from '../baukasten/untertitel';
|
||||||
|
import {Karaoke} from '../lieder/karaoke';
|
||||||
|
import {LATERNENLIED} from './laternenlied';
|
||||||
import {plane} from './plan';
|
import {plane} from './plan';
|
||||||
import {Abenddunkel, GartenAbend, Laterne, laterneInNoasHand} from './teile';
|
import {Abenddunkel, GartenAbend, Laterne, laterneInNoasHand} from './teile';
|
||||||
|
|
||||||
// Szene 3: Es wird dunkel. Abendgarten, rechts die Hauswand mit erleuchtetem Fenster.
|
// Szene 3: Es wird dunkel. Abendgarten, rechts die Hauswand mit erleuchtetem Fenster.
|
||||||
// Noa knipst das Lämpchen an (kein Feuer) und singt den Laternenvers; die Laterne pendelt sanft.
|
// Noa knipst das Lämpchen an (kein Feuer); dann erklingt das gesungene Laternenlied (Suno, je Sprache
|
||||||
|
// die zweimal gesungene Strophe, laternenlied.ts) mit Mitlesetext. Noa wiegt sich, die Laterne pendelt im Takt.
|
||||||
// Pino tippelt zu ihr (baukasten/gang.ts, Füße rutschen nicht). Lulu steht schon an der Hauswand –
|
// Pino tippelt zu ihr (baukasten/gang.ts, Füße rutschen nicht). Lulu steht schon an der Hauswand –
|
||||||
// sie geht nicht durchs Bild, weil ihr Geh-Clip kein echtes Gehen ist.
|
// sie geht nicht durchs Bild, weil ihr Geh-Clip kein echtes Gehen ist.
|
||||||
|
|
||||||
|
|
@ -23,16 +26,9 @@ export const S3 = plane('s3', [
|
||||||
{id: 'klick', dauer: 1.4},
|
{id: 'klick', dauer: 1.4},
|
||||||
{id: 'e2', wer: 'ERZ'},
|
{id: 'e2', wer: 'ERZ'},
|
||||||
{id: 'p1', wer: 'PINO'},
|
{id: 'p1', wer: 'PINO'},
|
||||||
{id: 'v1', wer: 'NOA'},
|
{id: 'e3', wer: 'ERZ'}, // „Kannst du mitsingen?“
|
||||||
{id: 'v2', wer: 'NOA'},
|
{id: 'lied', dauer: LATERNENLIED.dauer},
|
||||||
{id: 'v3', wer: 'NOA'},
|
{id: 'bild1', dauer: 1.2},
|
||||||
{id: 'v4', wer: 'NOA', pause: 0.6},
|
|
||||||
{id: 'e3', wer: 'ERZ', pause: 0.8},
|
|
||||||
{id: 'w1', wer: 'NOA'},
|
|
||||||
{id: 'w2', wer: 'NOA'},
|
|
||||||
{id: 'w3', wer: 'NOA'},
|
|
||||||
{id: 'w4', wer: 'NOA'},
|
|
||||||
{id: 'bild1', dauer: 1.8},
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const Szene3: React.FC = () => {
|
export const Szene3: React.FC = () => {
|
||||||
|
|
@ -41,12 +37,14 @@ export const Szene3: React.FC = () => {
|
||||||
|
|
||||||
const an = z.klick.start + 12;
|
const an = z.klick.start + 12;
|
||||||
const licht = interpolate(f, [an, an + 8], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
const licht = interpolate(f, [an, an + 8], [0, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
||||||
const singt = f >= z.v1.start && f < z.w4.ende;
|
// 84 BPM: die Laterne pendelt im Takt (ein Hin-und-her pro Takt)
|
||||||
const schwung = singt ? Math.sin((f - z.v1.start) * 0.09) * 7 : Math.sin(f * 0.05) * 2;
|
const singt = f >= z.lied.start && f < z.lied.ende;
|
||||||
|
const takt = (f - z.lied.start) * ((2 * Math.PI * 84) / 60 / 30 / 2);
|
||||||
|
const schwung = singt ? Math.sin(takt) * 7 : Math.sin(f * 0.05) * 2;
|
||||||
const lat = laterneInNoasHand(NOA_X);
|
const lat = laterneInNoasHand(NOA_X);
|
||||||
|
|
||||||
// Pino kommt beim Vers dicht an Noas Stiefel (ganze Schritte, Füße bleiben am Boden)
|
// Pino kommt beim Lied dicht an Noas Stiefel (ganze Schritte, Füße bleiben am Boden)
|
||||||
const PINO = gang('pino', z.v1.start + 6, 300, NOA_X - 120, 2.5);
|
const PINO = gang('pino', z.lied.start + 20, 220, NOA_X - 300, 2.5); // bleibt links der Laterne stehen, verdeckt sie nicht
|
||||||
|
|
||||||
const kam = kamFahrt(f, [
|
const kam = kamFahrt(f, [
|
||||||
[0, 1000, 540, 1.0],
|
[0, 1000, 540, 1.0],
|
||||||
|
|
@ -55,7 +53,7 @@ export const Szene3: React.FC = () => {
|
||||||
[z.e2.ende, 720, 640, 1.7],
|
[z.e2.ende, 720, 640, 1.7],
|
||||||
[z.p1.start + 6, lat.x, lat.y, 2.3], // „Mein Igel leuchtet!“
|
[z.p1.start + 6, lat.x, lat.y, 2.3], // „Mein Igel leuchtet!“
|
||||||
[z.p1.ende + 10, 820, 640, 1.35],
|
[z.p1.ende + 10, 820, 640, 1.35],
|
||||||
[z.w1.start, 900, 600, 1.2],
|
[z.lied.start + 90, 900, 600, 1.2],
|
||||||
[dauer, 920, 600, 1.15],
|
[dauer, 920, 600, 1.15],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
@ -71,7 +69,7 @@ export const Szene3: React.FC = () => {
|
||||||
x={NOA_X}
|
x={NOA_X}
|
||||||
y={BODEN}
|
y={BODEN}
|
||||||
stauchY={atmen(f, 2)}
|
stauchY={atmen(f, 2)}
|
||||||
drehung={singt ? Math.sin((f - z.v1.start) * 0.045) * 1.5 : 0}
|
drehung={singt ? Math.sin(takt) * 1.6 : 0}
|
||||||
/>
|
/>
|
||||||
<Laterne x={lat.x} y={lat.y} s={lat.s} licht={licht} schwung={schwung} stab={false} />
|
<Laterne x={lat.x} y={lat.y} s={lat.s} licht={licht} schwung={schwung} stab={false} />
|
||||||
<Funkeln x={lat.x} y={lat.y} start={an} dauer={30} s={0.8} />
|
<Funkeln x={lat.x} y={lat.y} start={an} dauer={30} s={0.8} />
|
||||||
|
|
@ -82,7 +80,7 @@ export const Szene3: React.FC = () => {
|
||||||
pose={[
|
pose={[
|
||||||
[0, 'pino_A6_blick-rechts'],
|
[0, 'pino_A6_blick-rechts'],
|
||||||
[an, 'pino_A4_staunen'],
|
[an, 'pino_A4_staunen'],
|
||||||
[z.v1.start, 'pino_A6_blick-rechts'],
|
[z.lied.start, 'pino_A6_blick-rechts'],
|
||||||
[PINO.ende, 'pino_A3_lachen'],
|
[PINO.ende, 'pino_A3_lachen'],
|
||||||
]}
|
]}
|
||||||
x={PINO.x(f)}
|
x={PINO.x(f)}
|
||||||
|
|
@ -93,12 +91,9 @@ export const Szene3: React.FC = () => {
|
||||||
<Abenddunkel licht={{x: lat.x, y: lat.y}} staerke={0.55 - 0.15 * licht} radius={380 + 260 * licht} />
|
<Abenddunkel licht={{x: lat.x, y: lat.y}} staerke={0.55 - 0.15 * licht} radius={380 + 260 * licht} />
|
||||||
</Kamera>
|
</Kamera>
|
||||||
<Vignette />
|
<Vignette />
|
||||||
{/* Zwischenlösung bis zum gesungenen Laternenlied (Suno): Instrumental aus Folge 1 unter dem Vers */}
|
<Sequence from={z.lied.start} durationInFrames={z.lied.ende - z.lied.start + 6}>
|
||||||
<Sequence from={z.v1.start - 20} durationInFrames={z.w4.ende - z.v1.start + 60}>
|
<Audio src={staticFile(LATERNENLIED.datei)} volume={0.85} />
|
||||||
<Audio
|
<Karaoke zeilen={LATERNENLIED.zeilen} />
|
||||||
src={staticFile('musik/folge01/lied.mp3')}
|
|
||||||
volume={(g) => 0.3 * Math.min(interpolate(g, [0, 20], [0, 1], {extrapolateRight: 'clamp'}), interpolate(g, [z.w4.ende - z.v1.start + 20, z.w4.ende - z.v1.start + 60], [1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'}))}
|
|
||||||
/>
|
|
||||||
</Sequence>
|
</Sequence>
|
||||||
<Untertitel zeilen={S3.liste} />
|
<Untertitel zeilen={S3.liste} />
|
||||||
<Blende dauer={dauer} rein={14} raus={14} />
|
<Blende dauer={dauer} rein={14} raus={14} />
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {interpolate, useCurrentFrame} from 'remotion';
|
import {interpolate, useCurrentFrame} from 'remotion';
|
||||||
import {Hand} from '../baukasten/hand';
|
import {Hand} from '../baukasten/hand';
|
||||||
import {Blende, kamFahrt} from '../baukasten/helfer';
|
import {POSEN_SKALA} from '../baukasten/figur';
|
||||||
|
import {Blende, kamFahrt, punkt} from '../baukasten/helfer';
|
||||||
|
import {BODEN} from '../baukasten/orte';
|
||||||
import {SCHRIFT, Untertitel} from '../baukasten/untertitel';
|
import {SCHRIFT, Untertitel} from '../baukasten/untertitel';
|
||||||
import {plane} from './plan';
|
import {plane} from './plan';
|
||||||
import {HandSchatten} from './teile';
|
import {HandSchatten} from './teile';
|
||||||
|
|
@ -26,14 +28,16 @@ export const S7 = plane('s7', [
|
||||||
|
|
||||||
const LATERNE = {x: 1010, y: PLATZ.laterneBoden.y};
|
const LATERNE = {x: 1010, y: PLATZ.laterneBoden.y};
|
||||||
const NOA_X = PLATZ.noa + 140;
|
const NOA_X = PLATZ.noa + 140;
|
||||||
// Der gezeichnete Arm wirkte unecht (Rückmeldung 06.11.) – bis die Higgsfield-Posen da sind
|
// Noa hockt neben der Laterne und hält die Hand hoch (Higgsfield-Posen noa_B_hand-hase / -igel).
|
||||||
// (noa_B_hand-hase / noa_B_hand-igel), zeigt nur die Karte oben die Hand; der Schatten kommt von
|
// Der Schatten wird von ihrer Hand aus an die Wand projiziert: Handmitte im Bild gemessen
|
||||||
// einer gedachten Hand über der Laterne.
|
// (Hase 870/285, Igel 880/345 auf ihrer Leinwand), Hocke-Größe wie noa_B_hocken.
|
||||||
const HAND = {x: 955, y: 770};
|
const HOCKE = 340 * POSEN_SKALA.noa_B_hocken;
|
||||||
const HAND_S = 0.3;
|
const HAND_HASE = punkt('noa', NOA_X, BODEN, 870, 285, HOCKE);
|
||||||
|
const HAND_IGEL = punkt('noa', NOA_X, BODEN, 880, 345, HOCKE);
|
||||||
|
const HAND_S = 0.26;
|
||||||
const K = 3; // Hand nah am Licht → großer Schatten
|
const K = 3; // Hand nah am Licht → großer Schatten
|
||||||
|
|
||||||
// Mitmach-Karte oben links (oben rechts erscheint in der Pause das „?“)
|
// Mitmach-Karte oben links wie im Zähllied (oben rechts erscheint in der Pause das „?“)
|
||||||
const HandKarte: React.FC<{art: 'hase' | 'igel'; von: number; bis: number}> = ({art, von, bis}) => {
|
const HandKarte: React.FC<{art: 'hase' | 'igel'; von: number; bis: number}> = ({art, von, bis}) => {
|
||||||
const f = useCurrentFrame();
|
const f = useCurrentFrame();
|
||||||
const auf = interpolate(f, [von, von + 10, bis - 8, bis], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
const auf = interpolate(f, [von, von + 10, bis - 8, bis], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
||||||
|
|
@ -67,10 +71,6 @@ export const Szene7: React.FC = () => {
|
||||||
const hase = interpolate(f, [z.bild0.start + 6, z.bild0.ende, z.hals.start, z.hals.start + 10], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
const hase = interpolate(f, [z.bild0.start + 6, z.bild0.ende, z.hals.start, z.hals.start + 10], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
||||||
const igel = interpolate(f, [z.igel.start, z.igel.start + 12, dauer - 20, dauer - 6], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
const igel = interpolate(f, [z.igel.start, z.igel.start + 12, dauer - 20, dauer - 6], [0, 1, 1, 0], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
||||||
const strecken = interpolate(f, [z.hals.start, z.hals.start + 20, z.hals.ende - 10, z.hals.ende + 6], [1, 1.12, 1.12, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
const strecken = interpolate(f, [z.hals.start, z.hals.start + 20, z.hals.ende - 10, z.hals.ende + 6], [1, 1.12, 1.12, 1], {extrapolateLeft: 'clamp', extrapolateRight: 'clamp'});
|
||||||
const wackelnHase = Math.sin(f * 0.25);
|
|
||||||
const wackelnIgel = Math.sin(f * 0.3);
|
|
||||||
// die Hand wippt leicht; der Schatten wippt K-mal so weit mit
|
|
||||||
const hand = {x: HAND.x + Math.sin(f * 0.07) * 4, y: HAND.y + Math.sin(f * 0.09) * 5};
|
|
||||||
const kam = kamFahrt(f, [
|
const kam = kamFahrt(f, [
|
||||||
[0, 920, 600, 1.2],
|
[0, 920, 600, 1.2],
|
||||||
[z.n1.start, 920, 620, 1.28],
|
[z.n1.start, 920, 620, 1.28],
|
||||||
|
|
@ -84,13 +84,13 @@ export const Szene7: React.FC = () => {
|
||||||
f={f}
|
f={f}
|
||||||
kam={kam}
|
kam={kam}
|
||||||
laterne={{inHand: false, licht: 1, x: LATERNE.x, y: LATERNE.y}}
|
laterne={{inHand: false, licht: 1, x: LATERNE.x, y: LATERNE.y}}
|
||||||
noa={{pose: 'noa_B_hocken', x: NOA_X}}
|
noa={{pose: [[0, 'noa_B_hocken'], [z.bild0.start + 4, 'noa_B_hand-hase'], [z.hals.start, 'noa_B_hocken'], [z.igel.start - 2, 'noa_B_hand-igel']], x: NOA_X}}
|
||||||
pino={{pose: [[0, 'pino_A4_staunen'], [z.p1.start, 'pino_A3_lachen']], x: LATERNE.x - 230}}
|
pino={{pose: [[0, 'pino_A4_staunen'], [z.p1.start, 'pino_A3_lachen']], x: LATERNE.x - 230}}
|
||||||
lulu={{pose: 'lulu_A3_lachen', stauchY: strecken}}
|
lulu={{pose: 'lulu_A3_lachen', stauchY: strecken}}
|
||||||
wandExtra={
|
wandExtra={
|
||||||
<>
|
<>
|
||||||
<HandSchatten art="hase" hand={hand} licht={LATERNE} s={HAND_S} k={K} deckkraft={0.42 * hase} wackeln={wackelnHase} />
|
<HandSchatten art="hase" hand={HAND_HASE} licht={LATERNE} s={HAND_S} k={K} deckkraft={0.42 * hase} />
|
||||||
<HandSchatten art="igel" hand={hand} licht={LATERNE} s={HAND_S} k={K} deckkraft={0.42 * igel} wackeln={wackelnIgel} />
|
<HandSchatten art="igel" hand={HAND_IGEL} licht={LATERNE} s={HAND_S} k={K} deckkraft={0.42 * igel} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue