Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

- One project, `src/FFmpegKit.Android`, produces all eight packages `FFmpegKit.Net.<Variant>.Android` — `Audio|Full|FullGpl|Https|HttpsGpl|Min|MinGpl|Video`, selected by `FFmpegKitBuildType`.
- Native binaries come from the community fork **[ffmpegkit-maintained/ffmpeg](https://github.com/ffmpegkit-maintained/ffmpeg)** via Maven Central (`dev.ffmpegkit-maintained`). `arthenica/ffmpeg-kit` is archived with its assets deleted and `ffmpeg-kit-next` ships no binaries — do not point anything back at them.
- **Two version schemes, never interchangeable.** `FFmpegVersion` (8.1.3) is the FFmpeg inside and what package versions are based on; `FFmpegKitNativeVersion` (8.1.9) is the fork release that names the `.aar`. Both live in `Directory.Build.props`; `build/native-versions.tsv` is the single source of truth for the pairing (`6.1.6↔6.0.3`, `7.1.5↔7.1.6`, `8.1.2↔8.1.7`, `8.1.3↔8.1.9`). Convert with `./build/resolve-versions.sh --ffmpeg 8.1.3` or `--ffmpegkit 8.1.9`.
- **Two version schemes, never interchangeable.** `FFmpegVersion` (8.1.3) is the FFmpeg inside and what package versions are based on; `FFmpegKitNativeVersion` (8.1.9) is the fork release that names the `.aar`. Both live in `Directory.Build.props`; `build/native-versions.tsv` is the single source of truth for the pairing (`6.1.6↔6.0.4`, `7.1.5↔7.1.7`, `8.1.2↔8.1.7`, `8.1.3↔8.1.9`). Convert with `./build/resolve-versions.sh --ffmpeg 8.1.3` or `--ffmpegkit 8.1.9`.
- Package version = `<FFmpeg version>.<binding revision>`, e.g. `8.1.3.1`. Three tracks publish in parallel; all ship `arm64-v8a` + `x86_64` at minSdk 24, never 32-bit.
- Prerequisites: .NET 8, 9 and 10 SDKs each with the Android workload (the SDK is chosen by the *working directory's* `global.json`), plus Python 3 for the merge step.

Expand Down Expand Up @@ -44,7 +44,7 @@ Everything runs on **ubuntu-latest**. `pr.yml` and `release.yml` both call the r

- Pull request → pack all eight variants as `<FFmpegVersion>-beta.<pr>.<run>`, package tests, MAUI sample builds (net8 + net10), emulator smoke tests, then publish the betas to nuget.org. Forked PRs build and test but skip publishing. Betas cannot be deleted, only unlisted.
- Merging `docs/release-notes/<version>.md` to `main` is the release: `auto-release.yml` tags the merge `v<version>` and dispatches `release.yml`, whose `guard` job proves the commit is an ancestor of the default branch before anything publishes.
- Tags name the **FFmpeg** version: `v6.1.6.4` publishes 6.1.6.4 and binds FFmpegKit 6.0.3 from the mapping; a version outside `build/native-versions.tsv` fails the release with the list of known builds.
- Tags name the **FFmpeg** version: `v6.1.6.5` publishes 6.1.6.5 and binds FFmpegKit 6.0.4 from the mapping; a version outside `build/native-versions.tsv` fails the release with the list of known builds.
- `upstream-drift.yml` (daily) runs `build/check-upstream.sh` over `build/upstream.tsv` and files one issue per group.

## Testing
Expand Down
4 changes: 2 additions & 2 deletions .github/instructions/native-versions.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ The `.aar` files come from Maven Central (`dev.ffmpegkit-maintained`) and are fe

1. **Establish the FFmpeg version the release actually contains.** Read it out of the shipped `libavcodec.so` (`jni/arm64-v8a/` inside the `.aar`), the way `.github/scripts/native-build-info.sh` does. Upstream release prose mentions other FFmpeg versions in passing and must not be used as the source.
2. **Record the checksum baseline:** `./build/update-checksums.sh <ffmpegkit version>` writes `build/checksums/<ffmpegkit>.sha256` (Maven Central `.sha256` sidecars where published, download-and-hash otherwise). Review the diff and commit it. This is deliberately never run in CI — CI verifies against a baseline a human recorded.
3. **Add the mapping row** to `build/native-versions.tsv`: `<ffmpeg>\t<ffmpegkit>`, tab-separated, keeping the existing comment header. The file is append-only — rows that have shipped stay so their tags remain releasable.
4. **Then** bump `FFmpegVersion` and `FFmpegKitNativeVersion` in `Directory.Build.props` (both, together — they are different schemes) and fetch: `./src/FFmpegKit.Android/Jars/FetchJars.sh <ffmpegkit version>`.
3. **Add the mapping row** to `build/native-versions.tsv`: `<ffmpeg>\t<ffmpegkit>`, tab-separated, keeping the existing comment header. There is one row per FFmpeg version, because the lookup stops at the first match and a test requires both columns to be unique. A new FFmpeg gets a new row. A respin of the same FFmpeg replaces that row: note the old pair in the header comment, keep its checksum baseline, and say in the release note that the old FFmpegKit release can no longer be built from `main`. Existing tags are unaffected, because a release reads the file as it stood at its tag. Never drop a track.
4. **Then**, if this is the default line, bump `FFmpegVersion` and `FFmpegKitNativeVersion` in `Directory.Build.props` (both, together — they are different schemes). Older lines leave the props alone. Either way, fetch: `./src/FFmpegKit.Android/Jars/FetchJars.sh <ffmpegkit version>`.
5. Verify and pack: `./src/FFmpegKit.Android/Jars/FetchJars.sh --verify`, then `./src/FFmpegKit.Android/BuildNugets.sh`, then `dotnet test tests/FFmpegKit.Android.PackageTests` (it asserts the mapping and the props agree).

## Rules
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ on:
native-version:
description: >
FFmpegKit native version to bind against. Defaults to FFmpegKitNativeVersion in
Directory.Build.props; set it to build a package for an older LTS line, e.g. 6.0.3.
Directory.Build.props; set it to build a package for an older LTS line, e.g. 6.0.4.
required: false
default: ''
type: string
Expand Down
18 changes: 17 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ jobs:
version: ${{ steps.resolve.outputs.version }}
native-version: ${{ steps.resolve.outputs.native-version }}
ffmpeg-version: ${{ steps.resolve.outputs.ffmpeg-version }}
default-track: ${{ steps.resolve.outputs.default-track }}
prerelease: ${{ steps.resolve.outputs.prerelease }}
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -83,6 +84,15 @@ jobs:
echo "ffmpeg-version=${ffmpeg}" >> "$GITHUB_OUTPUT"
echo "FFmpeg ${ffmpeg} (FFmpegKit ${ffmpegkit})" >> "$GITHUB_STEP_SUMMARY"

# FFmpegVersion in this tag's Directory.Build.props is the default track, so this
# follows the default without a second list of versions to keep up to date.
default_ffmpeg=$(sed -n 's:.*<FFmpegVersion>\(.*\)</FFmpegVersion>.*:\1:p' Directory.Build.props | head -1)
if [ "${ffmpeg}" = "${default_ffmpeg}" ]; then
echo "default-track=true" >> "$GITHUB_OUTPUT"
else
echo "default-track=false" >> "$GITHUB_OUTPUT"
fi

case "${version}" in
*-*) prerelease=true ;;
*) prerelease=false ;;
Expand Down Expand Up @@ -238,8 +248,14 @@ jobs:
# The parent repositories pin these packages by exact version; tell them what just shipped
# rather than leaving it to their daily drift check. Who cares, and about which packages,
# lives in build/parents.tsv. Skips itself quietly while PARENT_ISSUE_PAT does not exist.
#
# Parents pin the default track, and notify-parents.sh keeps one open issue per package: an
# older track's release would comment on that issue and retitle it to the older version, telling
# the parent to move down. The check is here because notify-parents.* are kept byte-identical
# across the repositories, and this is the only one publishing parallel tracks on one tag prefix.
notify-parents:
needs: publish
needs: [version, publish]
if: needs.version.outputs.default-track == 'true'
uses: ./.github/workflows/notify-parents.yml
with:
tag: ${{ github.ref_name }}
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ The fork currently publishes three lines, each with all eight variants:

