Found another solution here which may be helpful as it doesn't require adding multiple tracks.
Simply call seek time twice, once without specifying tolerance, and then AFTER, with specifying a tolerance for frame by frame increments.
let seekTime = CMTime(seconds: timeToSeekTo, preferredTimescale: yourPreferredTimescale)
playerItem?.seek(to: seekTime) { [weak self] _ in // where player item is an AVPlayerItem created using your composition
}
playerItem?.seek(to: seekTime, toleranceBefore: .zero, toleranceAfter: .zero) { [weak self] _ in
}