aboutsummaryrefslogtreecommitdiffstats
path: root/cogs/compression.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cogs/compression.py76
1 files changed, 55 insertions, 21 deletions
diff --git a/cogs/compression.py b/cogs/compression.py
index d235c6d..1fcefb5 100644
--- a/cogs/compression.py
+++ b/cogs/compression.py
@@ -5,7 +5,7 @@
5 5
6import mimetypes 6import mimetypes
7import os 7import os
8import subprocess 8import asyncio
9from typing import List, Optional 9from typing import List, Optional
10from os import PathLike 10from os import PathLike
11import discord 11import discord
@@ -32,6 +32,38 @@ class Compression(commands.Cog):
32 if not os.path.exists(self.temp_dir): 32 if not os.path.exists(self.temp_dir):
33 os.makedirs(self.temp_dir) 33 os.makedirs(self.temp_dir)
34 34
35 def _process_video(self, file_path: str, output_path: str) -> str:
36 """Process video compression"""
37 command = f"ffmpeg -y -i {file_path} -c:v libx264 -crf 51 -b:v 100 -vf 'fps=10,scale=trunc(iw*0.5/2)*2:trunc(ih*0.5/2)*2' -preset ultrafast -c:a libopus -b:a 500 {output_path}"
38 return command
39
40 def _process_audio(self, file_path: str, output_path: str) -> str:
41 """Process audio compression"""
42 if output_path.lower().endswith('.mp3'):
43 output_path = os.path.splitext(output_path)[0] + os.path.splitext(output_path)[1].replace('.mp3', '')
44 if not output_path.lower().endswith('.ogg'):
45 output_path = os.path.splitext(output_path)[0] + '.ogg'
46 command = f"ffmpeg -y -i {file_path} -c:a libopus -b:a 500 -ar 12000 -ac 1 {output_path}"
47 return command
48
49 def _process_image(self, file_path: str, output_path: str) -> tuple[str, str]:
50 """Process image compression"""
51 ext = os.path.splitext(file_path)[1].lower()
52 if ext in [".jpg", ".jpeg"]:
53 command = f"magick {file_path} -strip -resize 30% -quality 5 {output_path}"
54 elif ext == ".gif":
55 command = f"magick {file_path} -coalesce -resize 30% -colors 32 -strip -layers Optimize {output_path}"
56 else:
57 output_path = os.path.splitext(output_path)[0] + ".jpg"
58 command = f"magick {file_path} -strip -resize 30% -quality 5 {output_path}"
59 return command, output_path
60
61 async def _execute_compression(self, command: str) -> bool:
62 """Execute compression command"""
63 proc = await asyncio.create_subprocess_exec(command)
64 await proc.wait()
65 return proc.returncode == 0
66
35 async def _compress_attachment(self, attachment: discord.Attachment) -> Optional[discord.File]: 67 async def _compress_attachment(self, attachment: discord.Attachment) -> Optional[discord.File]:
36 """Compress a single attachment and return the compressed file""" 68 """Compress a single attachment and return the compressed file"""
37 file_path = PathLike[str] 69 file_path = PathLike[str]
@@ -46,32 +78,23 @@ class Compression(commands.Cog):
46 file_type = filetype(file_path) 78 file_type = filetype(file_path)
47 logger.info(f"Compression started for: {file_type}") 79 logger.info(f"Compression started for: {file_type}")
48 80
49 if file_type == "Video": 81 command = self._get_compression_command(file_type, file_path, output_path)
50 command = f"ffmpeg -y -i {file_path} -c:v libx264 -crf 51 -b:v 100 -vf 'fps=10,scale=trunc(iw*0.5/2)*2:trunc(ih*0.5/2)*2' -preset ultrafast -c:a libopus -b:a 500 {output_path}" 82 if command is None:
51 elif file_type == "Audio":
52 if output_path.lower().endswith('.mp3'):
53 output_path = os.path.splitext(output_path)[0] + os.path.splitext(output_path)[1].replace('.mp3', '')
54 if not output_path.lower().endswith('.ogg'):
55 output_path = os.path.splitext(output_path)[0] + '.ogg'
56 command = f"ffmpeg -y -i {file_path} -c:a libopus -b:a 500 -ar 12000 -ac 1 {output_path}"
57 elif file_type == "Image":
58 ext = os.path.splitext(file_path)[1].lower()
59 if ext in [".jpg", ".jpeg"]:
60 command = f"magick {file_path} -strip -resize 30% -quality 5 {output_path}"
61 elif ext == ".gif":
62 command = f"magick {file_path} -coalesce -resize 30% -colors 32 -strip -layers Optimize {output_path}"
63 else:
64 output_path = os.path.splitext(output_path)[0] + ".jpg"
65 command = f"magick {file_path} -strip -resize 30% -quality 5 {output_path}"
66 else:
67 logger.info(f"Unsupported file type: {file_type}") 83 logger.info(f"Unsupported file type: {file_type}")
68 os.remove(file_path) 84 os.remove(file_path)
69 return None 85 return None
70 86
87 # Update output_path if it was modified
88 if file_type == "Image":
89 command, output_path = command
90 elif file_type == "Audio":
91 # output_path is already modified in _process_audio
92 pass
93
71 # Run the compression 94 # Run the compression
72 subprocess.run(command, check=True, shell=True) 95 success = await self._execute_compression(command)
73 96
74 if os.path.exists(output_path): 97 if success and os.path.exists(output_path):
75 logger.info(f"Successfully compressed: {attachment.filename}") 98 logger.info(f"Successfully compressed: {attachment.filename}")
76 return discord.File(output_path, filename=f"compressed_{attachment.filename}") 99 return discord.File(output_path, filename=f"compressed_{attachment.filename}")
77 return None 100 return None
@@ -84,6 +107,17 @@ class Compression(commands.Cog):
84 # Clean up temporary files 107 # Clean up temporary files
85 if 'file_path' in locals() and os.path.exists(file_path): 108 if 'file_path' in locals() and os.path.exists(file_path):
86 os.remove(file_path) 109 os.remove(file_path)
110
111 def _get_compression_command(self, file_type: str, file_path: str, output_path: str):
112 """Get the appropriate compression command based on file type"""
113 if file_type == "Video":
114 return self._process_video(file_path, output_path)
115 elif file_type == "Audio":
116 return self._process_audio(file_path, output_path)
117 elif file_type == "Image":
118 return self._process_image(file_path, output_path)
119 else:
120 return None
87 121
88 async def _compress_attachments(self, attachments: List[discord.Attachment]) -> List[discord.File]: 122 async def _compress_attachments(self, attachments: List[discord.Attachment]) -> List[discord.File]:
89 """Compress multiple attachments and return list of compressed files""" 123 """Compress multiple attachments and return list of compressed files"""