From 96ea9e56e3396e1edc56aefb19468fbf1d5e08a3 Mon Sep 17 00:00:00 2001
From: lsr-05 <202249500+lsr-05@users.noreply.github.com>
Date: Sat, 31 Oct 2026 17:08:04 +0800
Subject: [PATCH 1/2] release: prepare CastTrace 0.2.14
---
.github/workflows/release-apk.yml | 39 ++-
CHANGELOG.md | 4 +-
FFMPEG-LICENSE.md | 38 +++
README.en.md | 135 ++++++++
README.md | 39 ++-
RELEASING.md | 120 ++++---
THIRD_PARTY.md | 25 +-
app/build.gradle.kts | 22 +-
app/libs/README.md | 26 +-
screenshots/live-reminders.png | Bin 0 -> 90201 bytes
screenshots/live-rooms-large-screen.png | Bin 0 -> 82322 bytes
screenshots/settings.png | Bin 0 -> 210808 bytes
scripts/build_ffmpeg_source.sh | 48 +++
scripts/prepare_ffmpeg_compliance.py | 298 +++++++++++-------
scripts/verify_release_readiness.py | 67 +++-
.../patches/0001-pin-gnutls-gnulib.patch | 10 +
.../patches/0002-pin-source-commits.patch | 70 ++++
third_party/ffmpeg/source-build.json | 51 +++
18 files changed, 756 insertions(+), 236 deletions(-)
create mode 100644 FFMPEG-LICENSE.md
create mode 100644 README.en.md
create mode 100644 screenshots/live-reminders.png
create mode 100644 screenshots/live-rooms-large-screen.png
create mode 100644 screenshots/settings.png
create mode 100644 scripts/build_ffmpeg_source.sh
create mode 100644 third_party/ffmpeg/patches/0001-pin-gnutls-gnulib.patch
create mode 100644 third_party/ffmpeg/patches/0002-pin-source-commits.patch
create mode 100644 third_party/ffmpeg/source-build.json
diff --git a/.github/workflows/release-apk.yml b/.github/workflows/release-apk.yml
index 0220db8..6938087 100644
--- a/.github/workflows/release-apk.yml
+++ b/.github/workflows/release-apk.yml
@@ -15,7 +15,8 @@ concurrency:
jobs:
publish:
if: github.ref_type == 'tag'
- runs-on: ubuntu-latest
+ runs-on: ubuntu-24.04
+ timeout-minutes: 360
steps:
- uses: actions/checkout@v4
with:
@@ -48,24 +49,33 @@ jobs:
- uses: android-actions/setup-android@v4
with:
- packages: 'platform-tools platforms;android-35 build-tools;35.0.0'
+ packages: 'platform-tools platforms;android-35 build-tools;35.0.0 ndk;26.2.11394342'
- uses: gradle/actions/setup-gradle@v4
- - name: Download and verify pinned FFmpegKit AAR
+ - name: Install FFmpeg source build tools
run: |
- mkdir -p app/libs
- curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \
- 'https://repo.maven.apache.org/maven2/dev/ffmpegkit-maintained/ffmpeg-kit-https/7.1.6/ffmpeg-kit-https-7.1.6.aar' \
- -o app/libs/ffmpeg-kit-https-7.1.6.aar
- echo 'e80e5ee52248a3dcb1dda0524dd784fe4bbb212dcd4d575e82e15d21a002d860 app/libs/ffmpeg-kit-https-7.1.6.aar' | sha256sum --check
+ sudo apt-get update
+ sudo apt-get install --yes gettext
- - name: Run unit tests and lint
- run: bash gradlew --no-daemon :app:testDebugUnitTest :app:lintDebug --console=plain
+ - name: Build FFmpegKit from pinned sources
+ run: |
+ bash scripts/build_ffmpeg_source.sh
+ aar="$GITHUB_WORKSPACE/build/compliance/ffmpeg-7.1.6/ffmpeg-kit-https-7.1.6.aar"
+ test -s "$aar"
+ digest="$(sha256sum "$aar" | cut -d' ' -f1)"
+ printf 'CASTTRACE_FFMPEG_AAR_PATH=%s\n' "$aar" >> "$GITHUB_ENV"
+ printf 'CASTTRACE_FFMPEG_AAR_SHA256=%s\n' "$digest" >> "$GITHUB_ENV"
+
+ - name: Collect FFmpeg corresponding-source materials
+ run: python scripts/prepare_ffmpeg_compliance.py --aar "$CASTTRACE_FFMPEG_AAR_PATH"
- name: Enforce FFmpeg corresponding-source release gate
run: python scripts/verify_release_readiness.py
+ - name: Run unit tests and lint with the release FFmpeg AAR
+ run: bash gradlew --no-daemon :app:testDebugUnitTest :app:lintDebug --console=plain
+
- name: Prepare signing key
env:
CASTTRACE_KEYSTORE_BASE64: ${{ secrets.CASTTRACE_KEYSTORE_BASE64 }}
@@ -127,11 +137,6 @@ jobs:
raise SystemExit('APK version changed after tag validation.')
PY
- - name: Collect FFmpeg corresponding-source materials
- env:
- GH_TOKEN: ${{ github.token }}
- run: python scripts/prepare_ffmpeg_compliance.py
-
- name: Check source materials and assemble release assets
env:
TAG_NAME: ${{ github.ref_name }}
@@ -141,10 +146,11 @@ jobs:
mkdir -p build/release
version="${TAG_NAME#v}"
cp app/build/outputs/apk/release/app-release.apk "build/release/casttrace-${version}-release.apk"
+ cp app/build/ffmpeg/ffmpeg-kit-https-7.1.6-compatible.aar "build/release/casttrace-ffmpeg-7.1.6-compatible.aar"
git archive --format=zip --prefix=casttrace-android/ HEAD -o "build/release/casttrace-${version}-source.zip"
cp build/compliance/ffmpeg-7.1.6/casttrace-ffmpeg-7.1.6-source-materials.zip build/release/
cd build/release
- sha256sum casttrace-*-release.apk casttrace-*-source.zip casttrace-ffmpeg-7.1.6-source-materials.zip > SHA256SUMS
+ sha256sum casttrace-*-release.apk casttrace-*-compatible.aar casttrace-*-source.zip casttrace-ffmpeg-7.1.6-source-materials.zip > SHA256SUMS
- name: Publish GitHub Release
uses: softprops/action-gh-release@v2
@@ -154,6 +160,7 @@ jobs:
fail_on_unmatched_files: true
files: |
build/release/casttrace-*-release.apk
+ build/release/casttrace-*-compatible.aar
build/release/casttrace-*-source.zip
build/release/casttrace-ffmpeg-7.1.6-source-materials.zip
build/release/SHA256SUMS
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2ba0477..fe71b5a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,13 +2,14 @@
此记录描述源码版本,不代表已发布可下载的 APK。设备验证范围见 README。
-## 0.2.14 - 未发布
+## 0.2.14 - 2026-10-31
- 增加直播提醒和超火、礼物、订阅等直播事件采集能力。
- 以 Hilt 统一应用、服务、Receiver、Worker 和 ViewModel 的依赖注入。
- 拆分平台 Resolver、仓储、录制存储和录制恢复职责,保留既有调用与 Intent 契约。
- 增加录制并发、重试优先级、恢复和 Resolver 工厂的 JVM 回归测试。
- 完善开发者上手文档和带源码许可门槛的 APK 发布流程。
+- 补齐 FFmpegKit 固定源码构建和对应源码材料;本地发布门槛检查通过。
## 0.2.13 - 2026-10-01
@@ -26,4 +27,3 @@
- 手机厂商后台策略、网络状态和平台接口仍可能影响自动录制。
- Mate 20 收尾期间曾观察到短会话重新开录,触发原因待进一步确认。
- 本轮长会话手机端拖动、HarmonyOS 4.2 和未充电深度待机尚未完成验收。
-- FFmpeg 完整对应源码材料尚未补齐,暂不正式分发 APK/AAB。
diff --git a/FFMPEG-LICENSE.md b/FFMPEG-LICENSE.md
new file mode 100644
index 0000000..1802f96
--- /dev/null
+++ b/FFMPEG-LICENSE.md
@@ -0,0 +1,38 @@
+# FFmpegKit License and Source Materials
+
+## Binary used by the app
+
+Local development uses `dev.ffmpegkit-maintained:ffmpeg-kit-https:7.1.6` from Maven Central. The AAR is excluded from Git and its SHA-256 is pinned in `app/build.gradle.kts`. Official Release builds instead compile FFmpegKit from the source commits, patches and toolchain pinned in [`third_party/ffmpeg/source-build.json`](third_party/ffmpeg/source-build.json). The Maven and source-built AARs are not claimed to be byte-for-byte identical. Both builds are LGPLv3 HTTPS variants with FFmpeg n7.1.5 and without GPL or nonfree FFmpeg components; the app packages `arm64-v8a` and `x86_64`.
+
+The build task `prepareCompatibleFfmpeg` adjusts only ELF64 `PT_GNU_RELRO.p_memsz` when 16 KiB alignment padding extends beyond the mapped `PT_LOAD` segments at 4 KiB page granularity. This avoids Android 10 `mprotect` failures on unmapped padding. The source AAR remains unchanged; the transformation is in `app/build.gradle.kts` and is part of the application build configuration.
+
+## License scope
+
+The root [Apache License 2.0](LICENSE) covers CastTrace application source. It does not relicense FFmpegKit or its linked libraries. Full notices shipped with the app are under `app/src/main/assets/licenses/` and can be read offline from Settings → Open-source licenses.
+
+The FFmpegKit build and its dependencies retain their own terms. The current native configuration identifies FFmpeg, GMP, GnuTLS, Nettle/Hogweed and libiconv on LGPL-compatible build paths. `cpu_features` and `ndk_compat` retain their upstream notices. Android zlib and MediaCodec are system libraries. The exact component versions, source commits, build options and hashes are recorded in [`third_party/ffmpeg/manifest.json`](third_party/ffmpeg/manifest.json).
+
+## Corresponding source and release gate
+
+An APK release includes the corresponding FFmpegKit/native-library source archives, pinned dependency source, build recipe and patches, application source/build configuration, license notices and SHA-256 checksums. The tag workflow builds the AAR from the pinned inputs, verifies its version, ABIs and native configuration, packages the source materials, and passes that same AAR to Gradle for tests and APK packaging. The policy records the exact verification scope and does not claim byte-for-byte equivalence with the separate Maven development artifact.
+
+## Rebuilding
+
+The pinned build uses Ubuntu 24.04, JDK 17, Android SDK Platform 35, NDK r26c and `gettext` for GnuTLS bootstrap. Reproduce it with [`scripts/build_ffmpeg_source.sh`](scripts/build_ffmpeg_source.sh), which fetches pinned commits, applies the tracked patches and writes the AAR under `build/compliance/`. Then run [`scripts/prepare_ffmpeg_compliance.py`](scripts/prepare_ffmpeg_compliance.py) and [`scripts/verify_release_readiness.py`](scripts/verify_release_readiness.py) to package and check corresponding-source materials.
+
+```sh
+./android.sh --enable-gnutls --enable-gmp \
+ --enable-android-media-codec --enable-android-zlib \
+ --disable-arm-v7a --disable-arm-v7a-neon --disable-x86
+```
+
+The source-built AAR is supplied to Gradle using `CASTTRACE_FFMPEG_AAR_PATH` and `CASTTRACE_FFMPEG_AAR_SHA256`. Gradle then creates a compatible AAR by trimming only unmapped ELF `PT_GNU_RELRO` padding that can cause `mprotect` failures on Android 10. This transformation is in the application build configuration and is included in the CastTrace source archive; the Release also publishes the resulting compatible AAR. Any native-library or transformation change requires renewed native loading, remuxing, playback and device compatibility tests.
+
+To rebuild CastTrace for development, download and verify the pinned Maven AAR, use JDK 17 and Android SDK 35, then run the Gradle commands in [README.md](README.md). To reproduce a Release, use the source-build sequence in [RELEASING.md](RELEASING.md). A modified LGPL library can be rebuilt and relinked using the application source and build configuration included with a release. Do not use CastTrace's private signing key for modified builds.
+
+## References
+
+- [FFmpegKit maintained source](https://github.com/ffmpegkit-maintained/ffmpeg)
+- [FFmpeg](https://github.com/FFmpeg/FFmpeg)
+- [GNU LGPL v3](https://www.gnu.org/licenses/lgpl-3.0.html)
+- [Release process](RELEASING.md)
diff --git a/README.en.md b/README.en.md
new file mode 100644
index 0000000..607f056
--- /dev/null
+++ b/README.en.md
@@ -0,0 +1,135 @@
+# CastTrace Android
+
+[简体中文](README.md) | English
+
+
+
+
+
+
+
+
+CastTrace is an Android application for monitoring live rooms and recording supported streams. It is built with Kotlin, Jetpack Compose, Room, WorkManager, Media3 and FFmpegKit. It manages room lists locally, monitors live status in the background, resumes interrupted recordings, collects supported chat messages, and plays saved videos.
+
+This is an independently maintained Android project that takes inspiration from the platform recording approach in [StreamCap](https://github.com/ihmily/StreamCap). It is not an official StreamCap mobile client. A platform being supported upstream does not mean that CastTrace supports it.
+
+
+ Screenshots ·
+ Download APK ·
+ Features ·
+ Build from source ·
+ Developer guide ·
+ Contributing
+
+
+## Screenshots
+
+
+
+
+
+
+
+## Download
+
+Download the APK and checksums from [GitHub Releases](https://github.com/SRiftX/casttrace-android/releases). CastTrace supports Android 8.0+ on `arm64-v8a` and `x86_64`. The APK uses the established CastTrace signing identity and can update an existing installation while retaining app data. Each release also includes CastTrace source, FFmpeg corresponding-source materials, the compatible AAR and SHA-256 checksums. See [RELEASING.md](RELEASING.md) for the release procedure.
+
+## Features
+
+- Manage multiple rooms and import room links, shared text or batches.
+- Monitor live status in the background and schedule live reminders.
+- Recover from short disconnects, expired stream URLs and process restarts.
+- Save FLV, HLS/TS or MP4 recordings, including long-session segments.
+- Browse, seek, rename, delete, export and share saved videos.
+- Capture text chat on supported platforms and export videos with chat overlays.
+- Back up room lists and app settings.
+
+Background monitoring depends on notification permission, battery policy and vendor-specific startup controls. Some devices require CastTrace to be allowed to start and run in the background.
+
+## Platform Support
+
+The platform catalog tracks supported, needs-review, planned and stopped entries. Current supported entry points include Huya, Douyin, Bilibili, Douyu and direct HLS/FLV URLs. Some other platforms require device, account or regional verification. Recognizing a shared link does not guarantee that a room is live or recordable. See [`PlatformCatalog.kt`](app/src/main/java/com/streamcap/mobile/platform/PlatformCatalog.kt) for the current status.
+
+## Build from Source
+
+Requirements:
+
+- JDK 17
+- Android SDK Platform 35 and Build Tools 35.0.0
+- Android 8.0 (API 26) or newer; APKs include `arm64-v8a` and `x86_64`
+- The pinned FFmpegKit 7.1.6 AAR, verified by SHA-256
+
+The AAR is excluded from Git. Download and verify it before building:
+
+Linux and macOS:
+
+```bash
+mkdir -p app/libs
+curl --fail --silent --show-error --location --proto '=https' --proto-redir '=https' \
+ 'https://repo.maven.apache.org/maven2/dev/ffmpegkit-maintained/ffmpeg-kit-https/7.1.6/ffmpeg-kit-https-7.1.6.aar' \
+ -o app/libs/ffmpeg-kit-https-7.1.6.aar
+echo 'e80e5ee52248a3dcb1dda0524dd784fe4bbb212dcd4d575e82e15d21a002d860 app/libs/ffmpeg-kit-https-7.1.6.aar' | sha256sum --check
+```
+
+Windows PowerShell:
+
+```powershell
+New-Item -ItemType Directory -Path app\libs -Force | Out-Null
+Invoke-WebRequest `
+ 'https://repo.maven.apache.org/maven2/dev/ffmpegkit-maintained/ffmpeg-kit-https/7.1.6/ffmpeg-kit-https-7.1.6.aar' `
+ -OutFile app\libs\ffmpeg-kit-https-7.1.6.aar
+$expected = 'e80e5ee52248a3dcb1dda0524dd784fe4bbb212dcd4d575e82e15d21a002d860'
+$actual = (Get-FileHash app\libs\ffmpeg-kit-https-7.1.6.aar -Algorithm SHA256).Hash.ToLowerInvariant()
+if ($actual -ne $expected) { throw "Unexpected FFmpegKit AAR SHA-256: $actual" }
+```
+
+Set `ANDROID_HOME` to the local SDK. If Gradle reports `Unable to establish loopback connection` on Windows, use a short writable temporary path:
+
+```powershell
+$env:ANDROID_HOME = "$env:LOCALAPPDATA\Android\Sdk"
+$env:TEMP = 'C:\tmp'
+$env:TMP = 'C:\tmp'
+New-Item -ItemType Directory -Path $env:TEMP -Force | Out-Null
+./gradlew.bat --no-daemon :app:testDebugUnitTest :app:lintDebug :app:assembleDebug
+```
+
+Linux and macOS:
+
+```bash
+bash gradlew --no-daemon :app:testDebugUnitTest :app:lintDebug :app:assembleDebug
+```
+
+The Debug APK is written to `app/build/outputs/apk/debug/app-debug.apk`. The application ID remains `com.streamcap.mobile` for compatibility with existing installations and data.
+
+## Developer Guide
+
+Start with [CONTRIBUTING.md](CONTRIBUTING.md). Read [ARCHITECTURE.md](ARCHITECTURE.md) before changing dependency injection, recording lifecycle or data boundaries.
+
+Production code is under `app/src/main/java/com/streamcap/mobile/`:
+
+- `app/`: Hilt root graph and Android entry points.
+- `data/`: Room, preferences, network policy and repositories.
+- `platform/`: platform identities, aliases and resolver construction.
+- `service/`: background monitoring, recording coordination, recovery and publication.
+- `storage/`: recording files, MediaStore, export, deletion and segment discovery.
+- `ui/`: Compose screens and Hilt ViewModels.
+
+To add a platform, update `PlatformCatalog` and add JVM tests for URL recognition, aliases and resolver selection. Preserve recording Intent actions and Room schema compatibility; database changes require a migration.
+
+## Tests
+
+Run the checks relevant to the change. Cross-module changes should pass:
+
+```bash
+bash gradlew --no-daemon :app:testDebugUnitTest :app:lintDebug :app:assembleDebug :app:assembleRelease
+```
+
+Instrumentation tests require a connected device or emulator. Real recording tests require an explicit authorized room ID and may create media files. Do not test rooms without permission to record them. Device test setup is documented in [CONTRIBUTING.md](CONTRIBUTING.md).
+
+## License
+
+Application source is licensed under [Apache License 2.0](LICENSE); see [NOTICE](NOTICE) for attribution. Third-party components retain their own licenses. FFmpegKit is an LGPLv3 build and its redistribution status is tracked separately from the application license. See [THIRD_PARTY.md](THIRD_PARTY.md) and [FFMPEG-LICENSE.md](FFMPEG-LICENSE.md).
+
+## Contributing
+
+Report reproducible issues through [GitHub Issues](https://github.com/SRiftX/casttrace-android/issues) and read [CONTRIBUTING.md](CONTRIBUTING.md) before opening a pull request. Remove cookies, account details, device identifiers and private recordings from reports.
diff --git a/README.md b/README.md
index 862b1b1..ae68cd2 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# CastTrace Android
+[简体中文](README.md) | [English](README.en.md)
+
@@ -12,9 +14,26 @@ CastTrace 是一款 Android 多平台直播监控和录制工具,使用 Kotlin
本项目参考了 [StreamCap](https://github.com/ihmily/StreamCap) 的平台录制思路,是独立维护的 Android 项目,并非 StreamCap 官方移动端;上游平台支持范围不代表本项目全部支持。
+
+ 界面截图 ·
+ 下载 APK ·
+ 功能 ·
+ 从源码构建 ·
+ 开发入口 ·
+ 参与和反馈
+
+
+## 界面截图
+
+
+
+
+
+
+
## 下载 APK
-前往 [GitHub Releases](https://github.com/SRiftX/casttrace-android/releases) 查看 APK。只有 FFmpeg 完整对应源码通过核验后,Release 工作流才会发布正式 APK。目前源码清单仍将公开二进制分发标记为未就绪,因此尚无正式 APK 下载。门槛和发布步骤见 [RELEASING.md](RELEASING.md)。
+前往 [GitHub Releases](https://github.com/SRiftX/casttrace-android/releases) 下载 APK 和校验文件。应用支持 Android 8.0+,目前提供 `arm64-v8a` 与 `x86_64`。APK 使用 CastTrace 正式签名,可通过系统安装器覆盖旧版并保留应用数据。Release 同时提供应用源码、FFmpeg 对应源码材料、兼容 AAR 和 SHA-256 清单。发布门槛和步骤见 [RELEASING.md](RELEASING.md)。
## 功能
@@ -39,7 +58,7 @@ CastTrace 是一款 Android 多平台直播监控和录制工具,使用 Kotlin
- JDK 17
- Android SDK Platform 35 和 Build Tools 35.0.0
- Android 8.0(API 26)及以上;APK 仅包含 `arm64-v8a` 和 `x86_64`
-- FFmpegKit 7.1.6 AAR,SHA-256 必须与下方固定值一致
+- 开发构建使用 FFmpegKit 7.1.6 Maven AAR,SHA-256 必须与下方固定值一致。正式 Release 从锁定源码构建 FFmpegKit,并通过 `CASTTRACE_FFMPEG_AAR_PATH` 提供给 Gradle;两种 AAR 不声明逐字节相同。
克隆仓库并下载固定版本 AAR。AAR 不提交到 Git,Gradle 和 CI 会校验它的 SHA-256。
@@ -53,6 +72,20 @@ curl --fail --silent --show-error --location --proto '=https' --proto-redir '=ht
echo 'e80e5ee52248a3dcb1dda0524dd784fe4bbb212dcd4d575e82e15d21a002d860 app/libs/ffmpeg-kit-https-7.1.6.aar' | sha256sum --check
```
+Windows PowerShell:
+
+```powershell
+git clone https://github.com/SRiftX/casttrace-android.git
+Set-Location casttrace-android
+New-Item -ItemType Directory -Path app\libs -Force | Out-Null
+Invoke-WebRequest `
+ 'https://repo.maven.apache.org/maven2/dev/ffmpegkit-maintained/ffmpeg-kit-https/7.1.6/ffmpeg-kit-https-7.1.6.aar' `
+ -OutFile app\libs\ffmpeg-kit-https-7.1.6.aar
+$expected = 'e80e5ee52248a3dcb1dda0524dd784fe4bbb212dcd4d575e82e15d21a002d860'
+$actual = (Get-FileHash app\libs\ffmpeg-kit-https-7.1.6.aar -Algorithm SHA256).Hash.ToLowerInvariant()
+if ($actual -ne $expected) { throw "Unexpected FFmpegKit AAR SHA-256: $actual" }
+```
+
设置 `ANDROID_HOME` 指向本机 Android SDK。Windows 上若 Gradle 报 `Unable to establish loopback connection`,请使用短且可写的临时目录后再构建:
```powershell
@@ -107,7 +140,7 @@ bash gradlew --no-daemon :app:assembleDebugAndroidTest
## 许可证
-应用源码采用 [Apache License 2.0](LICENSE),归属说明见 [NOTICE](NOTICE)。第三方组件仍采用各自许可证。FFmpegKit 是 LGPLv3 构建,其完整对应源码和二进制分发状态与应用许可证分别核验。发布前请查看 [THIRD_PARTY.md](THIRD_PARTY.md)。
+应用源码采用 [Apache License 2.0](LICENSE),归属说明见 [NOTICE](NOTICE)。第三方组件仍采用各自许可证。FFmpegKit 是 LGPLv3 构建,其完整对应源码和二进制分发状态与应用许可证分别核验。发布前请查看 [THIRD_PARTY.md](THIRD_PARTY.md) 和 [FFMPEG-LICENSE.md](FFMPEG-LICENSE.md)。
## 参与和反馈
diff --git a/RELEASING.md b/RELEASING.md
index 8f2079d..8540e88 100644
--- a/RELEASING.md
+++ b/RELEASING.md
@@ -1,54 +1,70 @@
-# Android APK 发布
-
-正式 APK 只能从已合入 `main` 的版本标签构建。发布工作流会运行 JVM 单测和 lint,校验 FFmpeg AAR、对应源码分发状态及签名证书,最后把 APK、应用源码、FFmpeg 源码材料和 SHA-256 校验文件放入同一 GitHub Release。
-
-## 当前发布门槛
-
-`third_party/ffmpeg/manifest.json` 中的 `redistributionReady` 必须为 `true`,`sourceGaps` 必须为空。当前清单仍为 `false`,原因是上游构建缓存和浮动子模块等原生源码输入尚未核实。因此 tag 工作流会停止,不会上传或发布 APK。单独签名成功或收集到源码归档都不等于该门槛已通过。
-
-关闭门槛前,维护者必须取得或自行构建与实际 AAR 对应的完整 LGPL 源码和构建输入,校验归档,并更新清单、`THIRD_PARTY.md`、README 与许可证说明。不能只把未核实的源码材料包标记为完整对应源码。
-
-## GitHub Actions 配置
-
-发布工作流需要仓库 Actions secrets。它们只用于签名,不应放在普通变量、仓库文件或命令行参数中:
-
-| Secret | 内容 |
-| --- | --- |
-| `CASTTRACE_KEYSTORE_BASE64` | 正式 `.p12` 密钥文件的 Base64 内容 |
-| `CASTTRACE_STORE_PASSWORD` | 密钥库密码 |
-| `CASTTRACE_KEY_ALIAS` | 正式密钥别名,当前为 `casttrace-release` |
-| `CASTTRACE_KEY_PASSWORD` | 密钥密码 |
-
-需由仓库所有者在 GitHub 仓库 Settings → Secrets and variables → Actions 添加。`CASTTRACE_KEYSTORE_BASE64` 必须是单行 Base64,不要加 PEM 头、换行或空格。私钥不进入 GitHub Release、构建日志或生成的源码包。签名身份必须继续与既有安装兼容,不能临时生成新密钥替代。
-
-## 发布步骤
-
-1. 更新 `versionName`、`versionCode` 和 `CHANGELOG.md`,确认 README 与许可证材料反映本次发布状态。
-2. 确保改动已合入 `main`,并通过 `:app:testDebugUnitTest`、`:app:lintDebug`、`:app:assembleRelease` 以及必要的设备回归。
-3. 确认源码清单通过发布门槛,并验证正式密钥已配置且证书指纹与既有身份一致。
-4. 创建并推送匹配 `versionName` 的标签,例如 `v0.2.14`。
-5. GitHub Actions 会再次验证标签位于 `main` 历史、版本号匹配、测试通过、签名正确,然后创建 GitHub Release。
-6. 下载 Release 中的 APK、应用源码包、FFmpeg 对应源码材料包和 `SHA256SUMS`,核对文件哈希与 APK 签名后再对外宣传。
-
-Release 资产应包含:
-
-- `casttrace--release.apk`
-- `casttrace--source.zip`
-- `casttrace-ffmpeg-7.1.6-source-materials.zip`
-- `SHA256SUMS`
-
-任何一个门槛失败,工作流都不会创建包含 APK 的 Release。当前不要为源码状态未就绪的版本创建正式标签。
-
-## 本地签名验证
-
-仓库维护者可在本机使用受保护的密钥生成候选 APK:
-
-```powershell
-$env:ANDROID_HOME = "$env:LOCALAPPDATA\Android\Sdk"
-$env:TEMP = 'C:\tmp'
-$env:TMP = 'C:\tmp'
-New-Item -ItemType Directory -Path $env:TEMP -Force | Out-Null
-./scripts/Build-SignedRelease.ps1
+# Release Process
+
+This repository publishes CastTrace APKs as GitHub Releases. A release tag is
+accepted only when it matches `versionName` in `app/build.gradle.kts`, points to
+a commit on `main`, passes the FFmpeg corresponding-source gate, and produces an
+APK signed with the established CastTrace release certificate.
+
+## Release prerequisites
+
+- The release commit is merged into `main` and its Android checks pass.
+- `third_party/ffmpeg/source-build.json` pins every source archive, build option,
+ patch, ABI and toolchain used by the release FFmpegKit build.
+- The GitHub Actions repository secrets are configured:
+ - `CASTTRACE_KEYSTORE_BASE64`: base64-encoded PKCS#12 signing keystore.
+ - `CASTTRACE_STORE_PASSWORD`: keystore password.
+ - `CASTTRACE_KEY_ALIAS`: signing key alias.
+ - `CASTTRACE_KEY_PASSWORD`: signing key password.
+- The configured certificate SHA-256 is
+ `D39B0394EE312DE5B1F25F8A215A0E81CA9C47229835D2F96DD0187694523C57`.
+
+Do not commit a keystore or password. Keep an offline backup of the signing key;
+Android updates must keep the same application id and signing identity.
+
+## Local release checks
+
+Use Ubuntu 24.04, JDK 17, Android SDK Platform 35, Build Tools 35.0.0, NDK
+26.2.11394342 (r26c), Python 3 and `gettext`. Download or install the pinned
+sources only through the tracked build recipe. From the repository root:
+
+```bash
+export ANDROID_HOME="$ANDROID_HOME"
+export ANDROID_NDK_ROOT="$ANDROID_HOME/ndk/26.2.11394342"
+bash scripts/build_ffmpeg_source.sh
+export CASTTRACE_FFMPEG_AAR_PATH="$PWD/build/compliance/ffmpeg-7.1.6/ffmpeg-kit-https-7.1.6.aar"
+export CASTTRACE_FFMPEG_AAR_SHA256="$(sha256sum "$CASTTRACE_FFMPEG_AAR_PATH" | cut -d' ' -f1)"
+python scripts/prepare_ffmpeg_compliance.py --aar "$CASTTRACE_FFMPEG_AAR_PATH"
+python scripts/verify_release_readiness.py
+bash gradlew --no-daemon :app:testDebugUnitTest :app:lintDebug :app:assembleDebug :app:assembleRelease
```
-脚本会验证 APK 签名并输出 SHA-256。此本地步骤只用于验证构建,不能绕过源码分发门槛,也不代表该 APK 可以公开发布。密钥保管细节见仓库所有者本机维护的签名说明。
+The release workflow repeats these checks from a clean runner. Its APK uses the
+source-built FFmpegKit AAR; ordinary local development may use the pinned Maven
+AAR described in `app/libs/README.md`. The Maven artifact is not claimed to be
+byte-for-byte equivalent to the source build.
+
+## Publish
+
+1. Update `versionName` and `versionCode` in `app/build.gradle.kts`, then update
+ `CHANGELOG.md` and user-facing release notes.
+2. Merge the release commit into `main`; wait for Android checks to pass.
+3. Confirm the corresponding-source policy and signing secrets are ready.
+4. Create and push the matching annotated tag, for example:
+
+ ```bash
+ git tag -a v0.2.14 -m "CastTrace 0.2.14"
+ git push origin v0.2.14
+ ```
+
+5. Follow the `Publish Android APK` Actions run. The workflow verifies the
+ source inputs, builds FFmpegKit, runs tests and lint, signs the APK, checks
+ its package/version/certificate, and creates the GitHub Release.
+6. Verify every uploaded asset and its SHA-256 using `SHA256SUMS`. The release
+ contains the APK, the Gradle-compatible FFmpeg AAR, CastTrace source, FFmpeg
+ corresponding-source materials and checksums.
+7. Install the APK over an existing CastTrace installation with `adb install
+ -r` and verify app startup, native FFmpeg loading, playback and recording
+ before announcing the release.
+
+The APK is intended for Android 8.0+ on `arm64-v8a` and `x86_64`. Keep the
+repository public if the Release is intended for unauthenticated downloads.
diff --git a/THIRD_PARTY.md b/THIRD_PARTY.md
index 01df3b9..8d22b30 100644
--- a/THIRD_PARTY.md
+++ b/THIRD_PARTY.md
@@ -14,18 +14,21 @@ are bundled in `app/src/main/assets/licenses/rust-srec-MIT.txt`.
JVM parser tests use JSON-java 20240303 (public domain / Unlicense,
https://github.com/stleary/JSON-java); Android uses its built-in `org.json` API.
-The local FFmpegKit binary is excluded from Git. Its SHA-256 matches Maven
-Central `dev.ffmpegkit-maintained:ffmpeg-kit-https:7.1.6` exactly. This is the
-LGPLv3 HTTPS build containing FFmpeg n7.1.5, with no enable-gpl/nonfree flags.
-It is not Apache-2.0 licensed. Full notices are bundled in the application's
-offline Settings / Open-source licenses screen.
+The development FFmpegKit AAR is excluded from Git and downloaded from Maven
+Central as `dev.ffmpegkit-maintained:ffmpeg-kit-https:7.1.6`. Its SHA-256 is
+pinned in Gradle. Official Release APKs use an AAR built from the source commits
+and patches pinned in `third_party/ffmpeg/source-build.json`; the source-built
+AAR is not claimed to be byte-for-byte identical to Maven Central's artifact.
+Both are LGPLv3 HTTPS builds containing FFmpeg n7.1.5, with no enable-gpl or
+nonfree flags. Full notices are bundled in the application's offline Settings
+/ Open-source licenses screen and in the Release source-material archive.
-The exact upstream native source cache and floating GnuTLS gnulib input remain
-unverified, so public binary redistribution is still blocked. Collected source
-archives are investigation materials, not a complete corresponding-source claim.
-See `app/libs/README.md` and `third_party/ffmpeg/manifest.json` for
-the provenance, obligations and remaining gap.
-Publishing this source repository does not automatically publish an APK.
+FFmpegKit's binary provenance, license scope, source-build procedure and
+redistribution gate are documented in `FFMPEG-LICENSE.md`. The Maven artifact
+evidence is in `third_party/ffmpeg/manifest.json`; the release source build and
+its input hashes are pinned in `third_party/ffmpeg/source-build.json`. The tag
+workflow builds the AAR from those sources and will not publish an APK unless
+the resulting source materials and binary checks pass.
Upstream project references:
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 38855e0..73f3517 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -80,11 +80,17 @@ ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
+val mavenFfmpegSha256 = "E80E5EE52248A3DCB1DDA0524DD784FE4BBB212DCD4D575E82E15D21A002D860"
+val ffmpegArtifactPath = providers.environmentVariable("CASTTRACE_FFMPEG_AAR_PATH")
+ .orElse(layout.projectDirectory.file("libs/ffmpeg-kit-https-7.1.6.aar").asFile.absolutePath)
+val ffmpegArtifact = providers.provider { file(ffmpegArtifactPath.get()) }
+val expectedFfmpegSha256 = providers.environmentVariable("CASTTRACE_FFMPEG_AAR_SHA256")
+ .orElse(mavenFfmpegSha256)
+
val verifyFfmpegArtifact by tasks.registering {
- val artifact = layout.projectDirectory.file("libs/ffmpeg-kit-https-7.1.6.aar")
- inputs.file(artifact)
+ inputs.file(ffmpegArtifact)
doLast {
- val binary = artifact.asFile
+ val binary = ffmpegArtifact.get()
check(binary.isFile) { "Missing FFmpegKit AAR: see app/libs/README.md; do not download an unverified replacement." }
val digest = MessageDigest.getInstance("SHA-256")
binary.inputStream().use { input ->
@@ -96,8 +102,10 @@ val verifyFfmpegArtifact by tasks.registering {
}
}
val actual = digest.digest().joinToString("") { "%02X".format(it) }
- check(actual == "E80E5EE52248A3DCB1DDA0524DD784FE4BBB212DCD4D575E82E15D21A002D860") {
- "FFmpegKit AAR checksum differs from the reviewed local artifact. Verify provenance before updating the pin."
+ val expected = expectedFfmpegSha256.get().uppercase()
+ check(expected.matches(Regex("[A-F0-9]{64}"))) { "CASTTRACE_FFMPEG_AAR_SHA256 must be a SHA-256 digest." }
+ check(actual == expected) {
+ "FFmpegKit AAR checksum differs from CASTTRACE_FFMPEG_AAR_SHA256. Verify provenance before building."
}
}
}
@@ -106,12 +114,12 @@ tasks.named("preBuild").configure { dependsOn(verifyFfmpegArtifact) }
val compatibleFfmpegArtifact = layout.buildDirectory.file("ffmpeg/ffmpeg-kit-https-7.1.6-compatible.aar")
val prepareCompatibleFfmpeg by tasks.registering {
dependsOn(verifyFfmpegArtifact)
- inputs.file(layout.projectDirectory.file("libs/ffmpeg-kit-https-7.1.6.aar"))
+ inputs.file(ffmpegArtifact)
outputs.file(compatibleFfmpegArtifact)
doLast {
val target = compatibleFfmpegArtifact.get().asFile
target.parentFile.mkdirs()
- ZipFile(layout.projectDirectory.file("libs/ffmpeg-kit-https-7.1.6.aar").asFile).use { source ->
+ ZipFile(ffmpegArtifact.get()).use { source ->
ZipOutputStream(target.outputStream()).use { output ->
source.entries().asSequence().forEach { entry ->
val bytes = source.getInputStream(entry).use { it.readBytes() }
diff --git a/app/libs/README.md b/app/libs/README.md
index 894f100..0f9030d 100644
--- a/app/libs/README.md
+++ b/app/libs/README.md
@@ -1,8 +1,10 @@
# Local FFmpegKit Dependency
-The application currently references `ffmpeg-kit-https-7.1.6.aar` from this
-directory. This local binary is not committed. Place a verified copy here
-before running Gradle; the original development workspace retains its copy.
+Local development uses `ffmpeg-kit-https-7.1.6.aar` from this directory. This
+Maven artifact is not committed. Place a verified copy here before running
+Gradle. Official release builds provide a separately source-built AAR through
+`CASTTRACE_FFMPEG_AAR_PATH` and its digest through
+`CASTTRACE_FFMPEG_AAR_SHA256`.
SHA256 of the development binary:
@@ -10,7 +12,7 @@ SHA256 of the development binary:
E80E5EE52248A3DCB1DDA0524DD784FE4BBB212DCD4D575E82E15D21A002D860
```
-The checksum matches Maven Central exactly:
+The development checksum matches Maven Central exactly:
`dev.ffmpegkit-maintained:ffmpeg-kit-https:7.1.6`.
Download URL:
@@ -18,9 +20,10 @@ https://repo.maven.apache.org/maven2/dev/ffmpegkit-maintained/ffmpeg-kit-https/7
Gradle and CI enforce this pin. This is the LGPLv3 build containing FFmpeg
n7.1.5 for arm64-v8a and x86_64. Do not substitute an arbitrary artifact.
-The upstream native source cache remains unavailable, so public binary
-redistribution is not yet cleared. See `THIRD_PARTY.md`
-and `third_party/ffmpeg/manifest.json` for evidence and outstanding source gaps.
+The formal Release does not redistribute this downloaded Maven binary. It uses
+the pinned source build and includes corresponding-source materials; see
+`RELEASING.md`, `FFMPEG-LICENSE.md` and
+`third_party/ffmpeg/source-build.json`.
The build uses a generated compatibility AAR under `app/build/ffmpeg/`.
`prepareCompatibleFfmpeg` changes only ELF64 `PT_GNU_RELRO.p_memsz` where
@@ -32,7 +35,8 @@ trims only that unmapped padding; all RELRO file data, code, load segments,
alignment and license files are preserved. The x86_64 artifact also needs
this correction in `libavdevice.so` and `libswresample.so`.
-This is a local binary modification, not an upstream rebuild. Any future
-artifact update must review/remove this transformation and rerun device
-loading, remuxing, decoding and seek tests, including a 16 KiB-page device.
-The source/compliance gaps above still apply to the derived artifact.
+This is a local compatibility transformation, not a source change to FFmpeg.
+The official release publishes the derived compatible AAR alongside the
+corresponding source materials and application build configuration. Any future
+artifact update must review this transformation and rerun device loading,
+remuxing, decoding and seek tests, including a 16 KiB-page device.
diff --git a/screenshots/live-reminders.png b/screenshots/live-reminders.png
new file mode 100644
index 0000000000000000000000000000000000000000..7796a44ae797c7813c988baac858719ed770dbe8
GIT binary patch
literal 90201
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