- 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.
1 line
19 KiB
JSON
1 line
19 KiB
JSON
{"nodes": [{"id": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "label": "api.py", "file_type": "code", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L1"}, {"id": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "label": "build_router()", "file_type": "code", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L18", "_callable": true}, {"id": "store", "label": "Store", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "D:\\yt-channel-scraper\\src\\yt_scraper\\webapp\\api.py"}, {"id": "config", "label": "Config", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "D:\\yt-channel-scraper\\src\\yt_scraper\\webapp\\api.py"}, {"id": "apirouter", "label": "APIRouter", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "D:\\yt-channel-scraper\\src\\yt_scraper\\webapp\\api.py"}, {"id": "d_yt_channel_scraper_src_yt_scraper_webapp_api_video_dict", "label": "_video_dict()", "file_type": "code", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L410", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_webapp_api_job_dict", "label": "_job_dict()", "file_type": "code", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L428", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_webapp_api_loads", "label": "_loads()", "file_type": "code", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L436", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_webapp_api_handle", "label": "_handle()", "file_type": "code", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L445", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_webapp_api_folder_info", "label": "_folder_info()", "file_type": "code", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L451", "_callable": true}, {"id": "path", "label": "Path", "file_type": "code", "source_file": "", "source_location": "", "origin_file": "D:\\yt-channel-scraper\\src\\yt_scraper\\webapp\\api.py"}, {"id": "d_yt_channel_scraper_src_yt_scraper_webapp_api_safe_dir", "label": "_safe_dir()", "file_type": "code", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L456", "_callable": true}, {"id": "d_yt_channel_scraper_src_yt_scraper_webapp_api_open_in_os", "label": "_open_in_os()", "file_type": "code", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L461", "_callable": true}], "edges": [{"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "json", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L3", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "pathlib", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L4", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "typing", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L5", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "fastapi", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L7", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "fastapi_responses", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L8", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "sse_starlette_sse", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L9", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_init_py", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L11", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_init_py", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L12", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_init_py", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L13", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_config_py", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L14", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_store_py", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L15", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L18", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "target": "store", "relation": "references", "context": "parameter_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L18", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "target": "config", "relation": "references", "context": "parameter_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L18", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "target": "apirouter", "relation": "references", "context": "return_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L18", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_webapp_api_video_dict", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L410", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_webapp_api_job_dict", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L428", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_webapp_api_loads", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L436", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_webapp_api_handle", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L445", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_webapp_api_folder_info", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L451", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_folder_info", "target": "path", "relation": "references", "context": "parameter_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L451", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_webapp_api_safe_dir", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L456", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_py", "target": "d_yt_channel_scraper_src_yt_scraper_webapp_api_open_in_os", "relation": "contains", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L461", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_open_in_os", "target": "path", "relation": "references", "context": "parameter_type", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L461", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "target": "apirouter", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L19", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_job_dict", "target": "d_yt_channel_scraper_src_yt_scraper_webapp_api_loads", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L430", "weight": 1.0}, {"source": "d_yt_channel_scraper_src_yt_scraper_webapp_api_folder_info", "target": "path", "relation": "calls", "context": "call", "confidence": "EXTRACTED", "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L452", "weight": 1.0}], "raw_calls": [{"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L22", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L27", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L31", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "delete", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L42", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L48", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L59", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L66", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L75", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L85", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L99", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L106", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L110", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L117", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "delete", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L137", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L143", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L155", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L186", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "delete", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L191", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L196", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L211", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L235", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L246", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L280", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L290", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L305", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L312", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L322", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L333", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L348", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L360", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "get", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L380", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_build_router", "callee": "post", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L395", "receiver": "r"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_video_dict", "callee": "loads", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L415", "receiver": "_json"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_loads", "callee": "loads", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L440", "receiver": "json"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_handle", "callee": "split", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L447", "receiver": null}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_handle", "callee": "split", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L447", "receiver": "url"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_folder_info", "callee": "resolve", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L453", "receiver": "path"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_folder_info", "callee": "exists", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L453", "receiver": "path"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_safe_dir", "callee": "join", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L457", "receiver": null}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_safe_dir", "callee": "strip", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L458", "receiver": null}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_safe_dir", "callee": "strip", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L458", "receiver": "safe"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_open_in_os", "callee": "startswith", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L467", "receiver": null}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_open_in_os", "callee": "startfile", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L468", "receiver": "os"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_open_in_os", "callee": "Popen", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L470", "receiver": "subprocess"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_open_in_os", "callee": "Popen", "is_member_call": true, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L472", "receiver": "subprocess"}, {"caller_nid": "d_yt_channel_scraper_src_yt_scraper_webapp_api_open_in_os", "callee": "HTTPException", "is_member_call": false, "source_file": "src/yt_scraper/webapp/api.py", "source_location": "L474", "receiver": null}]} |