import assemblyai as aai import discord from discord.ext import commands, voice_recv import logging from discord.opus import Decoder as OpusDecoder import wave # Replace with your API key aai.settings.api_key = "aa9962f0088a449a9c4ab2361e96cc08" discord.opus._load_default() # URL of the file to transcribe FILE_URL = "https://github.com/AssemblyAI-Community/audio-examples/raw/main/20230607_me_canadian_wildfires.mp3" # You can also transcribe a local file by passing in a file path # FILE_URL = './path/to/file.mp3' logger = logging.getLogger("discord") class SRBuffer(voice_recv.AudioSink): """Endpoint AudioSink that generates a wav file. Best used in conjunction with a silence generating sink. (TBD) """ CHANNELS = OpusDecoder.CHANNELS SAMPLE_WIDTH = OpusDecoder.SAMPLE_SIZE // OpusDecoder.CHANNELS SAMPLING_RATE = OpusDecoder.SAMPLING_RATE ##on member join - 5 plików buforowych na człowieka otwarty jest tylko aktualny i następny #on member disconnect - dropujemy go # event: BasicSinkWriteCB, # rtcp_event: Optional[BasicSinkWriteRTCPCB] = None, # self.cb = event # self.cb_rtcp = rtcp_event # def write(self, user: Optional[User], data: VoiceData) -> None: # self.cb(user, data) # @AudioSink.listener() # def on_rtcp_packet(self, packet: RTCPPacket, guild: discord.Guild) -> None: # self.cb_rtcp(packet) if self.cb_rtcp else None def __init__(self, destination): super().__init__() self._file: wave.Wave_write = wave.open(destination, 'wb') self._file.setnchannels(self.CHANNELS) self._file.setsampwidth(self.SAMPLE_WIDTH) self._file.setframerate(self.SAMPLING_RATE) self.user_list = [] def wants_opus(self) -> bool: return False def write(self, user, data) -> None: logger.info("writing to file %s", self._file) logger.info("user: %s", user) self._file.writeframes(data.pcm) def cleanup(self) -> None: try: self._file.close() except Exception: logger.warning("WaveSink got error closing file on cleanup", exc_info=True) class Transcriber(commands.Cog): def __init__(self, bot): def callback(user, data): logger.info(f"Got packet from {user}") self.bot = bot self._last_member = None self.wsink = voice_recv.SRBuffer(destination="/home/pi/Conjurer/wav.wav") async def transcribe(): config = aai.TranscriptionConfig(speaker_labels=True) transcriber = aai.Transcriber() transcript = transcriber.transcribe( FILE_URL, config=config ) for utterance in transcript.utterances: print(f"Speaker {utterance.speaker}: {utterance.text}") @commands.hybrid_command(name="transcribe") async def test(self, ctx): logger.info("Attempt transcribe") vc = await ctx.author.voice.channel.connect(cls=voice_recv.VoiceRecvClient) logger.info("Connected") vc.listen(self.wsink) @commands.command(name="stop_transcribe") async def stop(self, ctx): await ctx.voice_client.disconnect() async def setup(bot): await bot.add_cog(Transcriber(bot)) #1. zapisuj kwestie człowieka do pliku w którym będzie można stwierdzić kto co powiedział (callback z basicaudio + write z wavesinka). Zamykaj plik i wysyłaj do transkrypcji w momencie ciszy dłuższej niż 0.5s. Jeśli człowiek nadaje cały czas dawaj sygnał że nie można go transkrybować - i wyłaczaj zapis. #2. Transkrypcja to abstrakt - w zależności od tego która metoda jest włączona wysyła do odpowiedniego silnika, silniki offline odpalam na activcomie. Zaczynamy od assemblyai bo najlepiej wspiera polski. Potem zobaczymy co dalej.