muvid.footage.music_cut¶
Cut footage to the music — the montage half of a music video.
A music video in muvid has always assumed its footage is a RECORDING OF THE SONG — a
concert, a dance, a lip-sync — so every clip is synced: placed on the song by
listening to its own soundtrack (muvid.footage.align) and shown at exactly the
moment it was filmed. That is the right answer for that footage and the wrong one for
the other common case, which is the one phone galleries sell as “memories”: a day out
filmed in short clips and photos, plus a song that was never playing. There is nothing
to sync to, so the aligner rightly cannot place those clips, and an edit built only from
synced clips is mostly black.
This module is the other answer. Footage that does not contain the song is cut TO the music instead of synced WITH it:
where the cuts fall is the montage planner’s decision (
muvid.montage.plan.plan_montage()): every cut on a beat, bar or section boundary, denser in loud sections, with the reuse policy that lets a few clips carry a whole song and keeps a revisited clip from showing the same stretch twice;which stretch of a video each cut shows is decided here, by the picture: the stretch whose visual hits (
muvid.footage.beats.activity_signal()— the onsets of picture change, camera moves included) land on the beats inside the cut, and whose liveliness suits the section’s loudness. That is the alignment phone “memories” do not do;how a still moves is a named camera look (push, pull, pan) toward the photo’s salient region (
burns.salient_boxwhenburnsis installed).
The output is ordinary EdlEntry cuts with
source_in set — free cuts — so a montage is an
edit like any other: saved, changed cut by cut, rendered by the same assembler over the
clean song. Synced and free cuts mix in one edit: fill_spans() fills only the
spans it is given, which the service uses to put free cuts in the gaps a synced edit
leaves.
Pure planning: no file is written; the measurements (song analysis, picture-change envelopes, salient boxes) come in through keyword seams with working defaults.
Module Attributes
Pick the cutting style from the song (see |
Functions
|
Where in a video a cut of |
|
Free cuts of |
|
The cutting style for a song: a slow dissolve below |
Classes
|
A video's picture-change signal on a regular grid of its own time. |
|
One picture source a montage may cut to: a video ( |
|
The result: free cuts for the requested spans, and an account of how they were chosen (tempo, style, how well each video's picture landed on the beat). |
- muvid.footage.music_cut.ARCHETYPE_AUTO = 'auto'¶
Pick the cutting style from the song (see
pick_archetype()).
- class muvid.footage.music_cut.Envelope(hop_s, activity, hits, sharpness=None)[source]¶
Bases:
objectA video’s picture-change signal on a regular grid of its own time.
- classmethod from_signals(record)[source]¶
From
muvid.footage.beats.activity_signal()’ssignalsmapping.
- class muvid.footage.music_cut.FreeSource(clip_id, path, kind='video', duration_s=None)[source]¶
Bases:
objectOne picture source a montage may cut to: a video (
duration_sits length) or a still (kind="still",duration_s=None— it can be held for any span).
- class muvid.footage.music_cut.MusicCut(entries=<factory>, report=<factory>)[source]¶
Bases:
objectThe result: free cuts for the requested spans, and an account of how they were chosen (tempo, style, how well each video’s picture landed on the beat).
- muvid.footage.music_cut.choose_source_in(env, *, clip_duration, length, beat_offsets=(), used=(), energy=0.0, lead_s=0.0, trail_s=0.0, ordinal=0)[source]¶
Where in a video a cut of
lengthseconds should start:(source_in, fit).Scores every in-point on the envelope’s grid (
lead_s/trail_sof extra footage kept free on either side, for a blend), by three terms:hits on the beat — the mean picture-change hit at each
beat_offsets(beats inside the cut, in seconds from its start), relative to the video’s own mean hit: above 1 means the picture changes ON the beat more than it does anywhere;liveliness matched to loudness —
energyin [-1, 1] (quiet to loud section) times how lively the stretch is relative to the whole video;reuse — the fraction of the stretch already shown by another cut, penalised.
fitis the hits term at the chosen point (0 when there are no inner beats or no envelope). Without an envelope it falls back to a golden-ratio stride over the room, the montage planner’s own blind rule, with reuse still avoided.>>> hits = np.zeros(100); hits[[20, 30]] = 1.0 # changes at 2.0 s and 3.0 s >>> env = Envelope(hop_s=0.1, activity=np.full(100, 0.1), hits=hits) >>> s, fit = choose_source_in(env, clip_duration=10.0, length=2.0, beat_offsets=[0.5, 1.5]) >>> round(s, 2), fit > 1 (1.5, True)
- muvid.footage.music_cut.fill_spans(song_path, sources, *, spans=None, song_duration=None, analysis=None, archetype='auto', cut_feel='', envelope_of=None, anchor_of=<function _default_anchor>, canvas=(1920, 1080), fps=30.0, fit='cover', size_of=<function display_size>)[source]¶
Free cuts of
sourcescoveringspansof the song (default: all of it).Seams, each with a default that works:
analysis(the song’s beats, bars and sections —muvid.montage.analysis.analyze()),envelope_of(a video’s picture-changeEnvelope;Nonefalls back to the planner’s blind stride),anchor_of(a still’s focal point).archetypeis a montage archetype with one picture per slot, or"auto";cut_feela montage pace (slow,steady,driving,frantic).fitis one ofFITS;size_ofreads a picture’s displayed size (forcover).Returns
MusicCutwhoseentriesare validated-shapeEdlEntryfree cuts, contiguous over each span, in song order (spans with nothing in them are simply not covered — the caller’sfill_gapsmakes that explicit).- Return type: