Repository navigation
Conversation
…xports When no clip inserts audio (video-only sources, all clips muted), the composition kept an empty audio track. That track fails the AVAssetExportSession compatibility check for the re-encoding presets, so ExportEngine silently fell back to passthrough — which cannot apply a videoComposition and discarded transitions, speed, crop, overlays and the preset codec/resolution, while reporting success. - CompositionBuilder.build now removes audio tracks that ended up with no segments, and strips audio-mix parameters referencing them - insertVideoClip only records a ClipVolume when audio was actually inserted (previously a volume was recorded for audio-less sources, attaching mix parameters to the empty track) - Regression tests: HEVC export of no-audio compositions must actually re-encode (codec + track-count assertions) for merge, speed, transition and muted shapes - ClipVolumeTests: the volume test now uses a fixture that actually has audio; new test documents that an audio-less clip produces no mix Closes #201
fix: drop empty composition audio tracks to stop silent passthrough exports
Parallel tracks rendered under the implicit main chain: AVFoundation reads layerInstructions[0] as the topmost layer, and buildMultiTrack emitted them in declaration order. Emit them in reverse so later tracks draw over earlier ones (#205). A track ending before the composition held its last frame for the rest of the instruction. Hide each track from its content end on the default compositor, and drop ended tracks from KadrVideoCompositor's inputs, which ignores layer instructions (#206). Fixes #205 Fixes #206
…-frame-hold fix(multitrack): overlays stack on top and stop at their content end
When the preset can't encode a composition, ExportEngine and the transition/nested-track pre-render fell back to passthrough without condition. Passthrough can't apply a video composition, so the export reported success with transitions, track layout, crop and overlays missing (#201). Fall back only when the copy loses nothing but the preset's format; otherwise throw KadrError.exportFailed naming the preset and what would be lost. #204 removed the common trigger (empty audio tracks); this guards the rest. Also adds the changelog entries for #201 / #204.
fix(export): throw instead of a passthrough copy that drops work
CATextLayer draws lazily. On macOS nothing triggers that draw before AVVideoCompositionCoreAnimationTool renders the layer tree, so text overlays exported blank while image overlays, whose pixels are already in `contents`, rendered fine (#202). Call display() when the text layer is built. Text animations only touch opacity, position and transform, so one draw is enough. Fixes #202
fix(overlays): draw TextOverlay text up front on macOS
With the Core Animation overlay tool attached, a layer instruction whose transform is exactly identity, on a source that matches renderSize, made AVFoundation hand the frame straight to the tool. At some sizes (320x320, 560x560, 640x320 on macOS 27.0.1) the video layer then rendered solid white under any overlay. Reproduced with plain AVFoundation. When overlays are present, replace identity transforms (including the implicit one before a layer's first transform) with a 1/1024 px shift. Any non-identity transform takes the regular compositing path. Opacity and crop ramps are untouched, and exports without overlays keep the fast path.
Overlay exports crash on the iOS 26.5 / 27.0 Simulators: Core Animation wraps malloc-backed frames in an IOSurface and libxpc traps with "Attempt to pass a malloc(3)ed region to xpc_shmem_create()". Transition previews stall on the iOS 26 Simulator when clip size equals render size (#203). Both are documented with symptom, cause and workaround. Closes #203
docs: a Known Platform Issues article for two iOS Simulator bugs
fix(export): overlay exports no longer turn white at some render sizes
… crashing
On the iOS 26.5 and 27.0 Simulators, AVVideoCompositionCoreAnimationTool's
renderer wraps AVFoundation's malloc-backed frames in an IOSurface, and
libxpc kills the app ("Attempt to pass a malloc(3)ed region to
xpc_shmem_create()"). The trap can't be caught, so refuse overlay exports
on the iOS Simulator with KadrError.exportFailed pointing to the Known
Platform Issues article.
Tests that export with overlays are skipped on the iOS Simulator; a
Simulator-only test checks the refusal.
…rror fix(export): throw on overlay exports on the iOS Simulator instead of crashing
release: v1.1.1 changelog
A camera stores a portrait recording as landscape pixels plus a preferredTransform, and the front camera may add a mirror. A layer instruction's transform replaces that tag, and kadr never applied it, so every portrait iPhone clip exported and previewed sideways. The orientation of every source is now read from the composition's own segments once the clips are placed, and each clip is turned upright before it is scaled to fill. That covers plain chains, transitions (slide included), Tracks and free-floating clips, clip transforms and keyframes, and the preview player. Clips with different orientations on one track each keep their own. ReverseProcessor now copies the source's transform to the reversed file instead of dropping it. Transforms on a layer are collected and emitted once in time order, so the base layout and per-clip keyframes can't overwrite each other by call order. That also fixes a plain clip inheriting the previous clip's transform on the keyframe path.
Owner
Author
|
Superseded by the release/v1.1.2-main PR: the same two commits, cut from main. develop still carries v1.1.1's pre-rebase commits from the back-merge, so this PR wasn't rebaseable (rebaseable=false). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Portrait and rotated videos now export upright. Update if your app imports clips recorded on an iPhone.
Fixed
Portrait and rotated videos export upright.
preferredTransform), and the front camera may add a mirror. kadr never read that tag, so every portrait iPhone clip exported and previewed sideways, stretched to fill the frame.A plain clip no longer inherits the previous clip's transform. On the keyframe path, a clip with no transform that followed a transformed clip on the same track kept that transform. It now returns to its own layout.
Behaviour note
When every source is stored upright, nothing changes.
For a rotated source, kadr now builds a video composition so the rotation can be applied. If the preset can't encode it, the export throws
KadrError.exportFailedinstead of writing a passthrough copy, which would have been sideways. This is the same rule 1.1.1 introduced for transitions and crop.Known gaps
MultiInputCompositorstill receives source frames as stored, unrotated.VideoClip.metadata.resolutionreports the stored size, not the displayed size.Both are tracked for a later release.
Full changelog: v1.1.1...v1.1.2