비디오 스토리텔링은(는) 무엇을 하나요?
롱폼 비디오의 시각적 레이어를 구축하여 시청자가 9분이 지나도 방향감을 잃지 않도록 하는 방법입니다. 뉴스 테이크, 단일 주제 심층 분석, 비교, 튜토리얼, 리스트 기사 등 대본이 있는 모든 토크헤드 비디오에 적용됩니다.
이 스킬이 대체하는 실패는 '씬 씽킹(scene-thinking)'입니다. 몇 초마다 새로운 그래픽이 나타나면 시청자는 매번 이해를 재시작해야 하며, 어떤 개별 그래픽도 명확히 잘못된 것이 없기 때문에 피드백은 특정 결함 대신 모호한 '혼란스럽다' 또는 '너무 많은 정보'로 돌아옵니다.
중립적인 연습 비트 시트를 보려면 리포지토리 루트에 있는 docs/STORYTELLING-WORKBOOK.md를 읽으십시오. 재사용 가능한 디자인 시스템은 이 스킬의 reference/design-system.md에 있습니다. 작업된 오픈 루프 지오메트리는 reference/patterns/wall-of-slots/에 있습니다. 개인 소스 비디오는 필요하지 않습니다.
이것은 hyperframes-video-beats가 아닙니다. 그 스킬은 토크헤드 위에 오버레이 카드를 배치합니다. 이 스킬은 비디오가 다루는 것을 설계합니다.
1 · 네 가지 원칙
하나의 지속적인 세계
비디오는 단일 공간 안에 존재하며 절대 리셋되지 않습니다. 시청자가 이미 본 모든 것은 그들이 놓아둔 곳에 그대로 존재하며, 새로운 자료는 기존 자료를 대체하는 것이 아니라 추가됩니다. 한 번 그려진 요소는 다시 그려지거나, 이동되거나, 레이블이 다시 지정되지 않습니다.
이 스킬의 다른 모든 것은 이것에 의존합니다. 공간이 계속 변하면 카메라는 갈 곳이 없고, 화면에 다른 것이 없다면 스포트라이트는 의미가 없으며, 리셋되는 세계에서는 열린 루프가 열려 있을 수 없습니다.
세계는 또한 머물 가치가 있어야 하므로, 아무것도 구축하기 전에 공간 문법을 결정하고 전체 런타임 동안 유지하십시오. 참조 빌드에서는: 왼쪽에서 오른쪽은 결과를 향한 방향, 위는 인간을 향하며 화면에서 유일하게 따뜻한 것, 아래는 기록 시스템을 향합니다. 처음 2분 안에 이 문법을 배운 시청자는 나머지 비디오를 추가 비용 없이 읽을 수 있습니다.
의미를 위해 문법을 정확히 한 번, 의도적으로 깨십시오. 참조 빌드에서 10분 동안 유일한 오른쪽에서 왼쪽 이동은 '재개율'이라는 단어와 함께 해결된 티켓이 다시 큐로 되돌아가는 것입니다. 이전 3분 동안 방향이 무언가를 의미했기 때문에 아무 말 없이 이해됩니다.
카메라는 편집이다
새로운 그래픽으로 컷하는 것은 시청자가 매번 방향감을 잃게 만듭니다. 고정된 공간을 이동하는 것은 시청자에게 아무런 비용이 들지 않습니다. 푸시인(push-in)은 '이미 이해한 것의 부분을 자세히 보라'로 읽히고, 풀백(pull-back)은 지금까지 구축된 모든 것이 여전히 존재하기 때문에 작업이 결실을 맺는 곳입니다.
세 가지 고도(altitude)로 작업하고 인접한 고도 사이를 이동하십시오:
| 고도 | 보여주는 것 | 사용처 |
|---|---|---|
| 세계(World) | 전체 공간 | 방향 제시, 결실, '여기가 우리가 있는 곳' |
| 영역(Region) | 논의 중인 하위 그래프 | 대부분의 런타임 |
| 세부(Detail) | 하나의 요소 | 숫자, 상태 변경, 결정 |
세부에서 세계로 바로 점프하는 것은 의도적인 결실 비트가 아니라면 방향을 잃게 만듭니다. 그 경우에는 사용 가능한 최고의 이동입니다.
각각 배우는 데 재구축 비용이 드는 규칙:
- 프레이밍을 축척 비율이 아닌 정확한 세계 창(window)으로 이름 지정하십시오. 창 경계는 레이블 사이에 있어야 합니다. 프레이밍을 '축척 0.6'으로 지정하면 프레임 가장자리에서 단어가 반으로 잘립니다.
- 같은 목적에 같은 창을 재사용하십시오. 방향 확인 샷이 특정 창이라면 항상 그 정확한 창을 사용하십시오. 거의 동일한 프레이밍은 표류로 읽힙니다.
- 이동 거리에 따라 지속 시간을 다양화하십시오. 하나의 전역 프리셋을 사용하지 마십시오.
- 카메라와 전체 프레임 와이프는 순차적으로, 절대 겹치지 않게 하십시오. 동시에 발생하면 콘텐츠를 단두대처럼 자릅니다. 카메라가 먼저, 그다음 와이프.
- 커버 레이어는 카메라가 그 아래로 이동하기 전에 불투명해져야 합니다. 순서가 바뀌면 이동의 일부가 노출되어 점프 컷으로 읽힙니다.
- 프레임 가장자리로부터 60px 이내에 레이블을 배치하지 마십시오. 요소는 프레임 밖으로 나가서 '세상은 계속된다'로 읽힐 수 있지만, 글자가 중간에 잘리면 버그로 읽힙니다. 마스킹이 아닌 배치로 해결하십시오. 페더(feather)는 약 1800px/s로 이동하는 칼날을 잡을 수 없기 때문입니다.
- 같은 대상에 대한 두 번의 연속 이동은 글리치로 읽힙니다. 완료된 리프레임(re-frame) 후에 시작되는 와이프는 줌, 완전 정지, 그리고 두 번째 움직임입니다. 클라이언트는 이를 '글리치와 일시 정지'라고 부릅니다. 하나의 제스처로 병합하십시오: 공유 대칭 이즈(power2.inOut), 같은 프레임에 착지하여 패널이 푸티지를 옆으로 밀어내는 것으로 읽히게 합니다. 관련: 보이는 푸티지 이동 시 전방-로드 이즈(power3/4.out)는 이동의 약 90%를 전방-로드하고 나머지는 느리게 멈춥니다. 요소 진입에 예약하십시오. 느린 정지는 안착으로 읽힙니다. (작업된 예제 인트로에서 클라이언트가 플래그를 지정한 수정 사항이 발생했습니다.)
주의는 스포트라이트이다
어떤 순간에도 정확히 하나의 요소만 완전한 밝기로 유지하십시오. 이미 그려진 다른 모든 것은 조용하지만 읽을 수 있는 상태로 유지됩니다. 선택 사항이 아닙니다. 이 규칙은 세계가 수십 개의 요소로 축적되면서도 결코 복잡해 보이지 않게 하며, 풀백을 압도적이지 않고 읽을 수 있게 만듭니다.
계층 구조는 모든 것을 어둡게 만드는 것이 아니라 활성(active)과 조용(quiet) 상태 간의 비율에서 비롯됩니다. 참조 빌드의 첫 번째 프로토타입은 가장 밝은 픽셀이 101/255였고 960x540에서 읽을 수 없었습니다. 해결책은 더 어두운 잉크가 아닌 더 밝은 잉크였습니다.
| 상태 | 목표 휘도 (Y, 16-235) | 참조에서의 불투명도 |
|---|---|---|
| 활성 선 + 레이블 | 200-235 | 1.0 |
| 컨텍스트, 그려졌고 여전히 관련 있음 | 120-150 | 0.56 |
| 소진됨, 할 말을 다함 | 85-105 | 0.33 |
| 모든 레이블, 모든 상태 | 90 미만 안 됨 |
구현은 모든 내레이션 비트마다 논의 중인 ID와 함께 호출되는 하나의 함수입니다 (build_s01.py, lit()):
def lit(t, active, warm=(), dur=0.5, floor=FLOOR):
active = list(active) + [g + "-l" for g in active if g + "-l" in order]
for gid in order:
if gid not in opac: # 한 번도 그려지지 않음: 조명할 것 없음
continue
tgt = 1.0 if gid in active else (WARM if gid in warm else floor)
if gid not in active:
tgt = min(tgt, MUTED.get(gid, 1.0))
...
거기에는 세 가지 중요한 세부 사항이 있습니다:
- 레이블은 항상 해당 요소의 상태를 상속받습니다 (
-l접미사 포함). 조명된 요소 아래에 읽을 수 없는 레이블이 있는 것이 바로 수정하려는 정확한 결함입니다. - 완료된 소품은 불투명도 0으로 은퇴합니다.
MUTED상한을 통해, 0.3이 아닙니다. 0.3으로 음소거하면 섹션의 나머지 부분 동안 설명되지 않은 색종이가 화면에 남습니다. 생성기 규칙:mute()를 이후에 시작하는lit()앞에 내보내십시오. 그렇지 않으면 트윈이 완료될 때 음소거가 덮어씌워집니다. - 불투명도 이벤트는 타임라인 순서대로 내보내져야 합니다. 그렇지 않으면 트래커가 오래된 상태를 보고 잘못된 대상을 계산합니다. 순서가 잘못된 경우 예외를 발생시키는
seq()가드를 유지하십시오. - 창당 요소당 하나의 불투명도 권한. 동일한 요소의 불투명도를 다른 값으로 구동하는 두 개의 동시 활성 트윈은 독립형 섹션에서는 부드럽게 렌더링되지만, 조립된 마스터에서는 약 10Hz로 깜빡입니다. 승리하는 트윈이 프레임마다 교대하기 때문입니다. 참조 빌드는 모든 도크에서 이 결함을 출하했습니다.
lit()과 같은 스윕이 명시적 밝게 하기 또는 음소거와 겹칠 때, 이후에 시작하는 트윈이 유일한 드라이버가 되고 스윕은 해당 ID를 건너뜁니다 (lit(..., skip=(...))). 게이트하십시오: 모든 전환 창에서 1프레임 앞뒤 휘도 팝을 검사하기 위해 조립된 렌더를 스캔하십시오 (참조 빌드의qa/v4/flicker/qa-flicker.mjs).
열린 루프는 공간적이다
'나중에 다시 다루겠습니다'라고 말하지 마십시오. 세계에 시각적으로 불완전한 것을 남겨두고 그것으로 돌아오십시오. 시청자가 볼 수 있는 약속은 그들이 느낄 수 있는 미해결 약속입니다.
메커니즘은 모양에 관계없이 동일합니다:
- 후크(hook)에 심습니다. 공간에, 약속을 하는 라인에 심습니다.
- 모든 경계에서 다시 보여줍니다. 모든 섹션 핸드오프는 경계입니다. 다시 보여주는 데는 약 2초가 걸리며 유지 메커니즘입니다. 건너뛰는 것이 결실이 아무것도 결실을 맺지 못하게 하는 방법입니다.
- 시각적으로 진행시킵니다. 시청자는 불완전함이 줄어드는 것을 볼 수 있어야 합니다.
- 열었던 이미지로 닫습니다.
대본에서 모양을 선택하십시오:
| 대본 모양 | 세계 | 불완전한 것 |
|---|---|---|
| N개의 병렬 항목 | 척추에 N개의 소켓 | 빈 슬롯 (reference/patterns/wall-of-slots/ 참조) |
| 하나의 깊은 프로세스 | 전체 파이프라인, 배치됨 | 깨지거나 누락된 링크 |
| 레벨 또는 계층 | 위쪽으로 쌓이는 스택 | 스택의 상단은 유령 |
| 비교 | 하나의 공유 축에 두 개의 열 | 하나의 열이 비어 있거나, 채워지지 않은 점수판 |
| 뉴스 또는 발표 | 타임라인 또는 풍경 지도 | 오른쪽, 미래, 비어 있음 |
| 튜토리얼 또는 함께 만들기 | 완성된 아키텍처, 흐릿하게 표시됨 | 아직 구축되지 않은 모든 노드 |
항목을 해당 슬롯에 전달하는 것은 약 1.4초의 실시간 카메라 이동이지, 채워진 상태의 미리 만들어진 그림으로 컷하는 것이 아닙니다. 시청자는 방금 배운 것이 타일이 되는 것을 지켜봅니다. 비디오에 숫자나 카운터가 있으면, 같은 이동 안에서 주행 거리계처럼 굴리십시오. 두 숫자 모두 동일한 시작, 지속 시간 및 이즈를 사용하거나 중간 롤에서 하나의 밴드로 합쳐집니다.
카운터에는 숫자뿐만 아니라 이름이 필요합니다. 모서리 숫자는 시청자에게 순서상의 위치를 알려주지만 현재 항목이 무엇인지는 알려주지 않습니다. 9분이 지나면 '03'은 아무것도 전달하지 않습니다. 숫자를 현재 항목의 이름을 지정하는 1-2 단어 레이블(SUPPORT, VOICE AI)과 쌍으로 만드십시오. 같은 플레이트 화학으로, 숫자와 하나의 강체 고정물처럼 움직이며, 같은 주행 거리계 롤 안에서 교체하십시오. 참조 빌드의 클라이언트 검토에서 정확히 이것을 요청했습니다: 시각적으로는 좋았지만 시청자는 어떤 사용 사례가 화면에 있는지 계속 잃어버렸습니다.
2 · 규율
단어를 얻지 못하면 그려지지 않는다
모든 모양은 레이블이 지정된 요소, 레이블이 지정된 요소 간의 연결자, 이동하는 주제 또는 주변 배경입니다. 그 외에는 없습니다.
이것은 이해도 7/10을 기록하고 원인을 명명한 음소거 테스트 검토에서 비롯되었습니다: 다이어그램은 깨끗했지만 장식은 그렇지 않았습니다. 의미 있는 것과 같은 두께와 팔레트로 그려진 수십 개의 레이블이 없는 모양들로, 처음 보는 시청자는 신호와 질감을 구분할 수 없고 결코 해독되도록 의도되지 않은 것들을 해독하는 데 실제 주의를 소비합니다. 이것이 단어에서 모양으로 옮겨진 '너무 많은 정보'입니다.
예산: 섹션당 약 20개의 화면상 단어. 문장 없음. 레이블은 1-2 단어이며 해당 요소 아래에 있습니다. 참조 섹션 1은 84초에 21단어입니다.
결론: 안티패턴 시각물은 추천 사항 위에 절대 오버레이하지 않습니다. 먼저 세계를 거의 검은색으로 만들거나 좋은 다이어그램이 없는 곳에 반례를 배치하십시오.
시청자에게 따라갈 하나의 대상을 주십시오
상태가 눈에 띄게 변하는 단일 이동 주제에 이야기를 담으십시오: 데이터 행과 점수 막대가 있는 칩, 문서, 요청. 행이 채워지고, 막대가 움직이며, 테두리 색상이 변경됩니다. 시청자는 그 하나의 대상을 보면서 전체 섹션을 따라갈 수 있어야 하며, 절대 순간이동해서는 안 됩니다. 그려진 연결선을 따라 일정한 속도로 이동합니다.
하나의 전역 토큰 집합
전체 세부 사항은 reference/design-system.md에 있습니다.
| 토큰 | 값 |
|---|---|
| 선 두께 | 1.5 / 2.5 / 4 / 7, 그 외에는 없음 |
| 글꼴 크기 | 22 / 30 / 42 / 60 / 84 |
| 둥글기 | 10 / 22 / 40, 항상 superellipse(2) |
다섯 가지 색상, 다섯 가지 고정된 의미, 장식 제로. 따뜻함은 인간이 관련되어 있음을 의미하며 다른 어떤 것도 결코 따뜻하지 않습니다. 글꼴에 순수한 흰색은 절대 사용하지 마십시오. 어두운 배경에서 눈부심이 발생합니다.
이것이 방지하는 실패는 첫 번째 빌드의 장인 검토에서 비롯되었습니다: '모든 결정은 지역적으로 올바르게 내려졌습니다. 전역적으로 내려진 결정은 없었습니다.' 18개의 선 두께와 9개의 글꼴 크기, 대부분이 0.2 차이로 개별적으로는 보이지 않지만 집합적으로는 치명적이었습니다. 눈은 계층 구조 대신 노이즈를 얻습니다. 빌드를 실패시키는 토큰 린터로 게이트하십시오.
모션
진입은 cubic-bezier(0.16,1,0.3,1), 종료는 진입보다 빠르게, 지속 시간은 질량에 따라 다양화하여 290px 노드와 40px 레이블이 동일하게 감속하지 않도록 하고, back.out은 섹션당 정확히 한 번, 그럴 자격이 있는 비트에 사용합니다.
크로스페이드는 절대 사용하지 마십시오. 전체 블리드 레이어는 이미 불투명한 배경 위에서 클립으로 진입 및 종료합니다. 어떤 순간에도 픽셀은 그래픽이거나 푸티지입니다.
3 · 빌드 계약
- 섹션당 하나의 생성기.
scripts/build_<id>.py는compositions/<id>.html만 씁니다. 생성기를 편집하고, 생성된 HTML은 절대 편집하지 마십시오. 섹션 루트index-*.html은 수동으로 유지 관리되므로 프레이밍 변경은 거기서 이루어집니다. - 공유 모듈은 공유 상태로 유지됩니다. 공유 지오메트리를 정의하는 모든 것은 모든 섹션에서 가져옵니다. 섹션이 병렬 에이전트에 의해 빌드되는 경우, 공유 모듈을 건드리는 것을 금지하십시오. 분기된 지오메트리는 모든 핸드오프를 자동으로 중단시킵니다.
- 조립 전에 SVG defs에 네임스페이스를 지정하십시오. 각 섹션은 자체
gEdge,shadow,edgeFade를 정의합니다. 하나의 조립된 DOM에서url(#id)는 문서 순서의 첫 번째 일치 항목으로 확인되므로, 이전 구성이 마운트 해제되면 이후의 모든 그래픽은 아무것도 그리지 않습니다. 참조 빌드에서 비용: 모든 게이트가 녹색인 상태에서 35초 동안 빈 화면. 조립된 렌더를 살펴보는 것만이 이를 발견했습니다. - 모든 것을 단어 수준 대본에서 단어 시작 시간에 맞추십시오. 기준 단어보다 0.15-0.25초 앞서 진입합니다. 섹션을 비트로 균등하게 나누지 마십시오.
- 갭을 감사하십시오. 약 1.5초 이상 아무 일도 일어나지 않는 구간은 죽은 화면입니다. 생성기가 이를 출력하게 하십시오.
- 컷에 여유 공간(air)을 남기십시오. 공격적인 일시 정지 제한은 문장 경계에서 거의 0에 가까운 갭을 생성하여 클라이언트가 '더듬거림'과 점프 컷으로 듣습니다. 화자 자신의 기준에 맞게 교정하십시오: 화자의 중간값보다 약 10배 더 좁은 문장 경계 갭을 플래그 지정하고 (참조 화자의 중간값은 470ms였습니다. 플래그 지정된 접합부는 20-40ms에 있었습니다.), 4-8 프레임의 여유 공간을 삽입하여 수리하십시오. 단어는 절대 건드리지 않습니다. 여유 공간은 트랙의 실제 룸 톤에서 10ms 페이드가 있는 기증자 조각이며,
anullsrc가 아닙니다: -50dBFS 플로어에 대한 디지털 침묵은 가청 드롭아웃입니다. 비디오는 프레임을 유지합니다. 문장 사이에 토크헤드는 거의 정지 상태이며 4-8 프레임의 유지는 보이지 않습니다. 삽입만으로 변경하면 대본이 결정적으로 이동하므로 재전사가 필요하지 않습니다. 삽입의 가장자리는 음성 포락선을 존중해야 합니다: 기증자 톤을 1ms 안에 단어 꼬리에 붙이면 가딩(clicks)이 발생하며, 이는 종종 테스트를 통과하지만 청취 편집 타임라인에서 즉시 나타납니다. 항상 10ms 페이드로 톤의 속도를 늦추고 팝을 위해 리스너로 검증하십시오.