Files
yt-channel-scraper/graphify-out/cache/ast/v0.9.22/285ff3f97a258a1caa08b81e25d78590eb1aace9284a1a69d921f73bf80610b0.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
14 KiB
JSON

{"nodes": [{"id": "d_yt_channel_scraper_src_yt_scraper_config_py", "label": "config.py", "file_type": "code", "source_file": "src/yt_scraper/config.py", "source_location": "L1"}, {"id": "d_yt_channel_scraper_src_yt_scraper_config_delayconfig", "label": "DelayConfig", "file_type": "code", "source_file": "src/yt_scraper/config.py", "source_location": "L11", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_config_ytdlpconfig", "label": "YtDlpConfig", "file_type": "code", "source_file": "src/yt_scraper/config.py", "source_location": "L19", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_config_config", "label": "Config", "file_type": "code", "source_file": "src/yt_scraper/config.py", "source_location": "L25", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_config_config_database_path_resolved", "label": ".database_path_resolved()", "file_type": "code", "source_file": "src/yt_scraper/config.py", "source_location": "L40", "_callable": true}, {"id": "path", "label": "Path", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "D:\\yt-channel-scraper\\src\\yt_scraper\\config.py"}, {"id": "d_yt_channel_scraper_src_yt_scraper_config_config_output_dir_resolved", "label": ".output_dir_resolved()", "file_type": "code", "source_file": "src/yt_scraper/config.py", "source_location": "L44", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_config_config_template_path_resolved", "label": ".template_path_resolved()", "file_type": "code", "source_file": "src/yt_scraper/config.py", "source_location": "L48", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "label": "load_config()", "file_type": "code", "source_file": "src/yt_scraper/config.py", "source_location": "L52", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "label": "_build_config()", "file_type": "code", "source_file": "src/yt_scraper/config.py", "source_location": "L61", "_callable": true}, {"id": "any", "label": "Any", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "D:\\yt-channel-scraper\\src\\yt_scraper\\config.py"}], "edges": [{"source": "d_yt_channel_scraper_src_yt_scraper_config_py", "target": "dataclasses", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L3", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_py", "target": "pathlib", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L4", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_py", "target": "typing", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L5", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_py", "target": "yaml", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L7", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_py", "target": "d_yt_channel_scraper_src_yt_scraper_config_delayconfig", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L11", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_py", "target": "d_yt_channel_scraper_src_yt_scraper_config_ytdlpconfig", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L19", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_py", "target": "d_yt_channel_scraper_src_yt_scraper_config_config", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L25", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_config", "target": "d_yt_channel_scraper_src_yt_scraper_config_config_database_path_resolved", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L40", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_config_database_path_resolved", "target": "path", "relation": "references", "context": "return_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L40", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_config", "target": "d_yt_channel_scraper_src_yt_scraper_config_config_output_dir_resolved", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L44", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_config_output_dir_resolved", "target": "path", "relation": "references", "context": "return_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L44", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_config", "target": "d_yt_channel_scraper_src_yt_scraper_config_config_template_path_resolved", "relation": "method", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L48", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_config_template_path_resolved", "target": "path", "relation": "references", "context": "return_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L48", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_py", "target": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L52", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "target": "path", "relation": "references", "context": "parameter_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L52", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "target": "d_yt_channel_scraper_src_yt_scraper_config_config", "relation": "references", "context": "return_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L52", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_py", "target": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L61", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "target": "any", "relation": "references", "context": "generic_arg", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L61", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "target": "d_yt_channel_scraper_src_yt_scraper_config_config", "relation": "references", "context": "return_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L61", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_config_database_path_resolved", "target": "path", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L41", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_config_output_dir_resolved", "target": "path", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L45", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_config_template_path_resolved", "target": "path", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L49", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "target": "path", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L53", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "target": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L58", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "target": "d_yt_channel_scraper_src_yt_scraper_config_config", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L64", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "target": "d_yt_channel_scraper_src_yt_scraper_config_delayconfig", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L71", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "target": "d_yt_channel_scraper_src_yt_scraper_config_ytdlpconfig", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/config.py", "source_location": "L77", "weight": 1.0}], "raw_calls": [{"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_config_database_path_resolved", "callee": "resolve", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L41", "receiver": null}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_config_output_dir_resolved", "callee": "resolve", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L45", "receiver": null}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_config_template_path_resolved", "callee": "resolve", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L49", "receiver": null}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "callee": "exists", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L54", "receiver": "p"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "callee": "FileNotFoundError", "is_member_call": false, "source_file": "src/yt_scraper/config.py", "source_location": "L55", "receiver": null}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "callee": "safe_load", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L57", "receiver": "yaml"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_load_config", "callee": "f", "is_member_call": false, "indirect": true, "context": "argument", "source_file": "src/yt_scraper/config.py", "source_location": "L57"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L62", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L63", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L65", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L66", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L67", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L68", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L69", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L70", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L72", "receiver": "delay_raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L73", "receiver": "delay_raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L74", "receiver": "delay_raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L75", "receiver": "delay_raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L78", "receiver": "ydl_raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L79", "receiver": "ydl_raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L81", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L82", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L83", "receiver": "raw"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_config_build_config", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/config.py", "source_location": "L84", "receiver": "raw"}]}