Spaces:
Sleeping
Sleeping
File size: 6,324 Bytes
2931418 f6a6455 01abd01 f6a6455 401a193 f6a6455 dc57844 29c4ada e935ba7 29c4ada dc57844 f6a6455 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | ---
title: TutorialMaker
emoji: π»
colorFrom: indigo
colorTo: purple
sdk: gradio
sdk_version: 6.19.0
python_version: '3.13'
app_file: app.py
pinned: false
license: mit
short_description: Make Tutorials from YouTube Videos
---
# YouTube β Tutorial Post Generator
Give a **topic** and your **Hugging Face token**, and this Space builds a downloadable
**`.docx` tutorial** (text + AI-captioned screenshots) from the single best YouTube video
on that topic.
## Pipeline
1. **Search** β top 5 videos via the [`adarshajay/youtube-search`](https://huggingface.co/spaces/adarshajay/youtube-search) Space.
2. **Sentiment rank** β fetch top comments per video with `yt-dlp` and score them with the
BERT classifier [`OmarMedhat7/youtube-sentiment-analysis-model`](https://huggingface.co/OmarMedhat7/youtube-sentiment-analysis-model);
the video with the highest positive share wins.
3. **Download** the winner with `yt-dlp` and extract audio with `ffmpeg`.
4. **Transcribe** locally with `faster-whisper` (segment timestamps).
5. **Candidate frames** are extracted densely from the video, then the **video is
auto-deleted** β only small JPEGs and the transcript remain.
6. **Tutorial text** β `deepseek-ai/DeepSeek-V3` (HF Inference Providers, billed to your
token) turns the transcript into an **answer-engine-optimized** post: an answer-first
paragraph, H2 step headings, an FAQ, a meta description, a URL slug, and a
last-updated/source citation. Optional **primary/secondary keyword** placement (primary
~3Γ + in title/slug/meta/intro/H2; each secondary once).
7. **Screenshot selection** β a weighted indicator blends each step's LLM-suggested
timestamp with Whisper's actual speech timing.
8. **Captions** β a vision model (default `Qwen/Qwen2.5-VL-72B-Instruct`, billed to your
token) captions each screenshot.
9. **Assemble** the `.docx` for download.
## Notes
- **Your HF token is used only for the LLM and vision-model calls** and is billed to your
account. Create a fine-grained token with *"Make calls to Inference Providers"* at
<https://huggingface.co/settings/tokens>.
- **Free CPU tier:** Whisper runs on CPU, so transcription is slow β keep videos short
(default cap ~20 min).
- **YouTube usually blocks the Space's datacenter IP.** Each visitor can supply their own
access in the **"YouTube access β cookies / proxy"** panel (used only for that run, then
deleted):
- **Cookies:** a `youtube.com` cookies.txt (Netscape format, raw or base64) exported
from a **throwaway** Google account.
- **Proxy:** a **residential** proxy URL. **Free *datacenter* proxies (e.g. Webshare's
free tier) usually do *not* bypass YouTube's block** and have tight bandwidth caps.
- An operator can set shared defaults via the `YT_COOKIES` / `YT_PROXY` Space secrets.
- A hosted Space **cannot** open or read a visitor's browser β auth must be supplied
explicitly.
## PO token guide (free, no proxy)
YouTube increasingly requires a **Proof-of-Origin (PO) token** to serve video from
datacenter IPs. A matching **PO token + visitor data** pair can get the Space past the
"Sign in to confirm you're not a bot" wall **without any proxy** β and it's free. It's
fiddly to extract by hand and the tokens expire (hours), so re-do this when downloads
start failing.
Paste the values into the app's **"YouTube access β cookies / proxy"** panel:
**PO token** field and **Visitor data** field.
### Easiest: the PO Token Grabber extension (one click)
This repo ships a tiny Chrome/Edge extension in [`extension/`](extension/) that reads the
PO token + visitor data for you. Grab it with the **β¬οΈ Download the PO Token Grabber
extension (.zip)** button in the app's *YouTube access* panel (or from
[`extension/`](extension/)), unzip it, and load it unpacked (`chrome://extensions` β
Developer mode β Load unpacked). Open a YouTube video and press play, then click the
extension **while on the YouTube tab** to capture the values. Open this Space in another
tab and hit **‡ Fill the Space tab** to inject them straight into the fields below (or use
the Copy buttons and paste). See
[`extension/README.md`](extension/README.md). (It's unpublished/sideloaded and may need
updates when YouTube changes; the manual steps below always work as a fallback.)
### Get them manually (web client, ~2 min)
1. Open a fresh **Incognito** window and go to <https://www.youtube.com> (a throwaway
logged-in account is fine; if you log in, also export that session's cookies).
2. Open **DevTools β Network** (F12), then **play any video**.
3. **Visitor data:** filter Network for `v1/player`, open the request to
`youtubei/v1/player`, and in the **Request payload** copy
`context.client.visitorData` (a string ending in `%3D%3D`). Paste it into the
**Visitor data** field.
4. **PO token (gvs):** filter Network for `googlevideo.com`, open a `videoplayback`
request, and copy the value of its **`pot`** query parameter. In the **PO token**
field enter it prefixed with the client + context:
```
web.gvs+<pot-value>
```
You can supply more than one, comma-separated, e.g.
`web.gvs+<gvs-pot>, web.player+<player-pot>` (the player PO token comes from the
`v1/player` request's response, field `...poToken`).
5. Run the Space. When a PO token is present it automatically uses the **web** player
client so the token applies.
**Tips**
- The PO token is bound to the **visitor data** (and cookies) it was made with β always
submit them together, from the same session.
- Prefer using the **same Incognito session** for cookies + visitor data + PO token.
- Tokens are short-lived; refresh when you next get blocked.
### Automated / operator option
yt-dlp can auto-generate PO tokens via the
[`bgutil-ytdlp-pot-provider`](https://github.com/Brainicism/bgutil-ytdlp-pot-provider)
plugin, but that needs a small provider server running alongside yt-dlp β not bundled in
this hosted Space. A self-hosting operator can run it and set shared defaults via the
`YT_POT` / `YT_VISITOR_DATA` Space secrets.
See the authoritative, up-to-date method in the
[yt-dlp PO Token Guide](https://github.com/yt-dlp/yt-dlp/wiki/PO-Token-Guide).
## Local run
```bash
pip install -r requirements.txt # needs ffmpeg on PATH
python app.py
```
|