muvid.lyricvid.pictures¶
Pictures for a lyric video: a mosaic that builds up as its words are sung (muvid#151).
A learner’s lyric video wants a picture of what is being sung. This layer places small pictures around the lyrics. Each one appears when its word is first sung, so a mosaic builds up through the song, and it bounces (a quick enlarge and back) every time the word is sung again. The lyrics stay readable because no tile, even at the top of its bounce, enters the text block.
Four steps, each its own function so a caller can replace one:
text_block()finds where the lyrics are drawn: the union of non-background pixels over frames of the finished lyric render.mosaic_cells()lays out cells in the bands above and below it.plan_tiles()times each picture from the sung word times (word_times()): it appears just before the first time its word is sung, and bounces on every sung occurrence.render()composites the tiles onto the lyric render in one ffmpeg pass. Pictures are fitted inside their cell, never cropped, so a CC BY-SA picture is shown unmodified; the bounce is a per-framescale.
Rights travel with each Picture (its credit), and credits()
lists the credit of every tile actually shown, in order of appearance, so the
end card cannot forget one.
Needs ffmpeg/ffprobe on PATH and nothing beyond muvid’s core
dependencies (numpy).
Functions
|
An ffmpeg expression of |
|
The credit line of every shown picture, in order of appearance, without repeats. |
|
|
|
|
|
Place each sung picture in a cell, in order of its word's first sung time. |
|
Composite |
|
Where the lyrics are drawn: the box around every non-background pixel of |
|
The words that have a picture but are never sung (so the picture is never shown). |
|
Every sung start of every word, from a |
Classes
|
A quick enlarge and back, timed to a sung word. |
|
A picture for one sung word, with the credit line its licence requires. |
|
A picture placed in a cell, with when it appears and when it bounces. |
- class muvid.lyricvid.pictures.Bounce(scale=0.18, duration=0.32, lead=0.04)[source]¶
Bases:
objectA quick enlarge and back, timed to a sung word.
scaleis the extra size at the peak (0.18 is 18 % larger),durationthe length of the whole pop in seconds, andleadhow long before the sung onset it starts, so the peak lands on the syllable.
- class muvid.lyricvid.pictures.Picture(word, path, credit=None)[source]¶
Bases:
objectA picture for one sung word, with the credit line its licence requires.
- class muvid.lyricvid.pictures.Tile(picture, box, appear, beats=<factory>)[source]¶
Bases:
objectA picture placed in a cell, with when it appears and when it bounces.
- muvid.lyricvid.pictures.bounce_expr(beats, bounce)[source]¶
An ffmpeg expression of
t: 1 at rest,1 + scaleat the peak of each pop.- Return type:
- muvid.lyricvid.pictures.credits(tiles)[source]¶
The credit line of every shown picture, in order of appearance, without repeats.
Raises when a shown picture has no credit: a dropped attribution is a licence failure nobody downstream can see.
- muvid.lyricvid.pictures.frame_size(video)[source]¶
(width, height)ofvideo’s frames: thesizeto plan cells for.
- muvid.lyricvid.pictures.mosaic_cells(n, block, *, size=(1920, 1080), gap=24, aspect=1.3333333333333333, top=0.04, bottom=0.95, min_band=120, width=0.94)[source]¶
ncells in one row above and one row below the text block, centre-out.Bands thinner than
min_bandpixels are skipped. The first cells returned are the most central, so a short list of pictures sits near the lyrics.
- muvid.lyricvid.pictures.plan_tiles(pictures, times, cells, *, lead=0.15, bounce=Bounce(scale=0.18, duration=0.32, lead=0.04))[source]¶
Place each sung picture in a cell, in order of its word’s first sung time.
A picture whose word is never sung is left out (see
unsung_pictures()). With abounce, each picture shrinks inside its cell by the bounce’s peak, so at full size it still fits the cell, and the cells already keep clear of the text.
- muvid.lyricvid.pictures.render(video, tiles, out, *, bounce=Bounce(scale=0.18, duration=0.32, lead=0.04), fade_in=0.35, border=None, border_px=3, crf=18)[source]¶
Composite
tilesontovideoin one ffmpeg pass; audio is copied.Each picture is fitted inside its tile box (never cropped), framed by a
borderofborder_pxwhen given, fades in atappearand pops on each of itsbeatswhenbounceis set.- Return type:
- muvid.lyricvid.pictures.text_block(video, *, background, threshold=40, fps=1.0, downscale=4, margin=40)[source]¶
Where the lyrics are drawn: the box around every non-background pixel of
video.Frames are sampled at
fpsand shrunk bydownscalefor speed; a pixel is ink when its summed RGB distance frombackgroundexceedsthreshold.marginpixels are added on every side. Raises when nothing is drawn.