Files
yt-channel-scraper/graphify-out/cache/ast/v0.9.22/7aa050f1ed896a0e062669f2f287f75ceb7a57b22ddcc5b635bed3d59779b759.json
urieljareth 06497299ab feat: integrated audio player + animated transcript follower
- Video detail (done videos): added 'Download audio' button; removed the
  manual 'Thumbnail' button (thumbnails auto-download now, so it was redundant).
- New 'GET /api/videos/{id}/audio' endpoint (also serves HEAD for probing),
  serving data/audio/<video_id>.mp3. Audio job outtmpl switched to %(id)s so
  files are addressable per video.
- Integrated <audio> player appears in the detail view once the MP3 is present
  (probed via HEAD on openVideo; polled after a download job until ready).
- Synced transcript follower: as audio plays, the matching segment is
  highlighted (seg-active) and auto-scrolled into view like a karaoke/lyrics
  tracker. Clicking any segment timestamp or chapter seeks the audio to that
  point (falls back to scroll when no audio). Playback indicator pulses while
  playing.
2026-07-27 00:00:28 -06:00

1 line
8.5 KiB
JSON

{"nodes": [{"id": "d_yt_channel_scraper_src_yt_scraper_discover_py", "label": "discover.py", "file_type": "code", "source_file": "src/yt_scraper/discover.py", "source_location": "L1"}, {"id": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "label": "discover_channel()", "file_type": "code", "source_file": "src/yt_scraper/discover.py", "source_location": "L13", "_callable": true}, {"id": "videoref", "label": "VideoRef", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "D:\\yt-channel-scraper\\src\\yt_scraper\\discover.py"}, {"id": "d_yt_channel_scraper_src_yt_scraper_discover_flatten_entries", "label": "_flatten_entries()", "file_type": "code", "source_file": "src/yt_scraper/discover.py", "source_location": "L57", "_callable": true}, {"id": "any", "label": "Any", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "D:\\yt-channel-scraper\\src\\yt_scraper\\discover.py"}, {"id": "d_yt_channel_scraper_src_yt_scraper_discover_rationale_14", "label": "Returns (channel_id, channel_name, video_refs).", "file_type": "rationale", "source_file": "src/yt_scraper/discover.py", "source_location": "L14"}], "edges": [{"source": "d_yt_channel_scraper_src_yt_scraper_discover_py", "target": "logging", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L3", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_py", "target": "typing", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L4", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_py", "target": "yt_dlp", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L6", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_py", "target": "d_yt_channel_scraper_src_yt_scraper_store_py", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L8", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_py", "target": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L13", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "target": "videoref", "relation": "references", "context": "generic_arg", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L13", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_py", "target": "d_yt_channel_scraper_src_yt_scraper_discover_flatten_entries", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L57", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_flatten_entries", "target": "any", "relation": "references", "context": "generic_arg", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L57", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_flatten_entries", "target": "any", "relation": "references", "context": "generic_arg", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L57", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "target": "d_yt_channel_scraper_src_yt_scraper_discover_flatten_entries", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L30", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "target": "videoref", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L43", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_discover_rationale_14", "target": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/discover.py", "source_location": "L14", "weight": 1.0}], "raw_calls": [{"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "YoutubeDL", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L24", "receiver": "yt_dlp"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "extract_info", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L25", "receiver": "ydl"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L27", "receiver": "info"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L27", "receiver": "info"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L27", "receiver": "info"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L28", "receiver": "info"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L28", "receiver": "info"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L28", "receiver": "info"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L33", "receiver": "entry"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L36", "receiver": "entry"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L38", "receiver": "entry"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L39", "receiver": "entry"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L40", "receiver": "entry"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L41", "receiver": "entry"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "append", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L42", "receiver": "refs"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_discover_channel", "callee": "info", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L53", "receiver": "log"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_flatten_entries", "callee": "dict", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "src/yt_scraper/discover.py", "source_location": "L64"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_flatten_entries", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L64", "receiver": "entry"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_flatten_entries", "callee": "extend", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L65", "receiver": "out"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_discover_flatten_entries", "callee": "append", "is_member_call": true, "source_file": "src/yt_scraper/discover.py", "source_location": "L67", "receiver": "out"}]}