aboutsummaryrefslogtreecommitdiffstats
path: root/cogs/music/play_compressed.py
blob: 0d4901c625b0b267d36f936b319707d8722582e1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import asyncio
import os
import subprocess

import discord
from discord.ext import commands
from youtubesearchpython import VideosSearch


class GrajcujZkompresowane(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @staticmethod
    def prepend_title_to_file(file_path, title):
        try:
            with open(file_path, 'rb') as original:
                data = original.read()
            with open(file_path, 'wb') as modified:
                modified.write(f"{title}\n".encode('utf-8'))
                modified.write(data)
        except Exception as e:
            print(f"Failed to prepend title: {e}")

    @staticmethod
    def compress_audio(input_path):
        base, ext = os.path.splitext(input_path)
        output_path = f"{base}_compressed.opus"
        ffmpeg_command = f"ffmpeg -i {input_path} -ac 1 -b:a 500 -acodec libopus {output_path}"
        subprocess.run(ffmpeg_command, check=True, shell=True)
        return output_path

    @commands.slash_command(name="grajcuj_zkompresowane", description="grajcuj zkompresowane melodyje")
    async def grajcuj_zkompresowane(self, ctx, *, search: str):
        await ctx.defer()
        if not (ctx.author.voice and ctx.author.voice.channel):
            await ctx.followup.send("nie jesteś w kanale głosowym")
            return
        channel = ctx.author.voice.channel
        if ctx.voice_client is not None:
            vc = ctx.voice_client
            await vc.move_to(channel)
        else:
            vc = await channel.connect()
        bot_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        music_dir = os.path.join(bot_dir, "temp", "music")
        if not os.path.exists(music_dir):
            os.makedirs(music_dir)
        videos_search = VideosSearch(search, limit=1)
        result = videos_search.result()
        if not result['result']:
            await ctx.followup.send("Could not find a video for your search.", ephemeral=True)
            return
        video = result['result'][0]
        video_id = video['id']
        title = video['title']
        url = video['link']
        filename = f"{video_id}.mp3"
        file_path = os.path.join(music_dir, filename)
        compressed_file_path = os.path.join(music_dir, f"{video_id}_compressed.opus")
        if os.path.exists(compressed_file_path):
            found_file = compressed_file_path
            found_title = title
        else:
            if not os.path.exists(file_path):
                cmd = [
                    "yt-dlp",
                    "-x",
                    "--audio-format", "mp3",
                    "-o", file_path,
                    url
                ]
                process = await asyncio.create_subprocess_exec(*cmd)
                await process.communicate()
                self.prepend_title_to_file(file_path, title)
            if not os.path.exists(compressed_file_path):
                try:
                    compressed_file_path = self.compress_audio(file_path)
                except subprocess.CalledProcessError as e:
                    await ctx.followup.send(f"skompresowanie nie powiodło się: {str(e)}", ephemeral=True)
                    return
            found_file = compressed_file_path
            found_title = title
        title = found_title
        def after_playing(error):
            if error:
                print(f'Player error: {error}')
            coro = vc.disconnect()
            fut = asyncio.run_coroutine_threadsafe(coro, self.bot.loop)
            try:
                fut.result()
            except Exception as e:
                print(f'Error disconnecting: {e}')

        if vc.is_playing() or vc.is_paused():
            vc.stop()
        vc.play(discord.FFmpegPCMAudio(found_file), after=after_playing)
        await ctx.followup.send(f"gra (zkompresowane): {title}")


def setup(bot):
    bot.add_cog(GrajcujZkompresowane(bot))