Skip to content

feat: render TikTok photo posts into a video, and release 1.6.0 - #20

Merged
vannt-dev merged 25 commits into
mainfrom
feat/tiktok-slideshow-render
Sep 3, 2026
Merged

feat: render TikTok photo posts into a video, and release 1.6.0#20
vannt-dev merged 25 commits into
mainfrom
feat/tiktok-slideshow-render

Conversation

@vannt-dev

Copy link
Copy Markdown
Owner

Renders a TikTok photo post's images and music into one MP4 on the device, and
releases it as 1.6.0.

What this adds

  • A slideshow option on TikTok photo posts, rendered on Android into a
    1080x1920 H.264 MP4 at three seconds an image, with the post's music
    transcoded to AAC and muxed alongside it.
  • The option carries no download URL — there is nothing to fetch — so it is
    split off ahead of the download queue and rendered instead. The finished file
    enters history as a file that already exists.
  • Progress reporting and cancellation for a render, since the encode runs
    outside the download queue and neither the progress bar nor the Cancel button
    could reach it.
  • The option is shown only where it can actually run. A Dart conditional import
    cannot tell Android from iOS — both have dart.library.io — so a runtime
    Platform.isAndroid check in the renderer is what narrows support, and iOS,
    desktop and Web see no slideshow row at all.

Design notes worth reviewing

  • The audio stage runs before the muxer is started. MediaMuxer refuses
    both MP3 in an MP4 and any track added after start(), so the whole track is
    transcoded and buffered first. A track that will not decode therefore cannot
    damage the picture: the render carries on and produces a silent video with a
    note on it.
  • A rendered task's downloadUrl is the post URL, not empty. An empty one
    is the shape that 404s if anything ever fetches it.
  • Retry re-extracts. The source a render was built from is held in memory
    while a failed task is persisted, so a retry after a restart recovers the
    source from the post rather than falling through to the download path.

Verification

tool/check_all.ps1 passes all 7 steps on this branch: 261 unit tests, 20
Android integration tests on an emulator, release Web build, Node tests,
formatting and analysis.

No pre-existing test was edited — git diff against the previous main for
test/ and integration_test/ is additions only, zero deletions.

Release

The final commit bumps to 1.6.0 with matching changelog notes, so merging this
starts the release workflow. The workflow's own three gates were checked
locally first: the changelog section is present and non-empty, v1.6.0 does
not exist, and the version increases over 1.5.2.

Merge with --rebase to keep main linear.

…ixels

Budget total pixels when choosing inSampleSize: the previous per-axis
guard joined both axes with && , so it never fired for a landscape source
against a portrait frame and a 4032x3024 photo decoded at full size.

Catch Throwable in the channel handler. An OutOfMemoryError is an Error,
so it escaped, killed the worker thread and left MethodChannel.Result
never completed - crashing the app and hanging the Dart future.

Add frameColorAt and assert the decoded frame colours plus a file-size
ceiling. Every previous assertion passed against a deliberate U/V swap.

Derive the queueInputBuffer size from the planes' rowStride, guard both
retriever entry points to local files, and bound the cause-chain walk.
@vannt-dev
vannt-dev merged commit 0a08043 into main Sep 3, 2026
7 checks passed
@vannt-dev
vannt-dev deleted the feat/tiktok-slideshow-render branch September 3, 2026 13:34
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.

1 participant