feat: dodanie możliwości przesyłania własnych plików na serwer (wszystkie formaty ffmpeg), odtwarzanie jednym kliknięciem z web i komenda /playfile w Discord

This commit is contained in:
mmacierzanka committed 2026-07-04 15:33:43 +02:00
1 parent 444b797cd0
commit dfd681be04
6 files changed
+395 -5

No files matched your search

+38
View File
@@ -2,6 +2,7 @@ import discord
import yt_dlp as youtube_dl
import asyncio
import uuid
import os
ytdl_format_options = {
'format': 'bestaudio/best',
@@ -25,6 +26,22 @@ ffmpeg_options = {
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
async def get_file_duration(filepath):
try:
proc = await asyncio.create_subprocess_exec(
'ffprobe', '-v', 'error', '-show_entries', 'format=duration',
'-of', 'default=noprint_wrappers=1:nokey=1', filepath,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
stdout, _ = await proc.communicate()
if proc.returncode == 0:
return float(stdout.decode().strip())
except Exception as e:
print(f"Error getting duration with ffprobe: {e}")
return 0.0
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
@@ -51,3 +68,24 @@ class YTDLSource(discord.PCMVolumeTransformer):
filename = data['url'] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
@classmethod
async def from_file(cls, filepath, *, loop=None, title=None):
loop = loop or asyncio.get_event_loop()
duration = await get_file_duration(filepath)
filename_only = os.path.basename(filepath)
display_title = title or os.path.splitext(filename_only)[0]
data = {
'title': display_title,
'url': filepath,
'webpage_url': None,
'duration': duration,
'is_local': True,
'filepath': filepath
}
local_ffmpeg_options = {
'options': '-vn'
}
return cls(discord.FFmpegPCMAudio(filepath, **local_ffmpeg_options), data=data)