Properly take advantage of HW accel
This commit is contained in:
parent
e70056f2ff
commit
751287479a
1 changed files with 99 additions and 56 deletions
|
@ -2,6 +2,7 @@ import asyncio
|
||||||
import pathlib
|
import pathlib
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
import aiohttp
|
||||||
import discord
|
import discord
|
||||||
import re
|
import re
|
||||||
import tempfile
|
import tempfile
|
||||||
|
@ -66,37 +67,67 @@ class AutoResponder(commands.Cog):
|
||||||
else:
|
else:
|
||||||
self.log.info("No HEVC streams found in %s", uri)
|
self.log.info("No HEVC streams found in %s", uri)
|
||||||
return
|
return
|
||||||
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
|
extension = pathlib.Path(uri).suffix
|
||||||
tmp_path = pathlib.Path(tmp.name)
|
with tempfile.NamedTemporaryFile(suffix=extension) as tmp_dl:
|
||||||
self.log.info("Transcoding %r to %r", uri, tmp_path)
|
self.log.info("Downloading %r to %r", uri, tmp_dl.name)
|
||||||
args = [
|
async with aiohttp.ClientSession(
|
||||||
"-i", str(uri),
|
headers={
|
||||||
"-c:v", "libx264",
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,"
|
||||||
"-crf", "25",
|
"*/*;q=0.8",
|
||||||
"-c:a", "libopus",
|
"Accept-Language": "en-US,en;q=0.5",
|
||||||
"-b:a", "64k",
|
"Sec-Fetch-Dest": "document",
|
||||||
"-preset", "slower",
|
"Sec-Fetch-Mode": "navigate",
|
||||||
"-y"
|
"Sec-Fetch-Site": "none",
|
||||||
]
|
"Sec-Fetch-User": "?1",
|
||||||
process = await asyncio.create_subprocess_exec(
|
"Sec-Gpc": "1",
|
||||||
"ffmpeg",
|
"Upgrade-Insecure-Requests": "1",
|
||||||
*args,
|
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0",
|
||||||
str(tmp_path),
|
}
|
||||||
stdout=asyncio.subprocess.PIPE,
|
) as session:
|
||||||
stderr=asyncio.subprocess.PIPE,
|
async with session.get(uri) as resp:
|
||||||
)
|
resp.raise_for_status()
|
||||||
stdout, stderr = await process.communicate()
|
async for chunk in resp.content.iter_any():
|
||||||
self.log.info("finished transcode with return code %d", process.returncode)
|
# noinspection PyTypeChecker
|
||||||
self.log.debug("stdout: %r", stdout.decode)
|
tmp_dl.write(chunk)
|
||||||
self.log.debug("stderr: %r", stderr.decode)
|
self.log.info("Finished downloading %r to %r", uri, tmp_dl.name)
|
||||||
if process.returncode != 0:
|
|
||||||
raise subprocess.SubprocessError(
|
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
|
||||||
process.returncode,
|
tmp_path = pathlib.Path(tmp.name)
|
||||||
" ".join(args),
|
self.log.info("Transcoding %r to %r", uri, tmp_path)
|
||||||
stdout,
|
args = [
|
||||||
stderr,
|
"-hide_banner",
|
||||||
|
"-hwaccel", "auto",
|
||||||
|
"-i", tmp_dl.name,
|
||||||
|
"-c:v", "libx264",
|
||||||
|
"-crf", "25",
|
||||||
|
"-c:a", "libopus",
|
||||||
|
"-b:a", "64k",
|
||||||
|
"-preset", "faster",
|
||||||
|
"-vsync", "2",
|
||||||
|
"-pix_fmt", "yuv420p",
|
||||||
|
"-movflags", "faststart",
|
||||||
|
"-profile:v", "main",
|
||||||
|
"-y"
|
||||||
|
]
|
||||||
|
process = await asyncio.create_subprocess_exec(
|
||||||
|
"ffmpeg",
|
||||||
|
*args,
|
||||||
|
str(tmp_path),
|
||||||
|
stdout=asyncio.subprocess.PIPE,
|
||||||
|
stderr=asyncio.subprocess.PIPE,
|
||||||
)
|
)
|
||||||
return discord.File(tmp_path), tmp_path
|
stdout, stderr = await process.communicate()
|
||||||
|
self.log.info("finished transcode with return code %d", process.returncode)
|
||||||
|
self.log.debug("stdout: %r", stdout.decode)
|
||||||
|
self.log.debug("stderr: %r", stderr.decode)
|
||||||
|
if process.returncode != 0:
|
||||||
|
raise subprocess.SubprocessError(
|
||||||
|
process.returncode,
|
||||||
|
" ".join(args),
|
||||||
|
stdout,
|
||||||
|
stderr,
|
||||||
|
)
|
||||||
|
return discord.File(tmp_path), tmp_path
|
||||||
|
|
||||||
@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):
|
||||||
|
@ -104,33 +135,45 @@ class AutoResponder(commands.Cog):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check for HEVC truth social links and convert into h264
|
# Check for HEVC truth social links and convert into h264
|
||||||
links = self.extract_links(message.content, "static-assets-1.truthsocial.com")
|
if message.channel.name == "spam" and message.author.id in {1101439218334576742, 1229496078726860921}:
|
||||||
if links:
|
links = self.extract_links(message.content, "static-assets-1.truthsocial.com")
|
||||||
for link in links:
|
if links:
|
||||||
if link.lower().endswith(
|
for link in links:
|
||||||
(".mp4", ".mov", ".qtff", ".mkv", ".asf", ".avi", ".mxf", ".ps", ".ts", ".3gp", ".3g2")
|
hevc_containers = {
|
||||||
):
|
".mp4",
|
||||||
# All containers allowed to contain HEVC
|
".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
|
# per https://en.wikipedia.org/wiki/Comparison_of_video_container_formats
|
||||||
self.log.info("Found link to transcode: %r", link)
|
if link.lower().endswith(tuple(hevc_containers)):
|
||||||
try:
|
self.log.info("Found link to transcode: %r", link)
|
||||||
async with message.channel.typing():
|
try:
|
||||||
_r = await self._transcode_hevc_to_h264(link)
|
async with message.channel.typing():
|
||||||
if not _r:
|
_r = await self._transcode_hevc_to_h264(link)
|
||||||
continue
|
if not _r:
|
||||||
file, _p = _r
|
continue
|
||||||
if file:
|
file, _p = _r
|
||||||
if _p.stat().st_size <= 24.5 * 1024 * 1024:
|
if file:
|
||||||
await message.reply(file=file)
|
if _p.stat().st_size <= 24.5 * 1024 * 1024:
|
||||||
else:
|
await message.reply(file=file)
|
||||||
self.log.warning(
|
else:
|
||||||
"Transcoded file too large: %r (%.2f)MB",
|
self.log.warning(
|
||||||
_p,
|
"Transcoded file too large: %r (%.2f)MB",
|
||||||
_p.stat().st_size / 1024 / 1024
|
_p,
|
||||||
)
|
_p.stat().st_size / 1024 / 1024
|
||||||
_p.unlink()
|
)
|
||||||
except Exception as e:
|
_p.unlink()
|
||||||
self.log.error("Failed to transcode %r: %r", link, e)
|
except Exception as e:
|
||||||
|
self.log.error("Failed to transcode %r: %r", link, e)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
|
|
Loading…
Reference in a new issue