将音频内容从 YouTube 流式传输到 Discord

问题描述 投票:0回答:1

我正在使用

discord.py
开发一个 Discord 机器人,作为该机器人的一部分,我的任务是创建音乐功能。我实际上已经这样做了,机器人将使用
pytube
模块播放歌曲。它通过下载最佳音频源,将其转换为
.wav
(以便 Discord 可以理解),然后打开该文件并通过语音客户端播放该文件,让语音通话中的每个人都能听到来实现这一点。这样做的问题是,由于必须在开始播放之前下载完整的音频,因此速度非常慢。这是当前的代码:

    # Plays a Youtube object in the voice call.
    async def play_youtube_object(self, yt:YouTube, interaction:discord.Interaction, voice_client):
        try:
            # Extract audio stream with highest audio bitrate
            audio_stream = yt.streams.filter(file_extension="webm").order_by('abr').desc().first()
            audio_filename = os.path.abspath(rf"./data/music cache/{yt.author}{hex(random.randint(1,999999))[2:]}")
            audio_stream.download(filename=audio_filename+".webm")

            # Convert from .webm to .wav
            audio_f = moviepy.AudioFileClip(audio_filename+".webm")
            audio_f.write_audiofile(audio_filename+".wav", fps=48000) # Discord requires 48kHz, 44.1kHz causes it to speed up by 8.125%.
            remove_file(audio_filename + ".webm") # Remove the .webm since we're now done with it

            # Open the downloaded audio file in binary mode and create a PCMAudio object which can be interpreted by discord
            f = open(audio_filename+".wav", "rb")
            source = PCMAudio(f)

            # Play the audio
            voice_client.play(source)

            # Wait until the song is finished before ending the function
            while voice_client.is_playing() or voice_client.is_paused():
                await asyncio.sleep(1)
            f.close()
        except ...

我对此的潜在解决方案(如果可能的话)是直接从 YouTube 流式传输音频,将其转换为

PCMAudio
源并将其实时传送到 Discord。问题是,我不知道从哪里开始实施。是否可以?如果是这样,我应该从哪里开始研究呢?有一个模块可以帮助吗?

实际上,目标是获得接近即时的反馈:

pytube
YouTube
对象被解析为
play_youtube_object
子例程,然后音频立即开始在 Discord 中为用户播放(或者至少不超过 20)目前是第二次延迟)。

如有任何帮助或指点,请先感谢您! :D

python audio discord.py youtube pytube
1个回答
0
投票

解决了!感谢评论中的一些帮助,为我指明了正确的方向。使用

yt-dlp
并使用
ffmpeg
进行管道传输效果非常出色,消除了讨厌的延迟(现在大约 3 秒,一点也不差)。

这是工作代码,目前有点混乱,但我想在继续处理之前我应该先完成这篇文章:

    async def play_youtube_url(self, url, interaction:discord.Interaction, voice_client):
        ydl_opts = {
            'format': 'bestaudio/best',
            'quiet': True,
            'noplaylist': True
        }

        try:
            with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                info_dict = ydl.extract_info(url, download=False)
                audio_url = info_dict['url']

            ffmpeg_options = {
                'options': '-vn'
            }

            source = FFmpegPCMAudio(audio_url, **ffmpeg_options)
            voice_client.play(source)

            while voice_client.is_playing() or voice_client.is_paused():
                await asyncio.sleep(1)
        except Exception as e:
            await interaction.followup.send(f"An error occured: {e}")

感谢

yt-dlp
,该程序将能够处理更多的音频源,只是不能处理具有 DRM 保护的音频源(如 Spotify),所以我可能需要看看是否可以找到解决方法,或者是否有人知道什么请评论:)。

© www.soinside.com 2019 - 2024. All rights reserved.