| FFmpegKit | Bundled FFmpeg | ABIs | minSdk |
| --- | --- | --- | --- |
| `6.0.3` | `n6.1.6` | `arm64-v8a`, `x86_64` | 24 |
| `7.1.6` | `n7.1.5` | `arm64-v8a`, `x86_64` | 24 |
| `6.0.4` | `n6.1.6` | `arm64-v8a`, `x86_64` | 24 |
| `7.1.7` | `n7.1.5` | `arm64-v8a`, `x86_64` | 24 |
| `8.1.9` | `n8.1.3` | `arm64-v8a`, `x86_64` | 24 |

**FFmpegKit's version is not FFmpeg's.** FFmpegKit `8.1.9` packages FFmpeg `n8.1.3`; the fork versions its own releases independently of the FFmpeg it pins. The bundled version above is read out of the shipped `libavcodec.so`, and every generated release note states it, because upstream's own notes mention other FFmpeg versions in passing and are easy to misread.
Expand All @@ -52,18 +52,18 @@ Both constraints are surfaced at build time in consuming apps by a small `.targe

### Releasing an older line

Tags name the FFmpeg version: **`v6.1.6.4` publishes `6.1.6.4`** and builds against the FFmpegKit release that packages FFmpeg 6.1.6, looked up in [`build/native-versions.tsv`](build/native-versions.tsv). The fourth component is the binding revision and any prerelease suffix is ignored when resolving (`v8.1.2.4-rc.1` → FFmpeg `8.1.2`). A tag naming a version that is not in the mapping fails the release with the list of known builds, so an old-style tag like `v8.1.7.4` cannot be published by mistake. No branch or `Directory.Build.props` edit is needed.
Tags name the FFmpeg version: **`v6.1.6.5` publishes `6.1.6.5`** and builds against the FFmpegKit release that packages FFmpeg 6.1.6, looked up in [`build/native-versions.tsv`](build/native-versions.tsv). The fourth component is the binding revision and any prerelease suffix is ignored when resolving (`v8.1.2.4-rc.1` → FFmpeg `8.1.2`). A tag naming a version that is not in the mapping fails the release with the list of known builds, so an old-style tag like `v8.1.7.4` cannot be published by mistake. No branch or `Directory.Build.props` edit is needed.

Locally, pass the native version as the second argument:

```sh
./src/FFmpegKit.Android/Jars/FetchJars.sh 6.0.3 # .aar files are named after the FFmpegKit release
./src/FFmpegKit.Android/BuildNugets.sh 6.1.6.4 6.0.3 # package version, FFmpegKit release
./src/FFmpegKit.Android/Jars/FetchJars.sh 6.0.4 # .aar files are named after the FFmpegKit release
./src/FFmpegKit.Android/BuildNugets.sh 6.1.6.5 6.0.4 # package version, FFmpegKit release
```

NuGet orders `8.1.3` above `6.1.6`, so publishing an older line later does not change what `dotnet add package` resolves by default.

`FFmpegKitConfig` also needs the two `smart-exception` jars at runtime. They are not bundled in the `.aar`, and its `.pom` declares them only from FFmpegKit `8.1.9` on, which does nothing for a NuGet consumer, so they are fetched separately and embedded into the binding.
`FFmpegKitConfig` also needs the two `smart-exception` jars at runtime. They are not bundled in the `.aar`, and its `.pom` declares them only from FFmpegKit `6.0.4`, `7.1.7` and `8.1.9` on, which does nothing for a NuGet consumer, so they are fetched separately and embedded into the binding.

## License

Expand Down Expand Up @@ -111,8 +111,8 @@ Three FFmpegKit lines are published in parallel, so you can pin to the FFmpeg ge
| Track | FFmpeg | From FFmpegKit | Install |
| --- | --- | --- | --- |
| **`8.*`** (recommended) | `n8.1.3` | 8.1.9 | `dotnet add package FFmpegKit.Net.Video.Android --version "8.*"` |
| `7.*` | `n7.1.5` | 7.1.6 | `dotnet add package FFmpegKit.Net.Video.Android --version "7.*"` |
| `6.*` | `n6.1.6` | 6.0.3 | `dotnet add package FFmpegKit.Net.Video.Android --version "6.*"` |
| `7.*` | `n7.1.5` | 7.1.7 | `dotnet add package FFmpegKit.Net.Video.Android --version "7.*"` |
| `6.*` | `n6.1.6` | 6.0.4 | `dotnet add package FFmpegKit.Net.Video.Android --version "6.*"` |

A package version is **`<FFmpeg version>.<binding revision>`** — `8.1.3.1` is FFmpeg `8.1.3`, binding revision `1`. It deliberately names FFmpeg rather than FFmpegKit, because FFmpegKit's own release numbers do not track FFmpeg: FFmpegKit `8.1.9` packages FFmpeg `n8.1.3`. [`build/native-versions.tsv`](build/native-versions.tsv) maps between the two and is what the release workflow uses to turn a tag into the `.aar` to download.

Expand Down
10 changes: 10 additions & 0 deletions build/checksums/6.0.4.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
54bbc7fca3f27811a9289eaceac5b94837f87bd1d97d0f98148d8cbedcfa93c1 ffmpeg-kit-audio-6.0.4.aar
e4ca28c45b8d6a17b3c002313e3d112cd5d03ede6648fbcc4f1b508bc19f27b2 ffmpeg-kit-full-6.0.4.aar
7453e9c43749cd44689d6da49dbb24b5061f74d1c8fe0858e3866a7c5daa4d2c ffmpeg-kit-full-gpl-6.0.4.aar
6b6d70012861ca22553f4114f2387e07fccb0ea54b85d9c488986be9328ee1f2 ffmpeg-kit-https-6.0.4.aar
fc9f93989188cdce5b0a6d87014c39a44bb68989e4148edfb5c02368a3f6ecce ffmpeg-kit-https-gpl-6.0.4.aar
8447360873e1d875a0d187a0abf6d26de1950e39692abdc608b141abd404e181 ffmpeg-kit-min-6.0.4.aar
619ae8c59010d1aeaf82b15bc481602ca08b6a21adc07857b875140c8b1b9bc5 ffmpeg-kit-min-gpl-6.0.4.aar
782379a68c78e5c9481dbb1db15f2d97760bc279ad2d020295e5626295dd5538 ffmpeg-kit-video-6.0.4.aar
1cad0fb4dfa01755a014331b5ed199281d2c3fab5aca5c9d7abd0b41d0ec3f7b smart-exception-common-0.2.1.jar
5b96aaa5f191dedbef72fb0c38f1a2b01807920afc0d92a75a2acd6e0cc7703c smart-exception-java-0.2.1.jar
10 changes: 10 additions & 0 deletions build/checksums/7.1.7.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
a6cdcaf60020f1365919199c84cd5a67b65f00c1a5ffdf376b6bae1e23deaa4b ffmpeg-kit-audio-7.1.7.aar
5235d56ba510bc7302427968c720941bf6de29620f4837ee7f60ad5b8c07053d ffmpeg-kit-full-7.1.7.aar
07ebecf09e6adf1bec3b6ba589220b641919617a14be171be0e628f4b7aef88c ffmpeg-kit-full-gpl-7.1.7.aar
10e52c267079df3dbcfcb1017c56d132fd6e7f35e3e38bf7e033d258160da0ac ffmpeg-kit-https-7.1.7.aar
a14664a98b788219bde2219903f762538bdf68a3df0667b4f3ce6ffc9d89ece5 ffmpeg-kit-https-gpl-7.1.7.aar
3b7dd48c2ea980be4bc5f01c6cdfeb54121c73e814aa2d648759d1c1170a0c81 ffmpeg-kit-min-7.1.7.aar
ecd83b4b674c55bda16df2527ddf1f98d62691f5ae8b41d7fe4b2faa1364bc2f ffmpeg-kit-min-gpl-7.1.7.aar
358a5e7dc08038cd9a626a8f363dba8409f43d0e6850fe124abb2bb06d024910 ffmpeg-kit-video-7.1.7.aar
1cad0fb4dfa01755a014331b5ed199281d2c3fab5aca5c9d7abd0b41d0ec3f7b smart-exception-common-0.2.1.jar
5b96aaa5f191dedbef72fb0c38f1a2b01807920afc0d92a75a2acd6e0cc7703c smart-exception-java-0.2.1.jar
10 changes: 7 additions & 3 deletions build/native-versions.tsv
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
# Maps the FFmpeg version a build actually contains to the FFmpegKit release that packages it.
#
# These are two different numbering schemes and they do not track each other: FFmpegKit 8.1.7
# packages FFmpeg n8.1.2, FFmpegKit 7.1.6 packages FFmpeg n7.1.5. Package versions here are based
# packages FFmpeg n8.1.2, FFmpegKit 7.1.7 packages FFmpeg n7.1.5. Package versions here are based
# on the FFmpeg version, because that is what determines behaviour; the FFmpegKit version is only
# needed to name the .aar to download.
#
# Every value below was read from the shipped libavcodec.so, not from upstream release prose,
# which mentions other FFmpeg versions in passing and is easy to misread.
#
# There is one row per FFmpeg version. When FFmpegKit respins the same FFmpeg, its row is replaced,
# so the newest respin is what gets built. Tags are unaffected: a release reads this file as it
# stood at its tag. Replaced so far: 6.1.6 was 6.0.3, 7.1.5 was 7.1.6.
#
# ffmpeg ffmpegkit
6.1.6 6.0.3
7.1.5 7.1.6
6.1.6 6.0.4
7.1.5 7.1.7
8.1.2 8.1.7
8.1.3 8.1.9
3 changes: 2 additions & 1 deletion build/parents.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
# tag-prefix the release tag's prefix - the version follows it (v3.12.1.4 -> prefix "v")
# parent owner/repo of the repository holding the pin
# packages space-separated package ids the parent pins from this repository's release
# A released tag whose prefix matches no row notifies nobody.
# A released tag whose prefix matches no row notifies nobody. Neither does a release on an older
# track: the parent pins the default one, see the notify-parents job in release.yml.
#
# tag-prefix parent packages
v sbokatuk/FFMpegKit.Net FFmpegKit.Net.Full.Android
2 changes: 1 addition & 1 deletion build/update-checksums.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ set -e
#
# Usage:
# build/update-checksums.sh # version from Directory.Build.props
# build/update-checksums.sh 7.1.6 # an older line, e.g. when adding a native-versions.tsv row
# build/update-checksums.sh 7.1.7 # an older line, e.g. when adding a native-versions.tsv row

cd "$(dirname "$0")/.."

Expand Down
Loading
Loading