diff options
Diffstat (limited to 'cogs/compression.py')
| -rw-r--r-- | cogs/compression.py | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/cogs/compression.py b/cogs/compression.py new file mode 100644 index 0000000..dfd96ae --- /dev/null +++ b/cogs/compression.py | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | import discord | ||
| 2 | from discord.ext import commands | ||
| 3 | import asyncio | ||
| 4 | import mimetypes | ||
| 5 | import os | ||
| 6 | import subprocess | ||
| 7 | import tempfile | ||
| 8 | |||
| 9 | def filetype(filename): | ||
| 10 | mime_type, _ = mimetypes.guess_type(filename) | ||
| 11 | if mime_type: | ||
| 12 | if mime_type.startswith('video/'): | ||
| 13 | return "Video" | ||
| 14 | elif mime_type.startswith('audio/'): | ||
| 15 | return "Audio" | ||
| 16 | elif mime_type.startswith('image/'): | ||
| 17 | return "Image" | ||
| 18 | return "Unknown" | ||
| 19 | |||
| 20 | class Compression(commands.Cog): | ||
| 21 | def __init__(self, bot): | ||
| 22 | self.bot = bot | ||
| 23 | |||
| 24 | @commands.slash_command( | ||
| 25 | name="kompresja", | ||
| 26 | description="skompresuj wideło albo dźwienk :)", | ||
| 27 | ) | ||
| 28 | @discord.option( | ||
| 29 | "plik", | ||
| 30 | description="plik do skompresowania", | ||
| 31 | required=True, | ||
| 32 | type=discord.Attachment | ||
| 33 | ) | ||
| 34 | async def compression(self, ctx, plik): | ||
| 35 | await ctx.defer() | ||
| 36 | # Save files to temp directory inside the bot's root directory | ||
| 37 | bot_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | ||
| 38 | temp_dir = os.path.join(bot_dir, "temp") | ||
| 39 | if not os.path.exists(temp_dir): | ||
| 40 | os.makedirs(temp_dir) | ||
| 41 | file_path = os.path.join(temp_dir, plik.filename) | ||
| 42 | await plik.save(file_path) | ||
| 43 | |||
| 44 | input_path = file_path | ||
| 45 | output_path = os.path.join(temp_dir, f"better_{plik.filename}") | ||
| 46 | file_type = filetype(file_path) | ||
| 47 | if file_type == "Video": | ||
| 48 | # Execute ffmpeg command to compress video | ||
| 49 | ffmpeg_command = f"ffmpeg -i {input_path} -c:v libx264 -crf 51 -b:v 100 -vf 'fps=10' -preset ultrafast -c:a libopus -b:a 500 {output_path}" | ||
| 50 | elif file_type == "Audio": | ||
| 51 | ffmpeg_command = f"ffmpeg -i {input_path} -ar 8000 -ac 1 -b:a 16k -acodec libmp3lame -q:a 9 {output_path}" | ||
| 52 | elif file_type == "Image": | ||
| 53 | # Use ImageMagick's magick to heavily compress image (JPEG/PNG/GIF) | ||
| 54 | # For JPEG: quality 5, strip metadata, resize to 30% of original size | ||
| 55 | # For PNG: magick to JPEG, then compress | ||
| 56 | # For GIF: optimize and reduce colors | ||
| 57 | ext = os.path.splitext(input_path)[1].lower() | ||
| 58 | if ext in [".jpg", ".jpeg"]: | ||
| 59 | img_command = f"magick {input_path} -strip -resize 30% -quality 5 {output_path}" | ||
| 60 | elif ext == ".gif": | ||
| 61 | # Optimize GIF: reduce colors, optimize layers, and resize | ||
| 62 | img_command = f"magick {input_path} -coalesce -resize 30% -colors 32 -strip -layers Optimize {output_path}" | ||
| 63 | else: | ||
| 64 | # magick non-JPEG images to JPEG for maximum compression | ||
| 65 | output_path = os.path.splitext(output_path)[0] + ".jpg" | ||
| 66 | img_command = f"magick {input_path} -strip -resize 30% -quality 5 {output_path}" | ||
| 67 | ffmpeg_command = img_command | ||
| 68 | else: | ||
| 69 | await ctx.respond("Plik jest nieobsługiwany", ephemeral=True) | ||
| 70 | return | ||
| 71 | |||
| 72 | try: | ||
| 73 | subprocess.run(ffmpeg_command, check=True, shell=True) | ||
| 74 | # Upload compressed file | ||
| 75 | await ctx.respond(file=discord.File(output_path)) | ||
| 76 | # Delete compressed file | ||
| 77 | os.remove(input_path) | ||
| 78 | os.remove(output_path) | ||
| 79 | except subprocess.CalledProcessError as e: | ||
| 80 | await ctx.respond(f"Compression failed: {str(e)}", ephemeral=True) | ||
| 81 | if os.path.exists(input_path): | ||
| 82 | os.remove(input_path) | ||
| 83 | if os.path.exists(output_path): | ||
| 84 | os.remove(output_path) | ||
| 85 | |||
| 86 | |||
| 87 | def setup(bot): | ||
| 88 | bot.add_cog(Compression(bot)) \ No newline at end of file | ||
