Skip to content
This repository has been archived by the owner on Mar 2, 2024. It is now read-only.

Add option to convert webp images to gifs #285

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions mautrix_facebook/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ def do_update(self, helper: ConfigUpdateHelper) -> None:
if isinstance(value, list) and len(value) != 2:
raise ValueError(f"{key} must only be a list of two items")

copy("bridge.convert_animated_webp_attachments")

copy("facebook.device_seed")
if base["facebook.device_seed"] == "generate":
base["facebook.device_seed"] = self._new_token()
Expand Down
4 changes: 4 additions & 0 deletions mautrix_facebook/example-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,10 @@ bridge:
m.video: '<b>$sender_displayname</b> sent a video'
m.location: '<b>$sender_displayname</b> sent a location'

# Whether to convert animated webp to gifs. Element for Android does not support
# Animated WebP (https://github.com/vector-im/element-android/issues/2695).
convert_animated_webp_attachments: false

facebook:
device_seed: generate
default_region_hint: ODN
Expand Down
21 changes: 20 additions & 1 deletion mautrix_facebook/portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ async def _reupload_fb_file(
referer: str = "messenger_thread_photo",
find_size: bool = False,
convert_audio: bool = False,
convert_animated_webp_to_gif: bool = False,
) -> tuple[ContentURI, FileInfo | VideoInfo | AudioInfo | ImageInfo, EncryptedFile | None]:
if not url:
raise ValueError("URL not provided")
Expand All @@ -357,6 +358,22 @@ async def _reupload_fb_file(
data, ".ogg", output_args=("-c:a", "libopus"), input_mime=mime
)
mime = "audio/ogg"
if convert_animated_webp_to_gif and mime == "image/webp":
with Image.open(BytesIO(data)) as img:
with BytesIO() as data_bytes:
loop = img.info.get("loop", 0)
duration = img.info.get("duration", 70)
img.save(
data_bytes,
"gif",
save_all=True,
duration=duration,
loop=loop,
background=0,
)
data = data_bytes.getvalue()
mime = "image/gif"

info = FileInfo(mimetype=mime, size=len(data))
if Image and mime.startswith("image/") and find_size:
with Image.open(BytesIO(data)) as img:
Expand Down Expand Up @@ -1936,6 +1953,7 @@ async def _convert_mqtt_attachment(
return TextMessageEventContent(
msgtype=MessageType.NOTICE, body="Unsupported attachment"
)
convert_animated_webp_to_gif = self.config["bridge.convert_animated_webp_attachments"]
mxc, additional_info, decryption_info = await self._reupload_fb_file(
url,
source,
Expand All @@ -1945,9 +1963,10 @@ async def _convert_mqtt_attachment(
find_size=False,
referer=referer,
convert_audio=voice_message,
convert_animated_webp_to_gif=convert_animated_webp_to_gif,
)
info.size = additional_info.size
info.mimetype = attachment.mime_type or additional_info.mimetype
info.mimetype = additional_info.mimetype or attachment.mime_type
content = MediaMessageEventContent(
url=mxc, file=decryption_info, msgtype=msgtype, body=filename, info=info
)
Expand Down