全格式解码
libVLC 3.7 内核:DivX、HEVC、AV1、DTS、AC3/EAC3、TrueHD、FLAC 等;硬件解码优先,出错自动回退软解。
为“什么都能播”而设计,把细节做到位。
libVLC 3.7 内核:DivX、HEVC、AV1、DTS、AC3/EAC3、TrueHD、FLAC 等;硬件解码优先,出错自动回退软解。
内嵌字幕轨识别与语言自动选中;同目录外挂字幕自动匹配;ASS 特效渲染;样式与延迟调节;OpenSubtitles 在线搜索。
多音轨切换、音轨延迟对齐、10 段均衡器、多种声道模式、HDMI 源码输出(实验性)。
手机常驻纯图标迷你侧栏,底部存储圆环实时显示占用;展开为纯文字抽屉,含存储明细。Hero 海报、继续观看、收藏与文件夹分行。
SMB(SMB2/3)与 WebDAV 局域网浏览;HTTP / HLS(m3u8) 直链播放;密码经 Android Keystore 加密存储。
进度条画面预览、真裁剪不变形、变速/循环/旋转、睡眠定时、同文件夹自动连播、章节与书签;投屏可发可收——DLNA 投给电视,也能作为电视被其他设备投屏。
基于 Material 官方色彩算法生成完整色板,明暗双色板实时换肤;支持系统动态取色与 550ms 渐变过渡。
启动隐私缓冲可选:默认隐藏媒体内容,轻触才显示。无 GMS 依赖,适配小米 / OPPO / vivo / 荣耀 / 三星等定制系统。
从进度条预览到投屏串流,每一处都打磨过。
不只表面功夫——播放管线、投屏串流、字幕匹配,这些脏活累活都是自己实现的。
约 270 行 Kotlin 实现 HTTP 服务器:Range/206 分段、流式响应、逐请求线程。电视拉流拖动进度即时响应,不引入任何第三方 server 依赖。
先剔除片源发布标签(1080p / BluRay / WEB-DL / x265…),再按「主名精确 100 分、主名+语言 90、包含 60、模糊 30」四级打分;内置简繁双语与 chs&eng 等标记识别。
libVLC 无法直接打开 Android 的 content MRL:媒体经 ParcelFileDescriptor 桥接打开,外挂字幕先复制到缓存再 addSlave,SAF 文件夹也能直接播。
libVLC 的裁剪滤镜在 Android vout 上不可用,改为 TextureView 渲染 + graphicsLayer 等比放大,由父容器裁边——数学保证比例不变形。
用 Coil 的 videoFrameMillis 按 10 秒分桶取帧,内存缓存复用缩略图,拖动时保留上一帧避免闪烁;监听 Coil 3 的 StateFlow 正确触发重组。
SMB/WebDAV 凭据经 Android Keystore AES-GCM 加密;媒体库重扫走 upsert,只更新元数据,收藏与观看进度永不丢失;无统计 SDK。
// core:player/MediaStreamServer.kt — 内置局域网串流
val socket = ServerSocket(0) // 任选一个局域网端口
// 交给 DLNA 渲染设备的地址:
"http://$ip:${socket.localPort}/media"
// 电视拖动进度 → Range 请求 → 206 分段响应
val start = rangeStart.coerceIn(0L, total - 1)
val end = (rangeEnd ?: total - 1).coerceIn(start, total - 1)
writeStatus(
client,
"206 Partial Content",
listOf(
"Content-Range" to "bytes $start-$end/$total",
"Content-Length" to "${end - start + 1}",
),
)
// core:common/SubtitleMatcher.kt — 同目录字幕自动匹配
const val SCORE_EXACT = 100 // 主名完全一致
const val SCORE_BASE_WITH_LANGUAGE = 90 // 主名 + 语言标记
const val SCORE_CONTAINS_BASE = 60 // 主名包含关系
const val SCORE_FUZZY = 30 // 模糊匹配
// 比对前先剔除发布标签:
"1080p" "bluray" "web-dl" "x265" "10bit" …
// app/ui/player/PlayerScreen.kt — 裁剪填满:等比放大,父级裁边
val fitWidth = if (containerAspect > videoAspect)
containerHeight * videoAspect else containerWidth
val fitHeight = fitWidth / videoAspect
val layerScale = maxOf(
containerWidth / fitWidth,
containerHeight / fitHeight,
)
AndroidView(
modifier = Modifier
.fillMaxSize()
.graphicsLayer { scaleX = layerScale; scaleY = layerScale },
)
本站镜像最新版本;历史版本见 GitHub Releases。APK 使用固定签名,可直接覆盖升级。
不确定架构?选 arm64-v8a 即可。校验 SHA-256 可确认文件完整。
没找到答案?到 GitHub Issues 提问。
播放内核使用 libVLC,界面与全部功能均为独立开发:迷你侧栏、字幕链路、均衡器、投屏串流、主题系统等。项目以 GPL-3.0 开源。
项目基于最新系统 API 与 Compose 构建,未适配旧版本。旧设备可在 GitHub 提出需求,视情况评估。
侧载 APK 时系统会给出标准安全提示。本站 APK 与 GitHub Release 完全一致,可对照 releases.json 中的 SHA-256 校验;如不放心可自行编译。
手机与电视处于同一 Wi-Fi 时,播放页右上角点投屏图标,选择已发现的设备即可;本地视频由手机内置串流服务器传给电视(支持拖动进度)。反过来也可以:设置中开启「允许接收投屏」后,本机会以「OpenVisum · 设备型号」出现在其他设备的投屏列表中,被投屏时播放页自动打开。
不会。应用没有统计 SDK,也不要求账号;网络权限仅用于局域网与在线字幕搜索。SM B/WebDAV 凭据经 Android Keystore 加密存储。
欢迎在 GitHub Issues 反馈问题(附设备型号、系统版本与复现步骤),也欢迎 Pull Request。