|
| 1 | +--- |
| 2 | +name: ipynb-youtube-embed |
| 3 | +description: | |
| 4 | + Jupyter 노트북에 YouTube 영상을 임베드하는 스킬. |
| 5 | + Jupyter Book(GitHub Pages)에서 iframe이 올바르게 렌더링되도록 |
| 6 | + 출력(outputs)까지 함께 저장한다. |
| 7 | +
|
| 8 | + 트리거: "유튜브 임베드", "YouTube 임베드", "영상 노트북에 추가", "embed video" |
| 9 | +--- |
| 10 | + |
| 11 | +# ipynb-youtube-embed |
| 12 | + |
| 13 | +Jupyter Book으로 배포되는 `.ipynb`에 YouTube iframe을 삽입하는 워크플로우. |
| 14 | + |
| 15 | +## 핵심 원칙 |
| 16 | + |
| 17 | +Jupyter Book은 노트북을 **실행하지 않고** 저장된 `outputs`를 그대로 렌더링한다. |
| 18 | +따라서 코드 셀을 삽입할 때 `outputs`에 HTML 출력을 **미리 저장**해야 iframe이 표시된다. |
| 19 | +`outputs`가 비어 있으면 코드만 보이고 iframe은 렌더링되지 않는다. |
| 20 | + |
| 21 | +## 삽입 방법 |
| 22 | + |
| 23 | +### 1. YouTube에서 iframe 코드 복사 |
| 24 | + |
| 25 | +YouTube 영상 → 공유 → 퍼가기 → `<iframe ...>` 전체 복사 |
| 26 | + |
| 27 | +### 2. 노트북 JSON에 코드 셀 + 출력 삽입 |
| 28 | + |
| 29 | +```python |
| 30 | +import json |
| 31 | + |
| 32 | +NOTEBOOK = "book/{topic}/{notebook}.ipynb" |
| 33 | +IFRAME = '<iframe width="560" height="315" src="https://www.youtube.com/embed/{VIDEO_ID}" ...></iframe>' |
| 34 | + |
| 35 | +with open(NOTEBOOK) as f: |
| 36 | + nb = json.load(f) |
| 37 | + |
| 38 | +cell = { |
| 39 | + "cell_type": "code", |
| 40 | + "execution_count": 1, |
| 41 | + "metadata": {"tags": ["hide-input"]}, |
| 42 | + "source": [ |
| 43 | + "from IPython.display import HTML\n", |
| 44 | + f"HTML('''{IFRAME}''')" |
| 45 | + ], |
| 46 | + "outputs": [ |
| 47 | + { |
| 48 | + "data": { |
| 49 | + "text/html": [IFRAME], |
| 50 | + "text/plain": ["<IPython.core.display.HTML object>"] |
| 51 | + }, |
| 52 | + "execution_count": 1, |
| 53 | + "metadata": {}, |
| 54 | + "output_type": "execute_result" |
| 55 | + } |
| 56 | + ] |
| 57 | +} |
| 58 | + |
| 59 | +# 제목 셀(Cell 0) 바로 아래 삽입 |
| 60 | +nb['cells'].insert(1, cell) |
| 61 | + |
| 62 | +with open(NOTEBOOK, 'w') as f: |
| 63 | + json.dump(nb, f, ensure_ascii=False, indent=1) |
| 64 | +``` |
| 65 | + |
| 66 | +## 태그 선택 기준 |
| 67 | + |
| 68 | +| 태그 | 효과 | 사용 시점 | |
| 69 | +|------|------|-----------| |
| 70 | +| `hide-input` | 코드 접힘, 출력(iframe)만 표시 | 기본값 — 독자에게 Python 코드가 불필요할 때 | |
| 71 | +| `remove-input` | 코드 완전 제거, 출력만 표시 | 코드 존재 자체를 숨기고 싶을 때 | |
| 72 | +| (없음) | 코드 + 출력 모두 표시 | 코드 노출이 필요할 때 | |
| 73 | + |
| 74 | +## 삽입 위치 기준 |
| 75 | + |
| 76 | +- **제목 바로 아래(Cell 1)**: 영상이 해당 노트북 전체를 커버하는 경우 (기본값) |
| 77 | +- **특정 섹션 아래**: 영상이 특정 개념만 다루는 경우 |
| 78 | + |
| 79 | +## 주의사항 |
| 80 | + |
| 81 | +- `outputs`를 빈 배열로 두면 Jupyter Book에서 iframe이 **절대 렌더링되지 않는다**. |
| 82 | +- `text/html` 값은 반드시 **리스트 형태** (`["<iframe ...>"]`)여야 한다. |
| 83 | +- 언어별 노트북이 분리된 경우(`_ko.ipynb`, `_en.ipynb`), 각각 따로 삽입한다. |
0 commit comments