aboutsummaryrefslogtreecommitdiffstats
path: root/cogs/music/media_processing.py
diff options
context:
space:
mode:
authorsalmonik <raisersoft@proton.me>2026-04-17 15:36:12 +0200
committersalmonik <raisersoft@proton.me>2026-04-17 15:36:12 +0200
commitd135265798da8c2698f363237f4cb74b682f3f9e (patch)
treebca914d297e74a6188478a773ba7333c10fe4a34 /cogs/music/media_processing.py
parentMerge branch 'main' of https://codeberg.org/salmonik/senator-sperma (diff)
downloadsenator-sperma-d135265798da8c2698f363237f4cb74b682f3f9e.tar.gz
senator-sperma-d135265798da8c2698f363237f4cb74b682f3f9e.zip
make voice great again
Signed-off-by: salmonik <raisersoft@proton.me>
Diffstat (limited to '')
-rw-r--r--cogs/music/media_processing.py67
1 files changed, 40 insertions, 27 deletions
diff --git a/cogs/music/media_processing.py b/cogs/music/media_processing.py
index 430b51f..e04911c 100644
--- a/cogs/music/media_processing.py
+++ b/cogs/music/media_processing.py
@@ -3,26 +3,26 @@
3# Copyright (C) 2026 Salmonik @ salmonik@tuta.io 3# Copyright (C) 2026 Salmonik @ salmonik@tuta.io
4# https://codeberg.org/salmonik/senator-sperma 4# https://codeberg.org/salmonik/senator-sperma
5 5
6import os
7import asyncio 6import asyncio
8import logging 7import logging
9from pathlib import Path 8import os
10 9
11import yt_dlp 10import yt_dlp
12from youtubesearchpython import VideosSearch 11from youtubesearchpython import VideosSearch
13 12
14logger = logging.getLogger(__name__) 13logger = logging.getLogger(__name__)
15 14
15
16class MediaDownloader: 16class MediaDownloader:
17 """Handles downloading media from various sources.""" 17 """Handles downloading media from various sources."""
18 18
19 @staticmethod 19 @staticmethod
20 async def download(ctx, url): 20 async def download(ctx, url):
21 """Download audio from YouTube URL.""" 21 """Download audio from YouTube URL."""
22 # Create temp directory if it doesn't exist 22 # Create temp directory if it doesn't exist
23 temp_dir = os.path.join('cogs', 'temp', 'music') 23 temp_dir = os.path.join("cogs", "temp", "music")
24 os.makedirs(temp_dir, exist_ok=True) 24 os.makedirs(temp_dir, exist_ok=True)
25 25
26 ytdl_opts = { 26 ytdl_opts = {
27 "outtmpl": os.path.join(temp_dir, "%(title)s.%(ext)s"), 27 "outtmpl": os.path.join(temp_dir, "%(title)s.%(ext)s"),
28 "postprocessors": [ 28 "postprocessors": [
@@ -62,9 +62,10 @@ class MediaDownloader:
62 await ctx.respond("nic ni ma", ephemeral=True) 62 await ctx.respond("nic ni ma", ephemeral=True)
63 return None 63 return None
64 64
65
65class AudioCompressor: 66class AudioCompressor:
66 """Handles audio compression using FFmpeg.""" 67 """Handles audio compression using FFmpeg."""
67 68
68 @staticmethod 69 @staticmethod
69 async def compress(ctx, filename): 70 async def compress(ctx, filename):
70 """Compress audio file to opus format.""" 71 """Compress audio file to opus format."""
@@ -73,51 +74,63 @@ class AudioCompressor:
73 return None 74 return None
74 75
75 # Create temp directory if it doesn't exist 76 # Create temp directory if it doesn't exist
76 temp_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'temp', 'compressed') 77 temp_dir = os.path.join(
78 os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
79 "temp",
80 "compressed",
81 )
77 os.makedirs(temp_dir, exist_ok=True) 82 os.makedirs(temp_dir, exist_ok=True)
78 83
79 # Create a temporary output filename in the temp directory 84 # Create a temporary output filename in the temp directory
80 base_name = os.path.basename(filename) 85 base_name = os.path.basename(filename)
81 output_filename = os.path.join(temp_dir, f"{os.path.splitext(base_name)[0]}_compressed.opus") 86 output_filename = os.path.join(
82 87 temp_dir, f"{os.path.splitext(base_name)[0]}_compressed.opus"
88 )
89
83 # Ensure the output directory exists 90 # Ensure the output directory exists
84 os.makedirs(os.path.dirname(output_filename) or '.', exist_ok=True) 91 os.makedirs(os.path.dirname(output_filename) or ".", exist_ok=True)
85 92
86 # Use proper quoting for filenames with spaces 93 # Use proper quoting for filenames with spaces
87 ffmpeg_command = [ 94 ffmpeg_command = [
88 'ffmpeg', 95 "ffmpeg",
89 '-y', # Overwrite output file if it exists 96 "-y", # Overwrite output file if it exists
90 '-i', filename, 97 "-i",
91 '-ac', '1', # Mono audio 98 filename,
92 '-b:a', '500', # 500k bitrate 99 "-ac",
93 '-acodec', 'libopus', 100 "1", # Mono audio
94 output_filename 101 "-b:a",
102 "500", # 500k bitrate
103 "-acodec",
104 "libopus",
105 output_filename,
95 ] 106 ]
96 107
97 try: 108 try:
98 logger.info(f"Running FFmpeg command: {' '.join(ffmpeg_command)}") 109 logger.info(f"Running FFmpeg command: {' '.join(ffmpeg_command)}")
99 process = await asyncio.create_subprocess_exec( 110 process = await asyncio.create_subprocess_exec(
100 *ffmpeg_command, 111 *ffmpeg_command,
101 stdout=asyncio.subprocess.PIPE, 112 stdout=asyncio.subprocess.PIPE,
102 stderr=asyncio.subprocess.PIPE 113 stderr=asyncio.subprocess.PIPE,
103 ) 114 )
104 115
105 _, stderr = await process.communicate() 116 _, stderr = await process.communicate()
106 117
107 if process.returncode != 0: 118 if process.returncode != 0:
108 error_msg = stderr.decode() 119 error_msg = stderr.decode()
109 logger.error(f"FFmpeg error ({process.returncode}): {error_msg}") 120 logger.error(f"FFmpeg error ({process.returncode}): {error_msg}")
110 await ctx.respond("eror kompresujync pilk", ephemeral=True) 121 await ctx.respond("eror kompresujync pilk", ephemeral=True)
111 return None 122 return None
112 123
113 if not os.path.exists(output_filename): 124 if not os.path.exists(output_filename):
114 logger.error(f"Output file was not created: {output_filename}") 125 logger.error(f"Output file was not created: {output_filename}")
115 await ctx.respond("eror kompresujync pilk - output file not created", ephemeral=True) 126 await ctx.respond(
127 "eror kompresujync pilk - output file not created", ephemeral=True
128 )
116 return None 129 return None
117 130
118 logger.info(f"Successfully compressed file: {output_filename}") 131 logger.info(f"Successfully compressed file: {output_filename}")
119 return output_filename 132 return output_filename
120 133
121 except Exception as e: 134 except Exception as e:
122 logger.error(f"Error compressing file: {str(e)}", exc_info=True) 135 logger.error(f"Error compressing file: {str(e)}", exc_info=True)
123 await ctx.respond(f"eror kompresujync pilk: {str(e)}", ephemeral=True) 136 await ctx.respond(f"eror kompresujync pilk: {str(e)}", ephemeral=True)