[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80636":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":13,"contributorsCount":13,"subscribersCount":13,"size":13,"stars1d":13,"stars7d":14,"stars30d":15,"stars90d":13,"forks30d":13,"starsTrendScore":13,"compositeScore":16,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":17,"fork":17,"defaultBranch":18,"hasWiki":19,"hasPages":17,"topics":20,"createdAt":10,"pushedAt":10,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":13,"starSnapshotCount":13,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},80636,"Nyrima","EndlessMelody\u002FNyrima","EndlessMelody","A sleek Google Drive cinema player for private movie libraries.","https:\u002F\u002Fnyrima.pldkhoa.io.vn\u002F",null,"TypeScript",66,0,1,15,39,false,"main",true,[21,22,23,24],"chrome-extension","cinema-platform","once-ui","subtitles","2026-06-12 04:01:29","\u003Cdiv align=\"center\">\n\n\u003Cimg src=\"public\u002Ficons\u002Fapp-icon.png\" width=\"120\" alt=\"Nyrima logo\" \u002F>\n\n# Nyrima\n\n### Personal Video Cinema on Google Drive\n\n*Turn a Drive folder you can access into a private Chrome-extension cinema:\noriginal media bytes, folder-owned artwork, rich subtitles, and no Nyrima\nbackend.*\n\n[![Built with React](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FBuilt%20with-React%2018-61DAFB?logo=react&logoColor=white&style=flat-square)](https:\u002F\u002Freact.dev)\n[![TypeScript](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FTypeScript-5.6-3178C6?logo=typescript&logoColor=white&style=flat-square)](https:\u002F\u002Fwww.typescriptlang.org)\n[![Vite](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FBundler-Vite%206-646CFF?logo=vite&logoColor=white&style=flat-square)](https:\u002F\u002Fvite.dev)\n[![Manifest V3](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FChrome%20Extension-MV3-4285F4?logo=googlechrome&logoColor=white&style=flat-square)](https:\u002F\u002Fdeveloper.chrome.com\u002Fdocs\u002Fextensions)\n[![License](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-22C55E?style=flat-square)](#license)\n[![Tests](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FVitest-112%20passing-86EFAC?logo=vitest&logoColor=white&style=flat-square)](#testing)\n\n[Documentation](.\u002Fdocs\u002Findex.md) | [How It Works](.\u002Fdocs\u002Fhow-nyrima-works.md) |\n[Architecture](.\u002Fdocs\u002Farchitecture.md) | [OAuth Setup](.\u002Fdocs\u002Foauth-setup.md) |\n[Privacy Policy](.\u002Fdocs\u002Fprivacy-policy.md) |\n[Report an issue](https:\u002F\u002Fgithub.com\u002FEndlessMelody\u002FNyrima\u002Fissues)\n\n\u003C\u002Fdiv>\n\n---\n\n## What Nyrima Is\n\nNyrima is a Chrome Manifest V3 extension for watching personal video\nlibraries stored in Google Drive. You pair one Drive folder as the Nyrima\nroot, and each child folder becomes a library in the lobby. Nyrima finds\nvideos, sibling subtitles, and artwork files you place in those folders,\nthen plays the media inside an extension page.\n\nNyrima is not a hosted video service. The current app has no Nyrima backend,\ntranscoding server, analytics endpoint, or ad network. Media stays in Drive\nand streams from Google Drive APIs to the browser when the user opens it.\n\n## How It Works\n\n1. The extension page lists folders and files from Google Drive using either a\n   user-provided Drive API key for public files or a user-provided Google\n   OAuth client for signed-in Drive access.\n2. The lobby turns child folders under the paired root into libraries with\n   poster art from files such as `Poster.jpg` and `Backdrop.webp`.\n3. The player prefers browser-native playback. For MKV files that need help,\n   Nyrima can Range-fetch Drive bytes, remux supported streams to fragmented\n   MP4 through Media Source Extensions, and render ASS subtitles with JASSUB.\n4. Settings, watch progress, recent folders, credential values, and caches are\n   stored locally in extension storage or IndexedDB. OAuth access tokens are\n   mediated by the background service worker.\n5. Sharing is optional. When the user publishes a Drive-created `Shared\u002F`\n   folder, followers can read share metadata from Drive, comment through their\n   own Drive comment stream, and import accessible targets into their own\n   Drive with Drive server-side copy operations.\n\nFor the plain-language version of the full data flow, see\n[`docs\u002Fhow-nyrima-works.md`](.\u002Fdocs\u002Fhow-nyrima-works.md). For implementation\nboundaries and storage details, see\n[`docs\u002Farchitecture.md`](.\u002Fdocs\u002Farchitecture.md).\n\n## Current Features\n\n### Library\n\n- Pair one Google Drive root folder; each direct child folder becomes a\n  library tile.\n- Browse a cinematic lobby with recent libraries, pinned items, Continue\n  Watching, stats, library search, filters, sort order, grouped seasons, grid\n  mode, and list mode.\n- Use folder-owned artwork: `Poster.{jpg,png,webp}` and optional\n  `Backdrop.*` inside Drive folders. Nyrima does not fetch poster metadata\n  from a third-party media database.\n- Parse episode-style filenames and season folders for show grouping while\n  still supporting movie folders.\n\n### Player\n\n- Play Drive media from the extension player with resume state, next-up\n  autoplay, theatre mode, shortcuts, subtitle settings, audio-track controls,\n  and a custom HUD.\n- Prefer direct browser playback, then use the current MKV remux path for\n  supported MKV video\u002Faudio combinations that need MSE.\n- Support supported external sibling subtitles including SRT, VTT, ASS, and\n  SSA, plus supported embedded MKV text subtitles.\n- Render ASS\u002FSSA typesetting through JASSUB\u002Flibass where the current subtitle\n  path supports it.\n\n### Sharing\n\n- Create an app-owned Drive `Shared\u002F` folder with `index.json` share metadata\n  and `comments.jsonl` outbound comments.\n- Publish that folder only when the user opts into \"Anyone with the link\"\n  read access.\n- Follow another user's published `Shared\u002F` folder URL and sync entries into\n  an Inbox.\n- Import accessible shared videos or folders into\n  `Nyrima\u002FImports\u002F\u003Cshare title - timestamp>\u002F` with Drive copy APIs.\n\n## Access Modes\n\nNyrima has two current Google Drive access modes:\n\n| Mode | Best for | Notes |\n| --- | --- | --- |\n| Drive API key | Public \"Anyone with the link\" Drive media | The user creates and stores the key locally. Public Drive quotas and file privacy still apply. |\n| BYOK OAuth client ID | Private Drive folders, profile-backed sharing, Drive writes, and more reliable signed-in access | The user creates a Google Cloud OAuth client for the extension ID and pastes the client ID into Nyrima. |\n\nThe OAuth flow is current BYOK behavior. Nyrima uses\n`chrome.identity.launchWebAuthFlow` from the background service worker; it\ndoes not require editing an `oauth2` block into the manifest. Follow\n[`docs\u002Foauth-setup.md`](.\u002Fdocs\u002Foauth-setup.md) for development and tester\nsetup.\n\n## Quick Start\n\n### Build the unpacked extension\n\n```bash\nnpm install\nnpm run build\n```\n\n1. Open `chrome:\u002F\u002Fextensions`.\n2. Enable **Developer mode**.\n3. Click **Load unpacked** and choose `dist\u002F`.\n4. Open Nyrima from the toolbar popup or the app tab.\n\n### Prepare a first library\n\n1. Create or choose a Google Drive folder to be the Nyrima root.\n2. Put one child folder inside it for a movie or show.\n3. Put videos inside that child folder.\n4. Optionally add `Poster.jpg`, `Backdrop.webp`, and subtitle files with a\n   matching basename such as `Episode 01.mkv` and `Episode 01.en.ass`.\n5. Pair the root folder in Nyrima and configure access.\n\nFor the full first-run path, see\n[`docs\u002Fgetting-started.md`](.\u002Fdocs\u002Fgetting-started.md).\n\n## Development\n\n```bash\nnpm install\nnpm run dev\n```\n\n| Command | Purpose |\n| --- | --- |\n| `npm run dev` | Start Vite extension development output. |\n| `npm run build` | Type-check and write the production extension to `dist\u002F`. |\n| `npm run typecheck` | Run the TypeScript check without writing a build. |\n| `npm test` | Run the full Vitest suite once. |\n| `npm run test:watch` | Keep Vitest running while editing. |\n| `npm run check` | Type-check, test, and verify local Markdown links. |\n| `npm run docs:check` | Check local links in README, docs, phases, and `.claude` Markdown. |\n| `npm run probe:mkv -- \"\u003Cfile.mkv>\"` | Inspect MKV tracks, first audio blocks, and Nyrima audio-switch diagnostics. |\n\nLoad `dist\u002F` unpacked after a production build when checking extension\npermissions, OAuth extension ID behavior, and Chrome loading errors.\n\n### Release scripts\n\n| Command | Purpose |\n| --- | --- |\n| `npm run inspect:manifest` | Print the generated manifest entry points, permissions, hosts, and icons from `dist\u002F`. |\n| `npm run verify:extension` | Validate the generated manifest and required extension files in `dist\u002F`. |\n| `npm run release:check` | Build, test, check docs links, and verify generated extension output. |\n| `npm run package` | Build, verify, and write `dist-zip\u002Fnyrima-\u003Cversion>.zip` with a SHA-256 report. |\n| `npm run package:dist` | Package an already-built and verified `dist\u002F` tree. |\n| `npm run zip` | Compatibility alias for packaging the current `dist\u002F` tree as a real ZIP. |\n\n## Tech Stack\n\n| Layer | Current stack |\n| --- | --- |\n| Extension build | Chrome Manifest V3, Vite 6, `@crxjs\u002Fvite-plugin` |\n| UI runtime | React 18, TypeScript 5.6, hash routing with React Router |\n| UI system | Once UI token CSS and React contexts, Nyrima Sass surfaces, custom font assets |\n| Local state | Zustand, `chrome.storage`, IndexedDB caches |\n| Drive\u002Fmedia | Google Drive REST APIs, Media Source Extensions, EBML\u002FMKV services, Mediabunny AC-3 support |\n| Subtitles | JASSUB\u002Flibass plus Nyrima subtitle parsing\u002Fextraction |\n| Verification | Vitest, TypeScript build checks, Chrome unpacked-extension checks |\n\n## Public Promo Site\n\nNyrima also has a separate public promo website. That site is the public\ndistribution and information surface for the package upload\u002Fdownload path,\ninstallation help, product Q&A\u002FFAQ, privacy policy, terms, support\u002Fcontact,\nand reviewer\u002Fstore-facing links.\n\nThe promo site is separate from the extension runtime. Public copy there should\nmatch the currently packaged extension and the policy\u002Fdocs in this repository.\n\n## Testing\n\n```bash\nnpm test\n```\n\nThe current Vitest suite covers title parsing, subtitles, sharing stores,\nDrive import helpers, EBML\u002Fremux logic, AC-3 playback helpers, fragmented MP4\ngeneration, MSE controller behavior, and the Node release-script toolkit.\nBrowser extension integration, Google OAuth consent, real Drive permissions,\nand media playback against real files still need manual verification in Chrome.\n\n## Documentation\n\nStart at [`docs\u002Findex.md`](.\u002Fdocs\u002Findex.md).\n\n| Document | Purpose |\n| --- | --- |\n| [`docs\u002Fhow-nyrima-works.md`](.\u002Fdocs\u002Fhow-nyrima-works.md) | What the app is and how the current flows work. |\n| [`docs\u002Fgetting-started.md`](.\u002Fdocs\u002Fgetting-started.md) | Install, pair Drive, configure access, and play the first file. |\n| [`docs\u002Flibrary-guide.md`](.\u002Fdocs\u002Flibrary-guide.md) | Folder layout, artwork, subtitles, and player behavior. |\n| [`docs\u002Fsharing-guide.md`](.\u002Fdocs\u002Fsharing-guide.md) | Current Drive-only sharing model and privacy choices. |\n| [`docs\u002Ftroubleshooting.md`](.\u002Fdocs\u002Ftroubleshooting.md) | Setup, Chrome, OAuth, Drive, playback, and sharing diagnosis. |\n| [`docs\u002Farchitecture.md`](.\u002Fdocs\u002Farchitecture.md) | Detailed developer architecture and trust boundaries. |\n| [`docs\u002Foauth-setup.md`](.\u002Fdocs\u002Foauth-setup.md) | Google Cloud OAuth setup for developers and testers. |\n| [`docs\u002Fpermissions-and-data-use.md`](.\u002Fdocs\u002Fpermissions-and-data-use.md) | Permission, scope, endpoint, and storage audit. |\n| [`docs\u002Fprivacy-policy.md`](.\u002Fdocs\u002Fprivacy-policy.md) | Privacy policy for the current extension. |\n| [`docs\u002Fterms-of-use.md`](.\u002Fdocs\u002Fterms-of-use.md) | Terms for using the current extension. |\n\nEngineering phase status stays in [`PHASES.md`](.\u002FPHASES.md).\n\n## Contributor Project Memory\n\nFuture contributor and agent guidance lives in\n[.claude\u002FREADME.md](.\u002F.claude\u002FREADME.md): workflow, artifacts, system\nboundaries, reusable patterns, Nyrima styling, and Once UI integration notes.\nIt complements the deploy docs above; it does not replace them.\n\n## Security And Privacy Summary\n\n- Media bytes flow from Google Drive to the browser. Nyrima does not upload\n  media to a Nyrima server.\n- Nyrima does not read browser cookies from Drive or other websites.\n- OAuth tokens are handled through the background service worker and are not\n  sent to the optional GitHub raw directory endpoint.\n- Publishing a `Shared\u002F` folder makes share metadata readable by anyone with\n  that folder link. It does not automatically grant access to the underlying\n  target file or library folder.\n- The detailed permission and data-use map is in\n  [`docs\u002Fpermissions-and-data-use.md`](.\u002Fdocs\u002Fpermissions-and-data-use.md).\n\n## License\n\nMIT.\n","Nyrima 是一款基于 Chrome 的扩展程序，用于播放存储在 Google Drive 中的私人视频库。它能够将一个可访问的 Drive 文件夹转换为个人影院，支持原生媒体字节、文件夹封面艺术、丰富的字幕功能，并且无需依赖 Nyrima 后端服务。项目采用 React 18 和 TypeScript 5.6 构建，利用 Vite 作为打包工具，遵循 Chrome 扩展 Manifest V3 标准。适用于希望直接从 Google Drive 流式传输并管理个人电影收藏的用户，特别适合那些对隐私有较高要求、不希望通过第三方服务器处理媒体内容的人群。",2,"2026-06-11 04:01:28","CREATED_QUERY"]