Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ffmpeg:加载共享库时出错:libvpx.so.6:无法打开共享对象文件:没有此类文件或目录_Python_Ffmpeg_Libraries - Fatal编程技术网

Python ffmpeg:加载共享库时出错:libvpx.so.6:无法打开共享对象文件:没有此类文件或目录

Python ffmpeg:加载共享库时出错:libvpx.so.6:无法打开共享对象文件:没有此类文件或目录,python,ffmpeg,libraries,Python,Ffmpeg,Libraries,我正在用Python rewrite构建一个多工具discord机器人 所以我决定把音乐也加入其中。当我完成了这个机器人,并在我的本地pc上试用时,它工作得非常好。然而,当我上传到Heroku时,ffmpeg出现了一些错误 起初我认为Heroku是基于Linux的,所以我下载了适用于Linux的ffmpeg。还是不行。然后我添加了一个apt构建包,并以这种方式下载了它。不过,它现在起作用了,但出现了一个不同的错误。它查找ffmpeg,但未播放歌曲,并在控制台中显示: [ffmpeg:加载共享库时

我正在用Python rewrite构建一个多工具discord机器人

所以我决定把音乐也加入其中。当我完成了这个机器人,并在我的本地pc上试用时,它工作得非常好。然而,当我上传到Heroku时,ffmpeg出现了一些错误

起初我认为Heroku是基于Linux的,所以我下载了适用于Linux的ffmpeg。还是不行。然后我添加了一个apt构建包,并以这种方式下载了它。不过,它现在起作用了,但出现了一个不同的错误。它查找ffmpeg,但未播放歌曲,并在控制台中显示:

[ffmpeg:加载共享库时出错:libvpx.so.6:无法 打开共享对象文件:没有这样的文件或目录]

我如何解决这个问题

以下是全部代码:

import discord
from discord.ext import commands

import asyncio
import itertools
import sys
import traceback
from async_timeout import timeout
from functools import partial
from youtube_dl import YoutubeDL
import ctypes
import ctypes.util

@commands.Cog.listener()
async def on_ready(self):

    print("ctypes - Find opus:")
    a = ctypes.util.find_library('opus')
    print(a)
    
    print("Discord - Load Opus:")
    b = discord.opus.load_opus(a)
    print(b)
    
    print("Discord - Is loaded:")
    c = discord.opus.is_loaded()
    print(c)



ytdlopts = {
    'format': 'bestaudio/best',
    'outtmpl': 'downloads/%(extractor)s-%(id)s-%(title)s.%(ext)s',
    'restrictfilenames': True,
    'noplaylist': True,
    'nocheckcertificate': True,
    'ignoreerrors': False,
    'logtostderr': False,
    'quiet': True,
    'no_warnings': True,
    'default_search': 'auto',
    'source_address': '0.0.0.0'
}

ffmpegopts = {
    'before_options': '-nostdin',
    'options': '-vn'
}

ytdl = YoutubeDL(ytdlopts)


class VoiceConnectionError(commands.CommandError):


class InvalidVoiceChannel(VoiceConnectionError):



class YTDLSource(discord.PCMVolumeTransformer):

    def __init__(self, source, *, data, requester):
        super().__init__(source)
        self.requester = requester

        self.title = data.get('title')
        self.web_url = data.get('webpage_url')


    def __getitem__(self, item: str):
        return self.__getattribute__(item)

    @classmethod
    async def create_source(cls, ctx, search: str, *, loop, download=False):
        loop = loop or asyncio.get_event_loop()

        to_run = partial(ytdl.extract_info, url=search, download=download)
        data = await loop.run_in_executor(None, to_run)

        if 'entries' in data:
            data = data['entries'][0]

        await ctx.send(f'```ini\n[Added {data["title"]} to the Queue.]\n```')

        if download:
            source = ytdl.prepare_filename(data)
        else:
            return {'webpage_url': data['webpage_url'], 'requester': ctx.author, 'title': data['title']}

        return cls(discord.FFmpegPCMAudio(source), data=data, requester=ctx.author)

    @classmethod
    async def regather_stream(cls, data, *, loop):
        """Used for preparing a stream, instead of downloading.
        Since Youtube Streaming links expire."""
        loop = loop or asyncio.get_event_loop()
        requester = data['requester']

        to_run = partial(ytdl.extract_info, url=data['webpage_url'], download=False)
        data = await loop.run_in_executor(None, to_run)

        return cls(discord.FFmpegPCMAudio(data['url']), data=data, requester=requester)


class MusicPlayer(commands.Cog):

    __slots__ = ('bot', '_guild', '_channel', '_cog', 'queue', 'next', 'current', 'np', 'volume')

    def __init__(self, ctx):
        self.bot = ctx.bot
        self._guild = ctx.guild
        self._channel = ctx.channel
        self._cog = ctx.cog

        self.queue = asyncio.Queue()
        self.next = asyncio.Event()

        self.np = None
        self.volume = .5
        self.current = None

        ctx.bot.loop.create_task(self.player_loop())

    async def player_loop(self):
        """Our main player loop."""
        await self.bot.wait_until_ready()

        while not self.bot.is_closed():
            self.next.clear()

            try:
                    source = await self.queue.get()
            except asyncio.TimeoutError:
                return self.destroy(self._guild)

            if not isinstance(source, YTDLSource):
                try:
                    source = await YTDLSource.regather_stream(source, loop=self.bot.loop)
                except Exception as e:
                    await self._channel.send(f'There was an error processing your song.\n'
                                             f'```css\n[{e}]\n```')
                    continue

            source.volume = self.volume
            self.current = source

            self._guild.voice_client.play(source, after=lambda _: self.bot.loop.call_soon_threadsafe(self.next.set))
            self.np = await self._channel.send(f'**Now Playing:** `{source.title}` requested by '
                                               f'`{source.requester}`')
            await self.next.wait()

            source.cleanup()
            self.current = None

            try:
                await self.np.delete()
            except discord.HTTPException:
                pass

    def destroy(self, guild):
        """Disconnect and cleanup the player."""
        return self.bot.loop.create_task(self._cog.cleanup(guild))


class Music(commands.Cog):
    """Music related commands."""

    __slots__ = ('bot', 'players')

    def __init__(self, bot):
        self.bot = bot
        self.players = {}

    async def cleanup(self, guild):
        try:
            await guild.voice_client.disconnect()
        except AttributeError:
            pass

        try:
            del self.players[guild.id]
        except KeyError:
            pass

    async def __local_check(self, ctx):
        """A local check which applies to all commands in this cog."""
        if not ctx.guild:
            raise commands.NoPrivateMessage
        return True

    async def __error(self, ctx, error):
        """A local error handler for all errors arising from commands in this cog."""
        if isinstance(error, commands.NoPrivateMessage):
            try:
                return await ctx.send('This command can not be used in Private Messages.')
            except discord.HTTPException:
                pass
        elif isinstance(error, InvalidVoiceChannel):
            await ctx.send('Error connecting to Voice Channel. '
                           'Please make sure you are in a valid channel or provide me with one')

        print('Ignoring exception in command {}:'.format(ctx.command), file=sys.stderr)
        traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)

    def get_player(self, ctx):
        """Retrieve the guild player, or generate one."""
        try:
            player = self.players[ctx.guild.id]
        except KeyError:
            player = MusicPlayer(ctx)
            self.players[ctx.guild.id] = player

        return player

    @commands.command(name='connect', aliases=['join'])
    async def connect_(self, ctx):
        try:
            channel = ctx.author.voice.channel
        except AttributeError:
            raise InvalidVoiceChannel('No channel to join.')

        vc = ctx.voice_client

        if vc:
            if vc.channel.id == channel.id:
                return
            try:
                await vc.move_to(channel)
            except asyncio.TimeoutError:
                raise VoiceConnectionError(f'Moving to channel: <{channel}> timed out.')
        else:
            try:
                await channel.connect()
            except asyncio.TimeoutError:
                raise VoiceConnectionError(f'Connecting to channel: <{channel}> timed out.')

        await ctx.send(f'Connected to: **{channel}**', )

    @commands.command(name='play', aliases=['sing'])
    async def play_(self, ctx, *, search: str):
        await ctx.trigger_typing()

        vc = ctx.voice_client

        if not vc:
            await ctx.invoke(self.connect_)

        player = self.get_player(ctx)
        source = await YTDLSource.create_source(ctx, search, loop=self.bot.loop, download=False)

        await player.queue.put(source)

    @commands.command(name='pause')
    async def pause_(self, ctx):
        """Pause the currently playing song."""
        vc = ctx.voice_client

        if not vc or not vc.is_playing():
            return await ctx.send('I am not currently playing anything!')
        elif vc.is_paused():
            return

        vc.pause()
        await ctx.send(f'**`{ctx.author}`**: Paused the song!')

    @commands.command(name='resume')
    async def resume_(self, ctx):
        """Resume the currently paused song."""
        vc = ctx.voice_client

        if not vc or not vc.is_connected():
            return await ctx.send('I am not currently playing anything!', )
        elif not vc.is_paused():
            return

        vc.resume()
        await ctx.send(f'**`{ctx.author}`**: Resumed the song!')

    @commands.command(name='skip')
    async def skip_(self, ctx):
        """Skip the song."""
        vc = ctx.voice_client

        if not vc or not vc.is_connected():
            return await ctx.send('I am not currently playing anything!')

        if vc.is_paused():
            pass
        elif not vc.is_playing():
            return

        vc.stop()
        await ctx.send(f'**`{ctx.author}`**: Skipped the song!')

    @commands.command(name='queue', aliases=['q', 'playlist'])
    async def queue_info(self, ctx):
        """Retrieve a basic queue of upcoming songs."""
        vc = ctx.voice_client

        if not vc or not vc.is_connected():
            return await ctx.send('I am not currently connected to voice!')

        player = self.get_player(ctx)
        if player.queue.empty():
            return await ctx.send('There are currently no more queued songs.')

        upcoming = list(itertools.islice(player.queue._queue, 0, 5))

        fmt = '\n'.join(f'**`{_["title"]}`**' for _ in upcoming)
        embed = discord.Embed(title=f'Upcoming - Next {len(upcoming)}', description=fmt)

        await ctx.send(embed=embed)

    @commands.command(name='now_playing', aliases=['np', 'current', 'currentsong', 'playing'])
    async def now_playing_(self, ctx):
        """Display information about the currently playing song."""
        vc = ctx.voice_client

        if not vc or not vc.is_connected():
            return await ctx.send('I am not currently connected to voice!', )

        player = self.get_player(ctx)
        if not player.current:
            return await ctx.send('I am not currently playing anything!')

        try:
            await player.np.delete()
        except discord.HTTPException:
            pass

        player.np = await ctx.send(f'**Now Playing:** `{vc.source.title}` '
                                   f'requested by `{vc.source.requester}`')

    @commands.command(name='volume', aliases=['vol'])
    async def change_volume(self, ctx, *, vol: float):
        """Change the player volume.
        Parameters
        ------------
        volume: float or int [Required]
            The volume to set the player to in percentage. This must be between 1 and 100.
        """
        vc = ctx.voice_client

        if not vc or not vc.is_connected():
            return await ctx.send('I am not currently connected to voice!', )

        if not 0 < vol < 101:
            return await ctx.send('Please enter a value between 1 and 100.')

        player = self.get_player(ctx)

        if vc.source:
            vc.source.volume = vol / 100

        player.volume = vol / 100
        await ctx.send(f'**`{ctx.author}`**: Set the volume to **{vol}%**')

    @commands.command(name='stop', aliases=['leave'])
    async def stop_(self, ctx):
        vc = ctx.voice_client

        if not vc or not vc.is_connected():
            return await ctx.send('I am not currently playing anything!')

        await self.cleanup(ctx.guild)


