myspoti
Jetpack Compose로 만든 Spotify 전용 안드로이드 클라이언트
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Created: 12-05-2026 · Last updated: 10-10-2026
Live app → · v1.5.5 · changelog
If the app doesn't reflect the latest version after an update, do a hard refresh to clear the cache: Edge, Firefox, Opera —
Ctrl+F5· Chrome —Ctrl+Shift+R· Safari (Mac) —Cmd+Shift+RorCmd+Option+R
Sanskrit Karaoke turns a Sanskrit śloka into an interactive wave diagram that shows the metrical weight of each syllable (guru / laghu), lets you mark audio timing, and exports karaoke videos or high-resolution images.
node tools/export_captions.mjs <verse.json> [--timing timing.json] writes .srt/.vtt from syllable timing without rendering videoPaste s1 into the first field, s2 into the second. Encoding is auto-detected (Devanagari, IAST, SLP1, etc.).
Anuṣṭubh (8 syllables × 4 pādas) — Bhagavadgītā 2.47
| Field | Text |
|---|---|
| s1 | कर्मण्येवाधिकारस्ते मा फलेषु कदाचन |
| s2 | मा कर्मफलहेतुर्भूर्मा ते सङ्गोऽस्त्वकर्मणि |
Upajāti / Triṣṭubh (11 syllables × 4 pādas) — Kumārasambhava 1.1 (Kālidāsa)
| Field | Text |
|---|---|
| s1 | अस्त्युत्तरस्यां दिशि देवतात्मा हिमालयो नाम नगाधिराजः |
| s2 | पूर्वापरौ तोयनिधी वगाह्य स्थितः पृथिव्या इव मानदण्डः |
Mandākrāntā (17 syllables × 4 pādas) — Meghadūta 1.1 (Kālidāsa)
Each printed line of Meghadūta is one pāda. Concatenate lines 1+2 into s1 and lines 3+4 into s2.
| Field | Text |
|---|---|
| s1 | कश्चित्कान्ताविरहगुरुणा स्वाधिकारात्प्रमत्तः शापेनास्तङ्गमितमहिमा वर्षभोग्येण भर्तुः |
| s2 | यक्षश्चक्रे जनकतनयास्नानपुण्योदकेषु स्निग्धच्छायातरुषु वसतिं रामगिर्याश्रमेषु |
| Key | Action |
|---|---|
← / → | Select previous / next syllable |
Ctrl+← / Ctrl+→ | Shift syllable timing −0.01 s / +0.01 s |
Home | Align syllable to pada start |
Enter | Play current syllable |
Space | Play current syllable and advance |
Ctrl+Space | Play to end of śloka |
Ctrl+Enter | Play to end of pada |
cd SanskritKaraoke
python -m http.server 8000
# open http://localhost:8000
No build step or package manager required.
Student page generation:
python tools/make_student.py
python tools/make_student.py --check
tools/templates/student.html is the source of truth for the deployed student.html.
Syntax check:
node --check src/scripts/app.js
| File | Contents |
|---|---|
index.html | Entire UI — main view + all modals (settings, help, timing editor, Drive picker) |
src/scripts/app.js | Main application logic (~320 KB ES module) — imports the reusable rendering core |
src/core/*.js | Extracted rendering core (translit, layout, svg, compose, karaoke-frame, timing, feed) shared by the app and the headless renderer — see ADR-0001 |
docs/reference/apte_prosody.html | Apte prosody reference database |
ARCHITECTURE.md | Current + target architecture, phase by phase |
The project includes a server-side Teaching Pipeline built on LangGraph 1.0 and Pydantic, designed to automate verse curation and student analysis.
A Golden Dataset of 8 test cases (including edge cases like duplicate IDs and IAST script validation) is maintained in evals/golden/. The evals/judge.py harness scores the pipeline's output against expected criteria using an LLM judge with a provider-preference chain (Anthropic → OpenRouter → Gemini), ensuring no regressions in the automated content enrichment logic.
The browser app has no dependencies beyond the browser itself and mp4-muxer (bundled). app.js is an ES module that imports the shared src/core/* rendering modules; see CLAUDE.md for the internal function map.
The 2026 layer: a single batch recording of a whole chapter becomes a set of publish-ready vertical karaoke videos with a funnel to the paid course. Roles and step-by-step workflows are in docs/USE_CASES.md.
python tools/build_chapter.py <audio_dir> — auto-timing
(align_chapter.py) → feed_v1 render (vertical 9:16 MP4 @ 30 fps + .srt/.vtt,
render_chapter.js via Puppeteer) → post-kit with per-platform UTM CTAs (post_kit.py).
Run npm install --prefix tools once; --dry-run prints the plan without executing.feed_v1 template (src/core/feed.js): a dark vertical frame — ॐ + title + meter
(hook), Devanagari with a per-syllable IAST karaoke-fill on the active syllable, a
progress bar, and a CTA end-card with the translation and link in the final seconds.validate_library.py and post_kit.py refuse to publish
anything not cleared (see the "Rights Manager" role in the use cases).python tools/schedule_drops.py --config schedule.yaml builds
the posting plan from a cadence file; add --live to post via the publishers for
Telegram, VK, Facebook, Instagram, and WordPress — each fires only where that
platform's env-var credentials are set (see docs/USE_CASES.md
Appendix D). Telegram needs just a BotFather token; nothing is sent without --live + creds.At a glance:
audio_dir/<id>.m4a ─▶ align_chapter.py ─▶ render_chapter.js ─▶ post_kit.py ─▶ schedule_drops.py
(one recording) timing → JSON feed_v1 MP4+subs captions+UTM posting plan
→ dist/ → drop/<ch>/<id>/ → drop/schedule_plan.json
A full command reference, the first-drop checklist, and a glossary are in docs/USE_CASES.md (Appendices A–C).
The project is evolving from a teacher-facing authoring tool into a full Sanskrit edutech platform for Russian and English students — covering prosody literacy, pronunciation, and memorisation. Content is delivered via Telegram stories, the web app, course platforms, and YouTube.
Zoomed portrait video (9:16 or 1:1) where the camera follows the active syllable dot, keeping 2–4 syllables in frame with a smooth pan. Format and syllable-count selectors in the sidebar. Audio embedded, 24 fps.
A structured file-based catalogue (verses/data/*.json) with metadata per verse: source, meter, difficulty, translations (RU/EN), Drive links for audio and session. Includes a JSON Schema, validation script, and auto-generated index. The data layer everything else builds on.
A separate read-only page (student.html?id=…) that loads a verse from the catalogue, renders the wave diagram, and plays the karaoke — without any authoring controls. Students land here from Telegram or course links. Record-and-score (✓ shipped 10-10-2026): a «🎙 Записать себя» button records the student's take, POSTs it to the grading endpoint (https://samskrte.ru/sk-grade/api/grade, served by tools/serve_grade.py), and overlays the result on the wave diagram — per-syllable heat rings, a rhythm score, and three drill hints for the weakest syllables; only sounded syllables are graded.
A "Mode" cycling button on the student player: Full (all labels) → Dots only (circles, no text) → Blind (audio only, highlight dot). Applies spaced challenge to memorisation practice.
A globe button in the header switches the entire UI between Russian and English. Strings extracted to src/scripts/strings.js; DOM elements tagged with data-i18n.
After playing a verse, students rate recall (😊 😐 😕). SM-2 scheduling resurfaces verses at optimal intervals. State stored in localStorage; a "Study today" queue shows what's due.
Three rotating quiz types after a verse plays: tap guru/laghu (beat tap), identify the meter (multiple choice), fill in a hidden syllable before the karaoke reaches it.
Daily streak, "verses mastered" count (SRS interval ≥ 21 days), and a progress page listing all catalogue verses with status chips (New / Learning / Mastered).
✅ Done 26-08-2026 (commit 0e2f6a4): the tapping block is restored under the Timing Editor button — rate select, «⏺ Тэппинг», reset, and the play/stop pair, with i18n keys in ru+en.
✅ Fixed 26-08-2026 (commit 0e2f6a4): saving a session now looks up every same-name file in the target folder (not just the picker-selected one), uploads the replacement first, then deletes the stale copies; failed deletes surface a visible warning instead of being swallowed.
Complete the meter cross-check modal that compares the detected meter against the full Apte database and highlights discrepancies.
Complete overhaul of the student view for mobile devices. Sticky bottom bar, collapsible translations, and touch-friendly quiz buttons.
Full integration with the Telegram Web App SDK. Dark mode synchronization, native back button support, and automatic expansion.
LLM cost logging (llm_costs.jsonl), a cost dashboard, student-session telemetry, and local caching (Drive Fallback).
Firebase Auth (Google) + Firestore for cross-device sync of student progress (SRS) and telemetry. See docs/FIREBASE_ACCEPTANCE.md for the remaining live acceptance steps.
Detailed workflows for both audiences — maintainers (developers, drop producers, the rights manager, curators) and end-users (viewers, students, content creators, offline practitioners) — are documented in docs/USE_CASES.md.
Maintainers:
src/core/* modules, the headless render.html.build_chapter.py — chapter → videos → posts in one command.End-users:
feed_v1 UTM funnel to the course.Sanskrit Karaoke is one repo in a ~85-repo Sanskrit-lexicon workspace. This section is the one-click map out of it — read it before building anything here that another repo may already own.
What this repo produces that other repos consume
| Asset | Who consumes it |
|---|---|
tools/export_captions.mjs — verse-timing JSON → SRT/VTT captions | Registered as shared-code family 28: the canonical caption emitter for any repo showing timed Sanskrit verse. Import exportCaptions(verse, timing) or run the CLI; do not write a second SRT/VTT emitter. |
verses/data/*.json — verse records with metre, timing, rights and word-aligned RU glosses | The player, the student build, and the drop pipeline; rv_verse_seeds.json is a seed/lookup table joined against the Rigveda metrical data, not a karaoke verse record. |
What this repo consumes from elsewhere — RU word-glosses are baked in by
tools/build_glosses.py
from the 1.09 M-row Sa→Ru corpus alignment lexicon owned by
SanskritLexicography/RussianTranslation.
Query that lexicon; never re-align or re-translate here.
Where to record a gotcha you find here — infra and process go to Uprava/FINDINGS.md; anything about Sanskrit data, encodings or transliteration goes to SanskritLexicography/FINDINGS.md. This repo deliberately keeps no registries of its own.
The four hubs, one click each
Org-wide conventions live in the spine CLAUDE.md; encodings and corpus traps in the Sanskrit context primer.
Apache 2.0 — see LICENSE.
Dr. Mārcis Gasūns