Add on-demand HEVC-to-H264

This commit is contained in:
Nexus 2024-04-19 16:16:43 +01:00 committed by GitHub
parent 531c0e9d4e
commit 5d9a70e25c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,4 +1,5 @@
import asyncio import asyncio
from collections.abc import Iterable
import logging import logging
import pathlib import pathlib
import re import re
@ -177,6 +178,73 @@ class AutoResponder(commands.Cog):
stderr, stderr,
) )
return discord.File(tmp_path), tmp_path 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") @commands.Cog.listener("on_message")
async def auto_responder(self, message: discord.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 # Check for HEVC truth social links and convert into h264
if message.channel.name == "spam" and message.author != self.bot.user: if message.channel.name == "spam" and message.author != self.bot.user:
# links = self.extract_links(message.content, "static-assets-1.truthsocial.com") await self.transcode_hevc_to_h264(message)
links = self.extract_links(message.content)
if links: @commands.Cog.listener("on_reaction_add")
for link in links: async def on_reaction_add(self, reaction: discord.Reaction, user: discord.User):
hevc_containers = { if user == self.bot.user:
".mp4", return
".mov",
".qtff", if reaction.message.author != self.bot.user:
".mkv", if str(reaction.emoji) == "\N{VIDEOCASSETTE}":
".asf", extra = []
".avi", if reaction.message.attachments:
".mxf", extra = [attachment.url for attachment in reaction.message.attachments]
".ps", await self.transcode_hevc_to_h264(reaction.message, additional=extra)
".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)
def setup(bot): def setup(bot):