{"id":48864806,"url":"https://github.com/atorber/noderadio","last_synced_at":"2026-04-15T18:01:27.165Z","repository":{"id":351583090,"uuid":"1211399711","full_name":"atorber/NodeRadio","owner":"atorber","description":null,"archived":false,"fork":false,"pushed_at":"2026-04-15T16:25:38.000Z","size":422,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-15T17:27:22.755Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atorber.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T11:01:24.000Z","updated_at":"2026-04-15T16:25:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/atorber/NodeRadio","commit_stats":null,"previous_names":["atorber/noderadio"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/atorber/NodeRadio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2FNodeRadio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2FNodeRadio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2FNodeRadio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2FNodeRadio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atorber","download_url":"https://codeload.github.com/atorber/NodeRadio/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atorber%2FNodeRadio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31853279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T15:24:51.572Z","status":"ssl_error","status_checked_at":"2026-04-15T15:24:39.138Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-15T18:00:52.695Z","updated_at":"2026-04-15T18:01:27.144Z","avatar_url":"https://github.com/atorber.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NodeRadio | 私频收音机\n\n**NodeRadio（私频收音机）** 是一款为极客、开发者及架构师打造的、高度自定义的音视频直播流管理工具。目前使用 Flutter 框架进行开发，原生支持 Android 平台的高级特性。\n\n它像是一台来自未来的复古电台。不同于预设繁琐的传统播放器，NodeRadio 将每一个 **直播 URL** 或 **协作空间地址** 抽象为一个“频道节点（Channel Node）”。通过输入地址，你可以亲手“调教”出属于自己的私人频道阵列。\n\n-----\n\n## 📻 设计哲学：Neon Nocturne 赛博美学\n\n  * **暗黑霓虹：** 采用基于 Material 3 `AppTheme.darkTheme` 深度定制的 *Neon Nocturne* 主题，高对比度色彩（荧光紫、赛博青）点缀在深邃幽暗的背景上。\n  * **快速交互：** 极简的底部导航结构（频道矩阵、一键添加），摆脱冗杂逻辑，直达核心媒体内容。\n  * **节点架构：** 频道链接具有严谨的数据结构并自动识别流类型，每个频道都是独立的、持久化的 Node。\n\n-----\n\n## ✨ 当前已实现的核心特性\n\n  * **智能频道库管理：**\n    * 内置轻量级的持久化能力（SharedPreferences），无缝保存、添加、长按删除自定义频道。\n    * 频道地址智能探测：输入链接即可自动识别并标记为 **飞书直播**、**HLS 流**、**RTMP 流** 或 **常规 Web 页面** 类型。\n  * **深度支持飞书直播 (Feishu/Lark)：**\n    * 完美解析 `meetings.feishu.cn` 等内嵌 Web 直播流地址。\n    * 提供一键导入飞书直播测试流选项，免跨端复杂跳转直接在 App 内呈现，打造闭环体验。\n  * **全功能内置 Web 容器引擎：**\n    * 内嵌专属打造的 `WebViewPlayerScreen`。\n    * 提供内置加载进度条与强定制的 Chrome Mobile User-Agent 模拟，深度解决网页兼容问题。\n    * 一键全屏与横屏强制切入系统，具备最佳的大屏观影体验。\n  * **Android 原生画中画 (Picture-in-Picture) 后台悬浮播放：**\n    * 深度集成底层 API (`supportsPictureInPicture`)，拥有原生的系统级浮窗支持能力。\n    * 支持 **Auto PiP 行动**：观看任何直播频道时退回桌面（系统主屏），自动无缝收缩为系统级悬浮窗继续播放。\n    * 浮窗时自动剥离 App 导航栏与状态栏，呈现 100% 纯净流媒体小窗，并在点击时优雅扩展回全屏应用。\n  * **无阻碍的中国网络环境编译引擎支持：**\n    * 针对中国大陆进行了原生 Gradle 与 Maven 下载的定制重配（注入阿里云与腾讯云镜像仓库），保障项目开箱即用、随时可以顺滑构建出 Android Release 应用包。\n\n-----\n\n## 🛠 技术栈与架构 (For Architects)\n\n  * **渲染层：** Flutter \u0026 Dart。\n  * **持久层：** `shared_preferences` 对基础数据进行序列化管理。\n  * **媒体容器：** \n    * `webview_flutter` 用于实现复杂逻辑页面的渲染（如飞书鉴权页面与推流显示）。\n  * **底层支持：** \n    * 使用了 `simple_pip_mode` 突破了普通 Flutter 生命周期限制，获取了 Android 内部的 Picture in Picture 生命周期接口权限以接管悬浮状态。\n\n-----\n\n## 🚀 接入与使用示例\n\n### 如何添加一个飞书直播节点：\n\n1. **获取信号：** 在外部复制飞书会议/直播分享地址。\n2. **创建节点：** \n    * 在 App 底部导航切换至 **[添加]** 标签。\n    * 填入频道名称（如：`部门技术分享周会`），粘贴相应的 URL，或者使用一键填充测试模板。\n3. **注入链接：** 点击 **“保存并添加”**，频道将自动归纳至首页矩阵中进行持久化保存。\n4. **悬浮观看：** 点击卡片开始播放，随后上滑返回桌面即可启动画中画 (PiP) 功能。\n\n-----\n\n## 🤝 关于维护\n\n**项目主页：** [github.com/atorber/NodeRadio](https://github.com/atorber/NodeRadio)  \n\n如果您在打包编译出现问题（特别是在同步 Android 依赖时），请注意检查项目的 `android/build.gradle.kts` 网络代理以及镜像。当前的构建脚本已确保在国内最高效。\n\n-----\n\n\u003e *\"在数字荒原中，捕捉那一束属于你的霓虹电波。\"*","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatorber%2Fnoderadio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatorber%2Fnoderadio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatorber%2Fnoderadio/lists"}