Skip to content

fix: make video export work on Android 11+#158

Open
cizra wants to merge 1 commit into
Myzel394:masterfrom
cizra:alibi/update-dependencies
Open

fix: make video export work on Android 11+#158
cizra wants to merge 1 commit into
Myzel394:masterfrom
cizra:alibi/update-dependencies

Conversation

@cizra

@cizra cizra commented May 25, 2026

Copy link
Copy Markdown

The original com.arthenica FFmpegKit artifact no longer resolves from Maven Central, so a clean checkout couldn't even build. Once it did build, the export pipeline silently produced empty files, aborted with "No valid media batches available", or hung on stale SAF handles, depending on storage mode and Android version.

Build:

  • Switch app/build.gradle to a maintained fork that keeps the com.arthenica.ffmpegkit API intact, and adapt the few callsites that touched FFmpegKit internals.

Export:

  • Drop empty/invalid batches before invoking FFmpeg, and fail fast if no usable inputs remain instead of feeding it an empty concat list.
  • Reopen SAF input descriptors for each retry; the previous code reused one PFD across all 17 parameter attempts, so once FFmpeg closed it on the first failure the remaining retries had nothing to read.
  • Stage all FFmpeg I/O through ContentResolver-opened file descriptors (fd:<n> paths), with Closeable lifetimes tracked by FFmpegInputPaths/FFmpegOutputTarget.
  • Fix the MediaStore path-rewrite bug on both sides of the pipeline: MediaStore rewrites relative paths starting with '.' (our '.video_recordings' lives on disk as '_.video_recordings') and prefixes pending files with '.pending--', so the raw File paths we reconstructed never matched the actual files. Inputs and outputs now go through the MediaStore URI, which is why users were seeing abandoned 'tmp--*' content:// entries with no usable output file.

Code changes by Claude Opus running inside Pi.dev. I built and tested this commit, it works fine in my phone.

The original com.arthenica FFmpegKit artifact no longer resolves from
Maven Central, so a clean checkout couldn't even build. Once it did
build, the export pipeline silently produced empty files, aborted
with "No valid media batches available", or hung on stale SAF
handles, depending on storage mode and Android version.

Build:

* Switch app/build.gradle to a maintained fork that keeps the
  com.arthenica.ffmpegkit API intact, and adapt the few callsites
  that touched FFmpegKit internals.

Export:

* Drop empty/invalid batches before invoking FFmpeg, and fail fast
  if no usable inputs remain instead of feeding it an empty concat
  list.
* Reopen SAF input descriptors for each retry; the previous code
  reused one PFD across all 17 parameter attempts, so once FFmpeg
  closed it on the first failure the remaining retries had nothing
  to read.
* Stage all FFmpeg I/O through ContentResolver-opened file
  descriptors (`fd:<n>` paths), with Closeable lifetimes tracked by
  FFmpegInputPaths/FFmpegOutputTarget.
* Fix the MediaStore path-rewrite bug on both sides of the pipeline:
  MediaStore rewrites relative paths starting with '.' (our
  '.video_recordings' lives on disk as '_.video_recordings') and
  prefixes pending files with '.pending-<id>-', so the raw File
  paths we reconstructed never matched the actual files. Inputs and
  outputs now go through the MediaStore URI, which is why users were
  seeing abandoned 'tmp-<UUID>-*' content:// entries with no usable
  output file.
@cizra

cizra commented May 25, 2026

Copy link
Copy Markdown
Author

@Myzel394 may I ask for a review?

@Myzel394

Copy link
Copy Markdown
Owner

Hey @cizra,

thanks so much for opening all your PRs! I will take a look at this, but probably not in the near future (maybe around September - October). I'm too busy with other stuff currently. I've also tried updating the app in the past, but it was always so much since the ffmpeg library is deprecated and some stuff changed, and the app itself is also quite complex.

Did you create your PRs with the help of AI? I'm not against the usage of AI, I just want transparency here.

@cizra

cizra commented May 25, 2026

Copy link
Copy Markdown
Author

Yes, AI was involved. It's also in the commit message:

Code changes by Claude Opus running inside Pi.dev. I built and tested this commit, it works fine in my phone.

I don't speak Kotlin myself (though I'm a developer).
I pushed a merge of all my work into https://github.com/cizra/Alibi - I've lightly tested this merge of all those PRs.
@Myzel394

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants