- Fetch mp4s from Giphy for showing previews
- Fetch mp4s from Giphy for sending (behind featuree flag)
- A new flag on attachments to tag a video as "looping media"
- Videos tagged with this flag will be shown on repeat
Previously we had two different ways attachments got cloned: through
the cloneAttachment() method, which made a temporary file with the
original attachment contents, and ad hoc after recompression or
similar. Neither preserved all the properties of the original
attachment; now, both go through a common helper function.
This makes for a more uniform experience and optimizes for bandwidth
when attaching a JPEG that's under our threshold but still pretty big.
Previously we'd send that along after stripping metadata, but now
we'll recompress it regardless.
Sticker-like images are opted out because they usually contain content
that's better represented in a compressed lossless format due to the
use of solid colors...and also we don't want to lose transparency if
we don't need to.
Note that isBorderless is sometimes equivalent to the "sticker-like"
check, but we don't want to rely on that here. isBorderless is a
presentation option.
Uses the nigh-undocumented CGImageDestinationCopyImageSource instead
of CGImageDestinationAddImageFromSource to avoid having ImageIO
re-encode the image contents.* If that fails, falls back to the
standard resize-as-JPEG logic in all cases rather than just reporting
a failure to strip metadata.
* https://developer.apple.com/library/archive/qa/qa1895/_index.html
The preset name is "640x480", but in practice it's "max longest
dimension of 640", as tested on a widescreen vertical video. This is
still better quality than "medium", which seems to be "longest
dimension of 480".
Previously: all videos exported using AVFoundation's "medium" quality,
falling back to "low" quality if that was still too big
Now: videos that are already <100MB mp4s are sent as is, others go
through SignalAttachment.compressVideoAsMp4. This is the same as the
share sheet behavior.
We don't actually /like/ this behavior, but now it's all controlled in
one place. The next commit will start changing it.
Metadata stripping relies on CoreGraphics, but CoreGraphics doesn't
support WebP. When attempting to send a static WebP, we fail to send
because we fail to strip metadata.
We should account for this by checking the destination formats
CoreGraphics supports. If it doesn't support the type we're trying to
strip, we'll fall back to just converting it to png/jpeg.