From 5d9a70e25caa566f264ed644862962c8e78a92da Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Fri, 19 Apr 2024 16:16:43 +0100 Subject: [PATCH] Add on-demand HEVC-to-H264 --- src/cogs/auto_responder.py | 140 +++++++++++++++++++++---------------- 1 file changed, 81 insertions(+), 59 deletions(-) diff --git a/src/cogs/auto_responder.py b/src/cogs/auto_responder.py index 4493ccc..639a375 100644 --- a/src/cogs/auto_responder.py +++ b/src/cogs/auto_responder.py @@ -1,4 +1,5 @@ import asyncio +from collections.abc import Iterable import logging import pathlib import re @@ -177,6 +178,73 @@ class AutoResponder(commands.Cog): stderr, ) return discord.File(tmp_path), tmp_path + + async def transcode_hevc_to_h264( + self, + message: discord.Message, + *domains: str, + additional: Iterable[str] = None + ) -> discord.File | None: + additional = additional or [] + links = self.extract_links(message.content, *domains) + list(additional) + if links: + for link in links: + hevc_containers = { + ".mp4", + ".mov", + ".qtff", + ".mkv", + ".asf", + ".avi", + ".mxf", + ".ps", + ".ts", + ".3gp", + ".3g2", + } + # ^ All containers allowed to contain HEVC + # per https://en.wikipedia.org/wiki/Comparison_of_video_container_formats + if link.lower().endswith(tuple(hevc_containers)): + self.log.info("Found link to transcode: %r", link) + try: + async with message.channel.typing(): + _r = await self._transcode_hevc_to_h264(link, update=message) + if not _r: + continue + file, _p = _r + if file: + if _p.stat().st_size <= 24.5 * 1024 * 1024: + await message.add_reaction("\N{OUTBOX TRAY}") + await message.reply(file=file) + await message.remove_reaction("\N{OUTBOX TRAY}", self.bot.user) + else: + await message.add_reaction("\N{OUTBOX TRAY}") + self.log.warning( + "Transcoded file too large: %r (%.2f)MB", + _p, + _p.stat().st_size / 1024 / 1024, + ) + if _p.stat().st_size <= 510 * 1024 * 1024: + file.fp.seek(0) + self.log.info("Trying to upload file to pastebin.") + async with httpx.AsyncClient() as client: + response = await client.post( + "https://0x0.st", + files={"file": (_p.name, file.fp, "video/mp4")}, + headers={"User-Agent": "CollegeBot (matrix: @nex:nexy7574.co.uk)"}, + ) + await message.remove_reaction("\N{OUTBOX TRAY}", self.bot.user) + if response.status_code == 200: + await message.reply("https://embeds.video/" + response.text.strip()) + else: + await message.add_reaction("\N{BUG}") + response.raise_for_status() + else: + await message.add_reaction("\N{HAMBURGER}") + + _p.unlink() + except Exception as e: + self.log.error("Failed to transcode %r: %r", link, e) @commands.Cog.listener("on_message") async def auto_responder(self, message: discord.Message): @@ -185,66 +253,20 @@ class AutoResponder(commands.Cog): # Check for HEVC truth social links and convert into h264 if message.channel.name == "spam" and message.author != self.bot.user: - # links = self.extract_links(message.content, "static-assets-1.truthsocial.com") - links = self.extract_links(message.content) - if links: - for link in links: - hevc_containers = { - ".mp4", - ".mov", - ".qtff", - ".mkv", - ".asf", - ".avi", - ".mxf", - ".ps", - ".ts", - ".3gp", - ".3g2", - } - # ^ All containers allowed to contain HEVC - # per https://en.wikipedia.org/wiki/Comparison_of_video_container_formats - if link.lower().endswith(tuple(hevc_containers)): - self.log.info("Found link to transcode: %r", link) - try: - async with message.channel.typing(): - _r = await self._transcode_hevc_to_h264(link, update=message) - if not _r: - continue - file, _p = _r - if file: - if _p.stat().st_size <= 24.5 * 1024 * 1024: - await message.add_reaction("\N{OUTBOX TRAY}") - await message.reply(file=file) - await message.remove_reaction("\N{OUTBOX TRAY}", self.bot.user) - else: - await message.add_reaction("\N{OUTBOX TRAY}") - self.log.warning( - "Transcoded file too large: %r (%.2f)MB", - _p, - _p.stat().st_size / 1024 / 1024, - ) - if _p.stat().st_size <= 510 * 1024 * 1024: - file.fp.seek(0) - self.log.info("Trying to upload file to pastebin.") - async with httpx.AsyncClient() as client: - response = await client.post( - "https://0x0.st", - files={"file": (_p.name, file.fp, "video/mp4")}, - headers={"User-Agent": "CollegeBot (matrix: @nex:nexy7574.co.uk)"}, - ) - await message.remove_reaction("\N{OUTBOX TRAY}", self.bot.user) - if response.status_code == 200: - await message.reply("https://embeds.video/" + response.text.strip()) - else: - await message.add_reaction("\N{BUG}") - response.raise_for_status() - else: - await message.add_reaction("\N{HAMBURGER}") + await self.transcode_hevc_to_h264(message) + + @commands.Cog.listener("on_reaction_add") + async def on_reaction_add(self, reaction: discord.Reaction, user: discord.User): + if user == self.bot.user: + return + + if reaction.message.author != self.bot.user: + if str(reaction.emoji) == "\N{VIDEOCASSETTE}": + extra = [] + if reaction.message.attachments: + extra = [attachment.url for attachment in reaction.message.attachments] + await self.transcode_hevc_to_h264(reaction.message, additional=extra) - _p.unlink() - except Exception as e: - self.log.error("Failed to transcode %r: %r", link, e) def setup(bot):