Skip to content
ydqsglPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Ed2kPlayer

一个 Android 播放器,支持 ed2k:// 与 magnet: 链接的边下边播(下载未完成即可开始播放)。

不需要 115 会员,不需要先把文件下完,也不需要装 eMule。

解决什么问题

资源站提供的下载方式通常是 ed2k 或网盘。网盘要会员,ed2k 链接又无法被普通播放器直接打开—— 必须先经 eMule / aMule 之类的 P2P 客户端完整下载,才能播放。

这个 App 把整条链路收进一个安卓应用:

  1. 粘贴 ed2k / magnet 链接(或从系统分享菜单、浏览器点 ed2k://、magnet: 直接唤起)
  2. 内置下载引擎自动开始下载
  3. 下载到设定比例后自动开播,边下边看

为什么"边下边播"没那么简单

两个容易被忽略的坑,也是本项目大部分复杂度的来源:

1. 分片乱序 + 空洞

P2P 下载是按分片(piece)乱序完成的,文件会被预先分配成完整长度,未下载的区域全是 0。 播放器直接读这个文件,会把空洞里的 0 当成有效数据,结果是容器解析失败,或者一直转圈缓冲。

解决方式:内置一个本地 HTTP Range 服务(stream/LocalStreamServer.kt),把"分片可用性位图" 翻译成标准 HTTP 语义——已下载区域立即返回,未下载区域先挂住连接等下载追上(默认最多等 10 分钟)。 播放器看到的就是一个"长度固定、按需变慢"的正常 HTTP 资源,Seek 也自然可用。

2. 头部优先

容器(尤其是 mp4 的 moov)通常在文件开头,播放器一上来就要读它。 所以给引擎传了 --bt-prioritize-piece=head=8M,tail=1M,优先拿首尾分片,开播时间因此大幅提前。

架构

┌──────────────────────────────────────────────────┐
│  UI   MainActivity / PlayerActivity / Downloads   │
├──────────────────────────────────────────────────┤
│  LocalStreamServer   ← 把分片位图翻译成 HTTP Range │
│  StreamAvailability  ← 分片可用性视图              │
├────────────────────────┬─────────────────────────┤
│  Aria2Manager          │  Ed2kEngine              │
│  ├ Aria2Process        │  └ jed2k (原生 eD2k)     │
│  ├ Aria2Rpc (JSON-RPC) │                          │
│  └ aria2c (ELF)        │                          │
│    BT / magnet / HTTP  │  ed2k://                 │
├────────────────────────┴─────────────────────────┤
│  ExoPlayer (Media3)  ← 播放本地流地址              │
└──────────────────────────────────────────────────┘

两套下载引擎并存,因为协议栈不同:

链接类型 引擎 说明
magnet: aria2c BitTorrent(DHT + Trackers)
ed2k:// jed2k eD2k 原生协议(连服务器、找源、分片校验)

核心模块

模块 文件 说明
链接解析 ed2k/LinkParser.kt 统一识别 ed2k:// 与 magnet:
ed2k 解析 ed2k/Ed2kParser.kt 解析 ed2k://|file|名称|大小|hash|/
ed2k 引擎 ed2k/Ed2kEngine.kt 封装 jed2k:连接、找源、下载、分片位图
aria2 二进制 aria2/Aria2Binary.kt 从 jniLibs 取 libaria2c.so,构建启动参数
aria2 进程 aria2/Aria2Process.kt 启动 / 停止 aria2c 子进程
aria2 RPC aria2/Aria2Rpc.kt JSON-RPC 2.0 客户端
aria2 服务 aria2/Aria2Service.kt 前台服务,保持引擎存活
高层管理 aria2/Aria2Manager.kt UI 与下载引擎的唯一入口
流服务 stream/LocalStreamServer.kt 本地 HTTP Range 服务(边下边播的关键)
播放器 ui/PlayerActivity.kt ExoPlayer + 下载进度浮层

org/dkf/jed2k/ 是 eD2k 协议栈的实现(约 240 个类),包含 Kad DHT、eD2k 服务器协议、 分片校验与磁盘 IO。

构建

前置条件

  • Android Studio Hedgehog (2023.1) 或更高
  • JDK 17
  • Android SDK 34
  • NDK(仅在需要自行编译 aria2c 时)

步骤

  1. 克隆

    git clone https://github.com/ydqsgl/yded2k.git
    cd yded2k
  2. 准备 aria2c 二进制

    aria2c 在 Android 上以 libaria2c.so 的形式随 APK 打包 (放在 jniLibs/ 而非 assets/,这样能被解压到可执行的 nativeLibraryDir, 绕开 Android 的 W^X 限制)。

    仓库已包含 arm64-v8a 的预编译产物。若要自行编译:

    git clone https://github.com/aria2/aria2.git
    cd aria2
    ./configure --host=aarch64-linux-android \
      --with-libcares --without-libxml2 \
      --disable-ssl --disable-gssapi
    make -j$(nproc)
    cp src/aria2c /path/to/yded2k/app/src/main/jniLibs/arm64-v8a/libaria2c.so

    scripts/fetch_aria2c.sh 提供了从 Termux 仓库提取预编译二进制的备选路径。

  3. 配置 SDK 路径

    创建 local.properties:

    sdk.dir=/path/to/Android/sdk
  4. 编译

    ./gradlew assembleDebug
    # 产物:app/build/outputs/apk/debug/app-debug.apk

使用方法

  1. 打开 App,等待引擎就绪(绿色圆点)

  2. 粘贴链接,例如:

    ed2k://|file|movie.mkv|7340032000|ABCDEF0123456789ABCDEF0123456789|/
    magnet:?xt=urn:btih:08ADA5A7A6183Aae1E09D831df6748d566095A10&dn=Sintel
    
  3. 点击解析

  4. 进入播放页,下载到设定比例后自动开播

其他入口

  • 系统分享:任意 App 中分享链接给本应用
  • 直接打开:浏览器点 ed2k:// / magnet: 链接自动拦截
  • 下载列表:暂停 / 继续 / 删除 / 播放,查看连接数与实时速度

设置

设置项 默认值 说明
下载目录 应用外部存储 文件保存位置
最大并行任务数 3 同时下载数
分片大小 1024 KB aria2 分片
RPC 端口 6800 aria2 JSON-RPC 端口
缓冲百分比 5% 下载到此比例后开播
上传限速 64 KB/s P2P 上传限速(P2P 礼仪,不建议设为 0)

已知限制

1. 没有源就下不动,这不是 Bug

ed2k 与 BitTorrent 都是 P2P,下载速度完全取决于网络中在线源的数量。 链接里写死了文件名和哈希,所以即使全网无人持有,客户端照样能显示"已解析"—— 能解析 ≠ 有源。

磁力更明显:拿不到元数据时连文件名都显示不出来,表现为停在"加载中"。

判断方法:在电脑上用 eMule / qBittorrent 打开同一条链接。 来源数为 0 的资源,任何 P2P 客户端都下不动(迅雷能下是因为它有中心化缓存,不走 P2P)。

2. 文件头在末尾的 mp4

部分 mp4 把 moov 放在文件末尾。这类文件在下载完成前无法解析出时长与索引, 会等到尾部下载完成才开播。--bt-prioritize-piece=tail 已缓解,但无法根治。

3. 编码支持取决于设备

播放依赖系统 MediaCodec。H.264 / HEVC 普遍支持;部分冷门编码(如 RMVB)需要软解, 本项目未内置软解器。

4. eD2k 端口

监听 4662(TCP)/ 4672(UDP)为标准端口。被运营商或路由器阻断时会拿到 LowID, 可用源会显著减少。

技术栈

  • Kotlin + Coroutines
  • AndroidX / Material 3
  • Media3 (ExoPlayer) 1.2.1
  • OkHttp 4.12
  • aria2c(BitTorrent 引擎)
  • jed2k(eD2k 协议栈)

License

应用代码采用 MIT 协议。

内嵌组件遵循其自身协议:

  • aria2c — GPLv2,本项目仅作为前端调用,未修改其源码
  • jed2k — GPLv2

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages