🎨 Improve the ffmpeg return status judgment and automatic jump to video width and height

* 🎨 Use `return_code` to determine whether ffmpeg has executed successfully

* 🎨 Automatically adjust the width and height of a video using the scale filter from ffmpeg
This commit is contained in:
洛水居室 2023-04-14 20:51:39 +08:00 committed by GitHub
parent 47a1c33abe
commit 0566769ee1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,4 +1,5 @@
import os import os
from asyncio import create_subprocess_shell, subprocess
from typing import List, Optional, Tuple, TYPE_CHECKING, Union from typing import List, Optional, Tuple, TYPE_CHECKING, Union
import aiofiles import aiofiles
@ -22,7 +23,7 @@ from core.config import config
from core.plugin import Plugin, conversation, handler from core.plugin import Plugin, conversation, handler
from modules.apihelper.client.components.hyperion import Hyperion from modules.apihelper.client.components.hyperion import Hyperion
from modules.apihelper.error import APIHelperException from modules.apihelper.error import APIHelperException
from utils.helpers import execute, sha1 from utils.helpers import sha1
from utils.log import logger from utils.log import logger
if TYPE_CHECKING: if TYPE_CHECKING:
@ -70,13 +71,13 @@ class Post(Plugin.Conversation):
logger.success("文章定时推送处理已经开启") logger.success("文章定时推送处理已经开启")
self.application.job_queue.run_repeating(self.task, 60) self.application.job_queue.run_repeating(self.task, 60)
logger.success("文章定时推送处理已经开启") logger.success("文章定时推送处理已经开启")
output = await execute("ffmpeg -version") output, _ = await self.execute("ffmpeg -version")
if "ffmpeg version" in output: if "ffmpeg version" in output:
self.ffmpeg_enable = True self.ffmpeg_enable = True
logger.info("检测到 ffmpeg 可用 已经启动编码转换") logger.info("检测到 ffmpeg 可用 已经启动编码转换")
logger.debug("ffmpeg version info\n%s", output) logger.debug("ffmpeg version info\n%s", output)
else: else:
logger.debug("ffmpeg 不可用 已经禁用编码转换") logger.warning("ffmpeg 不可用 已经禁用编码转换")
async def task(self, context: "ContextTypes.DEFAULT_TYPE"): async def task(self, context: "ContextTypes.DEFAULT_TYPE"):
temp_post_id_list: List[int] = [] temp_post_id_list: List[int] = []
@ -167,9 +168,25 @@ class Post(Plugin.Conversation):
return InputMediaVideo(media.data, filename=filename, *args, **kwargs) return InputMediaVideo(media.data, filename=filename, *args, **kwargs)
return InputMediaDocument(media.data, *args, **kwargs) return InputMediaDocument(media.data, *args, **kwargs)
@staticmethod
async def execute(command: str) -> Tuple[str, int]:
process = await create_subprocess_shell(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE
)
stdout, stderr = await process.communicate()
try:
result = str(stdout.decode().strip()) + str(stderr.decode().strip())
except UnicodeDecodeError:
result = str(stdout.decode("gbk").strip()) + str(stderr.decode("gbk").strip())
return result, process.returncode
@staticmethod @staticmethod
def get_ffmpeg_command(input_file: str, output_file: str): def get_ffmpeg_command(input_file: str, output_file: str):
return f'ffmpeg -i "{input_file}" -c:v libx264 -crf 20 -vf "fps=30,format=yuv420p" -y "{output_file}"' return (
f'ffmpeg -i "{input_file}" '
f'-c:v libx264 -crf 20 -vf "fps=30,format=yuv420p,'
f'scale=trunc(iw/2)*2:trunc(ih/2)*2" -y "{output_file}"'
)
async def gif_to_mp4(self, media: "List[ArtworkImage]"): async def gif_to_mp4(self, media: "List[ArtworkImage]"):
if self.ffmpeg_enable: if self.ffmpeg_enable:
@ -190,7 +207,8 @@ class Post(Plugin.Conversation):
temp_file = sha1(file_name) + ".mp4" temp_file = sha1(file_name) + ".mp4"
temp_path = os.path.join(self.cache_dir, temp_file) temp_path = os.path.join(self.cache_dir, temp_file)
command = self.get_ffmpeg_command(file_path, temp_path) command = self.get_ffmpeg_command(file_path, temp_path)
result = await execute(command) result, return_code = await self.execute(command)
if return_code == 0:
if os.path.exists(temp_path): if os.path.exists(temp_path):
logger.debug("ffmpeg 执行成功\n%s", result) logger.debug("ffmpeg 执行成功\n%s", result)
os.rename(temp_path, output_path) os.rename(temp_path, output_path)
@ -200,12 +218,15 @@ class Post(Plugin.Conversation):
i.file_extension = "mp4" i.file_extension = "mp4"
else: else:
logger.error( logger.error(
"输出文件不存在!可能是 ffmpeg 命令执行失败!\nfile_path[%s]\noutput_path[%s]\ntemp_file[%s]\nffmpeg result[%s]\n", "输出文件不存在!可能是 ffmpeg 命令执行失败!\n"
"file_path[%s]\noutput_path[%s]\ntemp_file[%s]\nffmpeg result[%s]",
file_path, file_path,
output_path, output_path,
temp_path, temp_path,
result, result,
) )
else:
logger.error("ffmpeg 执行失败\n%s", result)
return media return media
@conversation.entry_point @conversation.entry_point