Modified converters to support pngs option of lottieconverter
See https://github.com/Eramde/LottieConverter/commit/37e73d8dc15152e050288ea0a55541546dde84d1
This commit is contained in:
+3
-1
@@ -172,13 +172,15 @@ bridge:
|
||||
# disable - No conversion, send as-is (gzipped lottie)
|
||||
# png - converts to non-animated png (fastest),
|
||||
# gif - converts to animated gif, but loses transparency
|
||||
# webm - converts to webm video, requires ffmpeg executable with vp9 codec and webm container support
|
||||
target: gif
|
||||
# Arguments for converter. All converters take width and height.
|
||||
# GIF converter takes background as a hex color.
|
||||
args:
|
||||
width: 256
|
||||
height: 256
|
||||
background: "020202"
|
||||
background: "020202" # only for gif
|
||||
fps: 30 # only for webm
|
||||
|
||||
# Whether to bridge Telegram bot messages as m.notices or m.texts.
|
||||
bot_messages_as_notices: true
|
||||
|
||||
@@ -206,8 +206,9 @@ async def _unlocked_transfer_file_to_matrix(client: MautrixTelegramClient, inten
|
||||
if is_sticker and tgs_convert and (mime_type == "application/gzip" or (
|
||||
mime_type == "application/octet-stream"
|
||||
and magic.from_buffer(file).startswith("gzip"))):
|
||||
mime_type, file, width, height, thumbnail = await convert_tgs_to(
|
||||
mime_type, file, width, height = await convert_tgs_to(
|
||||
file, tgs_convert["target"], **tgs_convert["args"])
|
||||
thumbnail = None
|
||||
image_converted = mime_type != "application/gzip"
|
||||
|
||||
if mime_type == "image/webp":
|
||||
|
||||
@@ -21,6 +21,4 @@ for i in {0..99}; do
|
||||
$lottieconverter input frame-${padded: -2}.png png $resolution $((i+1))
|
||||
done
|
||||
|
||||
ffmpeg -start_number 0 -framerate 30 -i frame-%02d.png -c:v libvpx-vp9 -pix_fmt yuva420p out.webm
|
||||
|
||||
cat out.webm
|
||||
ffmpeg -start_number 0 -framerate 30 -i frame-%02d.png -c:v libvpx-vp9 -pix_fmt yuva420p out.webm -f webm -
|
||||
|
||||
@@ -19,6 +19,7 @@ import asyncio.subprocess
|
||||
import logging
|
||||
import shutil
|
||||
import os.path
|
||||
import tempfile
|
||||
|
||||
log: logging.Logger = logging.getLogger("mau.util.tgs")
|
||||
converters: Dict[str, Callable[[bytes, int, int, Any], Awaitable[Tuple[str, bytes]]]] = {}
|
||||
@@ -30,7 +31,7 @@ def abswhich(program: Optional[str]) -> Optional[str]:
|
||||
|
||||
|
||||
lottieconverter = abswhich("lottieconverter")
|
||||
lottie2ffmpeg = abswhich("lottie2ffmpeg")
|
||||
ffmpeg = abswhich("ffmpeg")
|
||||
|
||||
if lottieconverter:
|
||||
async def tgs_to_png(file: bytes, width: int, height: int, **_: Any) -> Tuple[str, bytes]:
|
||||
@@ -39,42 +40,73 @@ if lottieconverter:
|
||||
f"{width}x{height}", str(frame),
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stdin=asyncio.subprocess.PIPE)
|
||||
stdout, _ = await proc.communicate(file)
|
||||
return "image/png", stdout
|
||||
stdout, stderr = await proc.communicate(file)
|
||||
if proc.returncode == 0:
|
||||
return "image/png", stdout
|
||||
else:
|
||||
log.error("lottieconverter error: " + stderr.decode("utf-8") if stderr is not None
|
||||
else "unknown")
|
||||
return "application/gzip", file
|
||||
|
||||
|
||||
async def tgs_to_gif(file: bytes, width: int, height: int, background: str = "202020",
|
||||
**_: Any) -> Tuple[str, bytes]:
|
||||
proc = await asyncio.create_subprocess_exec(lottieconverter, "-", "-", "gif",
|
||||
f"{width}x{height}", "0", f"0x{background}",
|
||||
f"{width}x{height}", f"0x{background}",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stdin=asyncio.subprocess.PIPE)
|
||||
stdout, _ = await proc.communicate(file)
|
||||
return "image/gif", stdout
|
||||
stdout, stderr = await proc.communicate(file)
|
||||
if proc.returncode == 0:
|
||||
return "image/gif", stdout
|
||||
else:
|
||||
log.error("lottieconverter error: " + stderr.decode("utf-8") if stderr is not None
|
||||
else "unknown")
|
||||
return "application/gzip", file
|
||||
|
||||
|
||||
converters["png"] = tgs_to_png
|
||||
converters["gif"] = tgs_to_gif
|
||||
|
||||
if lottieconverter and lottie2ffmpeg:
|
||||
async def tgs_to_webm(file: bytes, width: int, height: int, **_: Any) -> Tuple[str, bytes]:
|
||||
proc = await asyncio.create_subprocess_exec(lottie2ffmpeg, lottieconverter,
|
||||
f"{width}x{height}",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stdin=asyncio.subprocess.PIPE)
|
||||
stdout, _ = await proc.communicate(file)
|
||||
return "video/webm", stdout
|
||||
if lottieconverter and ffmpeg:
|
||||
async def tgs_to_webm(file: bytes, width: int, height: int, fps: int = 30,
|
||||
**_: Any) -> Tuple[str, bytes]:
|
||||
with tempfile.TemporaryDirectory(prefix="tgs_") as tmpdir:
|
||||
file_template = tmpdir + "/out_"
|
||||
proc = await asyncio.create_subprocess_exec(lottieconverter, "-", file_template,
|
||||
"pngs", f"{width}x{height}", str(fps),
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stdin=asyncio.subprocess.PIPE)
|
||||
_, stderr = await proc.communicate(file)
|
||||
if proc.returncode == 0:
|
||||
proc = await asyncio.create_subprocess_exec(ffmpeg, "-hide_banner", "-loglevel",
|
||||
"error", "-framerate", str(fps),
|
||||
"-pattern_type", "glob", "-i",
|
||||
file_template + "*.png",
|
||||
"-c:v", "libvpx-vp9", "-pix_fmt",
|
||||
"yuva420p", "-f", "webm", "-",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stdin=asyncio.subprocess.PIPE)
|
||||
stdout, stderr = await proc.communicate()
|
||||
if proc.returncode == 0:
|
||||
return "video/webm", stdout
|
||||
else:
|
||||
log.error("ffmpeg error: " + stderr.decode("utf-8") if stderr is not None
|
||||
else "unknown")
|
||||
else:
|
||||
log.error("lottieconverter error: " + stderr.decode("utf-8") if stderr is not None
|
||||
else "unknown")
|
||||
return "application/gzip", file
|
||||
|
||||
|
||||
converters["webm"] = tgs_to_webm
|
||||
|
||||
|
||||
async def convert_tgs_to(file: bytes, convert_to: str, width: int, height: int, **kwargs: Any
|
||||
) -> Tuple[str, bytes, Optional[int], Optional[int], Optional[bytes]]:
|
||||
) -> Tuple[str, bytes, Optional[int], Optional[int]]:
|
||||
if convert_to in converters:
|
||||
converter = converters[convert_to]
|
||||
mime, out = await converter(file, width, height, **kwargs)
|
||||
return mime, out, width, height, None
|
||||
return mime, out, width, height
|
||||
elif convert_to != "disable":
|
||||
log.warning(f"Unable to convert animated sticker, type {convert_to} not supported")
|
||||
return "application/gzip", file, None, None, None
|
||||
return "application/gzip", file, None, None
|
||||
|
||||
Reference in New Issue
Block a user