def setup(client):
    client.add_cog(Music(client))
导入不一致
从discord.ext导入命令
导入异步
进口itertools
导入系统
导入回溯
从异步\u超时导入超时
从functools导入部分
从youtube\u dl导入YoutubeDL
导入ctypes
导入ctypes.util
@commands.Cog.listener()
异步def on_就绪(自):
打印(“ctypes-查找作品:”)
a=ctypes.util.find_库('opus'))
印刷品(a)
打印(“不和谐-加载作品:”)
b=不和谐的工作负载\u工作负载(a)
印刷品(b)
打印(“不协调-已加载:”)
c=不和谐。作品已加载()
印刷品(c)
ytdlopts={
“格式”:“最佳音频/最佳”,
'outtmpl':'downloads/%(提取器)s-%(id)s-%(title)s.%(ext)s',
“RestrictFileName”:True,
'noplaylist':True,
“nocheckcertificate”:正确,
“忽略错误”:False,
“logtostderr”:False,
“安静”:没错,
“无警告”:正确,
“默认搜索”:“自动”,
“源地址”:“0.0.0.0”
}
ffmpegopts={
“在选项之前”:“-nostdin”,
'选项':'-vn'
}
ytdl=YTDLUPEDL(ytdlopts)
类VoiceConnectionError(commands.CommandError):
类InvalidVoiceChannel(VoiceConnectionError):
YTDLSource类(discord.PCMVolumeTransformer):
定义初始化(自身、源、*、数据、请求者):
super().\uuuu init\uuuuu(源)
self.requester=请求者
self.title=data.get('title')
self.web\u url=data.get('webpage\u url')
def uu getitem uu(self,item:str):
返回自我。获取属性(项目)
@类方法
异步定义创建源(cls、ctx、搜索:str、*、循环、下载=False):
loop=循环或异步IO.get\u event\u loop()
to_run=partial(ytdl.extract_info,url=search,download=download)
数据=等待循环。在执行器中运行(无,要运行)
如果数据中有“条目”:
数据=数据['entries'][0]
等待ctx.send(f'``ini\n[将{data[“title”]}添加到队列。]\n`````)
如果下载:
source=ytdl.prepare\u文件名(数据)
其他:
返回{'webpage_url':数据['webpage_url'],'requester':ctx.author,'title':数据['title']}
返回cls(discord.FFmpegPCMAudio(源),data=data,requester=ctx.author)
@类方法
异步def regather_流(cls、数据、*、循环):
“”用于准备流,而不是下载。
由于Youtube流媒体链接过期。”“”
loop=循环或异步IO.get\u event\u loop()
请求者=数据[“请求者”]
to_run=partial(ytdl.extract_info,url=data['webpage_url'],download=False)
数据=等待循环。在执行器中运行(无,要运行)
返回cls(discord.FFmpegPCMAudio(数据['url']),数据=数据,请求者=请求者)
类MusicLayer(commands.Cog):
__插槽(bot、guild、channel、cog、queue、next、current、np、volume)
定义初始化(自身,ctx):
self.bot=ctx.bot
self.\u guild=ctx.guild
自通道=ctx.channel
自身坐标=ctx.cog
self.queue=asyncio.queue()
self.next=asyncio.Event()
self.np=无
self.volume=.5
自身电流=无
ctx.bot.loop.create_任务(self.player_loop())
异步def播放器_循环(自):
“”“我们的主要玩家循环。”“”
等待self.bot。等待,直到准备就绪()
而不是self.bot.is_closed():
self.next.clear()
尝试:
source=等待self.queue.get()
除asyncio.TimeoutError外:
返回自我毁灭(自我公会)
如果不存在(源,YTDLSource):
尝试:
source=wait YTDLSource.regather_流(source,loop=self.bot.loop)
例外情况除外,如e:
等待self.\u channel.send(f'处理您的歌曲时出错。\n'
f'``css\n[{e}]\n````)
持续
source.volume=self.volume
自身电流=源
self.\u guild.voice\u client.play(source,after=lambda.\uself.bot.loop.call\u soon\u threadsafe(self.next.set))
self.np=等待self.\u channel.send(f'**正在播放:*`{source.title}`requested by'
f'`{source.requester}`'))
等待self.next.wait()
source.cleanup()
自身电流=无
尝试:
wait self.np.delete()
除discord.HTTPException外:
通过
def销毁(自我,公会):
“”“断开并清理播放机。”“”
返回self.bot.loop.create_任务(self._cog.cleanup(guild))
课堂音乐(commands.Cog):
“”“与音乐相关的命令。”“”
__老虎机('bot','players'))
def uuu init uuuu(自我,机器人):
self.bot=bot
self.players={}
异步def清理(自、公会):
尝试:
等待公会。语音客户端。断开连接()
除属性错误外:
通过
尝试:
del self.players[guild.id]
除KeyError外:
通过
异步定义本地检查(自检、ctx):
“”“适用于此cog中所有命令的本地检查。”“”
如果不是ctx.guild:
提高通信能力