discord.py Heroku FFmpeg issue - heroku

hi I'm trying to deploy a discord bot on heroku. i'm using ffmpeg to stream music to a voice channel. i tried it local on my windows and got it working but when I deployed it on heroku, throws this exception and says nothing!
I use these buildpacks:
heroku/python
https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git
I appreciate if someone can help
here's a sample code:
vid = pafy.new("https://www.youtube.com/watch?v=gdL7s0kw0SM")
print("Pafy Vid Created!")
audio = vid.getbestaudio()
print("Pafy Audio Created!")
try:
// self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
self.vc[ctx.guild.id].play(FFmpegPCMAudio(Song['source'], **self.FFMPEG_OPTIONS), after=lambda _: E.set())
print("Playing Music!!!")
except Exception as ex:
print(ex)
and here's what I got:
2021-09-20T14:31:19.958645+00:00 app[worker.1]: Pafy Vid Created!
2021-09-20T14:31:19.958889+00:00 app[worker.1]: Pafy Audio Created!
2021-09-20T14:31:20.447278+00:00 app[worker.1]:

thanks to #Dominik I added the buildpacks bellow and it worked:
1.https://github.com/xrisk/heroku-opus
2.https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git

Related

How can I use youtube_dl with a discord.py bot?

I am making a music discord bot using python and I am having an issue where I download the video as a .webm file but then ffmpeg is not able to read this file and throws the error below.
ERROR: WARNING: unable to obtain file audio codec with ffprobe
2022-11-30 20:57:06 ERROR discord.ext.commands.bot Ignoring exception in command play
Traceback (most recent call last):
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 2115, in post_process
files_to_delete, info = pp.run(info)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\postprocessor\ffmpeg.py", line 277, in run
raise PostProcessingError('WARNING: unable to obtain file audio codec with ffprobe')
youtube_dl.utils.PostProcessingError: WARNING: unable to obtain file audio codec with ffprobe
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\discord\ext\commands\core.py", line 229, in wrapped
ret = await coro(*args, **kwargs)
File "C:\Users\willf\Desktop\DiscordBots\code.py", line 31, in play
ydl.download([url])
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 2068, in download
res = self.extract_info(
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 808, in extract_info
return self.__extract_info(url, ie, download, extra_info, process)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 815, in wrapper
return func(self, *args, **kwargs)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 847, in __extract_info
return self.process_ie_result(ie_result, download, extra_info)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 881, in process_ie_result
return self.process_video_result(ie_result, download=download)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 1692, in process_video_result
self.process_info(new_info)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 2050, in process_info
self.post_process(filename, info_dict)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 2117, in post_process
self.report_error(e.msg)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 628, in report_error
self.trouble(error_message, tb)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\youtube_dl\YoutubeDL.py", line 598, in trouble
raise DownloadError(message, exc_info)
youtube_dl.utils.DownloadError: ERROR: WARNING: unable to obtain file audio codec with ffprobe
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\discord\ext\commands\bot.py", line 1349, in invoke
await ctx.command.invoke(ctx)
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\discord\ext\commands\core.py", line 1023, in invoke
await injected(*ctx.args, **ctx.kwargs) # type: ignore
File "C:\Users\willf\Desktop\DiscordBots\venv\lib\site-packages\discord\ext\commands\core.py", line 238, in wrapped
raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: DownloadError: ERROR: WARNING: unable to obtain file audio codec with ffprobe
Here is my current code. It breaks between line 30 and 35.
import discord
from discord.ext import commands
import youtube_dl
import os
client = commands.Bot(command_prefix="q!", intents=discord.Intents.all())
#client.command()
async def play(ctx, url: str):
# song_there = os.path.isfile("song.mp3")
# try:
# if song_there:
# os.remove("song.mp3")
# except PermissionError:
# await ctx.send("Wait for the current playing music to end or use the 'stop' command")
# return
voiceChannel = discord.utils.get(ctx.guild.voice_channels, name='General')
await voiceChannel.connect()
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
for file in os.listdir("./"):
if file.endswith(".mp3"):
os.rename(file, "song.mp3")
voice.play(discord.FFmpegPCMAudio("song.mp3"))
#client.command()
async def leave(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice.is_connected():
await voice.disconnect()
else:
await ctx.send("The bot is not connected to a voice channel.")
#client.command()
async def pause(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice.is_playing():
voice.pause()
else:
await ctx.send("Currently no audio is playing.")
#client.command()
async def resume(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
if voice.is_paused():
voice.resume()
else:
await ctx.send("The audio is not paused.")
#client.command()
async def stop(ctx):
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
voice.stop()
client.run('Token')
I have tried converting the file to an mp3 but I am unsure how to get this to work properly. All I need is for the .webm file to be converted to a .mp3 file so that discord can read this.
You need to add ffmpeg to path
Open windows search bar and open up 'edit the system environment variables'
Then click on environment variables on the bottom
Click on path and edit
after that just find where you downloaded ffmpeg and add it

Why can't whiltelist mint in candymachine UI?

I am a beginner of metaplex.
What I want to achieve is to provide the feature of presale, which means white list!.
I followed the instruction in metaplex to set config.json.
}
"whitelistMintSettings": {
"mode" : { "neverBurn": true },
"mint" : "xxxxKnH5",
"presale" : true,
"discountPrice" : 0.5
},
Here, I set xxxxKnH5 as a member of whitelist and let him mint before public mint.
Then I update_candy_machine (this works fine).
But in the UI interface, I always got error message:
There was a problem fetching whitelist token balance
Home.tsx:184 Error: failed to get token account balance: Invalid param: could not find account
Any idea of why I received this message and how can I fix it?
Make sure that the "mint": "XXX...X", line should contain a 0 decimals SPL-TOKEN.
Moreover, for airdropping it to users, you join the Metaplex Discord server and check the #airdrop-bash thread. It contains a JS script that'll make airdropping the token to wallets alot easier:)

Pyppeteer: Browser closed unexpectedly in AWS Lambda

I'm running into this error in AWS Lambda. It appears that the devtools websocket is not up. Not sure how to fix it. Any ideas? Thanks for your time.
Exception originated from get_ws_endpoint() due to websocket response timeout https://github.com/pyppeteer/pyppeteer/blob/ad3a0a7da221a04425cbf0cc92e50e93883b077b/pyppeteer/launcher.py#L225
Lambda code:
import os
import json
import asyncio
import logging
import boto3
import pyppeteer
from pyppeteer import launch
logger = logging.getLogger()
logger.setLevel(logging.INFO)
pyppeteer.DEBUG = True # print suppressed errors as error log
def lambda_handler(event, context):
asyncio.get_event_loop().run_until_complete(main())
async def main():
browser = await launch({
'headless': True,
'args': [
'--no-sandbox'
]
})
page = await browser.newPage()
await page.goto('http://example.com')
await page.screenshot({'path': '/tmp/example.png'})
await browser.close()
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
Exception:
Response:
{
"errorMessage": "Browser closed unexpectedly:\n",
"errorType": "BrowserError",
"stackTrace": [
" File \"/var/task/lambda_handler.py\", line 23, in lambda_handler\n asyncio.get_event_loop().run_until_complete(main())\n",
" File \"/var/lang/lib/python3.8/asyncio/base_events.py\", line 616, in run_until_complete\n return future.result()\n",
" File \"/var/task/lambda_handler.py\", line 72, in main\n browser = await launch({\n",
" File \"/opt/python/pyppeteer/launcher.py\", line 307, in launch\n return await Launcher(options, **kwargs).launch()\n",
" File \"/opt/python/pyppeteer/launcher.py\", line 168, in launch\n self.browserWSEndpoint = get_ws_endpoint(self.url)\n",
" File \"/opt/python/pyppeteer/launcher.py\", line 227, in get_ws_endpoint\n raise BrowserError('Browser closed unexpectedly:\\n')\n"
]
}
Request ID:
"06be0620-8b5c-4600-a76e-bc785210244e"
Function Logs:
START RequestId: 06be0620-8b5c-4600-a76e-bc785210244e Version: $LATEST
---- files in /tmp ----
[W:pyppeteer.chromium_downloader] start chromium download.
Download may take a few minutes.
0%| | 0/108773488 [00:00<?, ?it/s]
11%|█▏ | 12267520/108773488 [00:00<00:00, 122665958.31it/s]
27%|██▋ | 29470720/108773488 [00:00<00:00, 134220418.14it/s]
42%|████▏ | 46172160/108773488 [00:00<00:00, 142570388.86it/s]
58%|█████▊ | 62607360/108773488 [00:00<00:00, 148471487.93it/s]
73%|███████▎ | 79626240/108773488 [00:00<00:00, 154371569.93it/s]
88%|████████▊ | 95754240/108773488 [00:00<00:00, 156353972.12it/s]
100%|██████████| 108773488/108773488 [00:00<00:00, 161750092.47it/s]
[W:pyppeteer.chromium_downloader]
chromium download done.
[W:pyppeteer.chromium_downloader] chromium extracted to: /tmp/local-chromium/588429
-----
/tmp/local-chromium/588429/chrome-linux/chrome
[ERROR] BrowserError: Browser closed unexpectedly:
Traceback (most recent call last):
  File "/var/task/lambda_handler.py", line 23, in lambda_handler
    asyncio.get_event_loop().run_until_complete(main())
  File "/var/lang/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
    return future.result()
  File "/var/task/lambda_handler.py", line 72, in main
    browser = await launch({
  File "/opt/python/pyppeteer/launcher.py", line 307, in launch
    return await Launcher(options, **kwargs).launch()
  File "/opt/python/pyppeteer/launcher.py", line 168, in launch
    self.browserWSEndpoint = get_ws_endpoint(self.url)
  File "/opt/python/pyppeteer/launcher.py", line 227, in get_ws_endpoint
    raise BrowserError('Browser closed unexpectedly:\n')END RequestId: 06be0620-8b5c-4600-a76e-bc785210244e
REPORT RequestId: 06be0620-8b5c-4600-a76e-bc785210244e Duration: 33370.61 ms Billed Duration: 33400 ms Memory Size: 3008 MB Max Memory Used: 481 MB Init Duration: 445.58 ms
I think BrowserError: Browser closed unexpectedly is just the error you get when Chrome crashes for whatever reason. It would be nice if pyppeteer printed out the error, but it doesn't.
To track things down, it's helpful to pull up the exact command that pyppeteer runs. You can do that this way:
>>> from pyppeteer.launcher import Launcher
>>> ' '.join(Launcher().cmd)
/root/.local/share/pyppeteer/local-chromium/588429/chrome-linux/chrome --disable-background-networking --disable-background-timer-throttling --disable-breakpad --disable-browser-side-navigation --disable-client-side-phishing-detection --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=site-per-process --disable-hang-monitor --disable-popup-blocking --disable-prompt-on-repost --disable-sync --disable-translate --metrics-recording-only --no-first-run --safebrowsing-disable-auto-update --enable-automation --password-store=basic --use-mock-keychain --headless --hide-scrollbars --mute-audio about:blank --no-sandbox --remote-debugging-port=33423 --user-data-dir=/root/.local/share/pyppeteer/.dev_profile/tmp5cj60q6q
When I ran that command in my Docker image, I got the following error:
$ /root/.local/share/pyppeteer/local-chromium/588429/chrome-linux/chrome # ...
/root/.local/share/pyppeteer/local-chromium/588429/chrome-linux/chrome:
error while loading shared libraries:
libnss3.so: cannot open shared object file: No such file or directory
So I installed libnss3:
apt-get install -y libnss3
Then I ran the command again and got a different error:
$ /root/.local/share/pyppeteer/local-chromium/588429/chrome-linux/chrome # ...
[0609/190651.188666:ERROR:zygote_host_impl_linux.cc(89)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
So I needed to change my launch command to something like:
browser = await launch(headless=True, args=['--no-sandbox'])
and now it works!
Answering my own question.
Finally I was able to run Pyppeteer(v0.2.2) with Python 3.6 and 3.7 (not 3.8) after I bundled chromium binary in a lambda layer.
So in summary, it appears to work only when its configured to run with user provided chromium executable path and not with automatically downloaded chrome. Probably some race condition or something.
Got Chromium from https://github.com/adieuadieu/serverless-chrome/releases/download/v1.0.0-41/stable-headless-chromium-amazonlinux-2017-03.zip
browser = await launch(
headless=True,
executablePath='/opt/python/headless-chromium',
args=[
'--no-sandbox',
'--single-process',
'--disable-dev-shm-usage',
'--disable-gpu',
'--no-zygote'
])
Issue posted on repo https://github.com/pyppeteer/pyppeteer/issues/108
I have been trying to run pyppeteer in a Docker container and ran into the same issue.
Finally managed to fix it thanks to this comment: https://github.com/miyakogi/pyppeteer/issues/14#issuecomment-348825238
I installed Chrome manually through apt
curl -sSL https://dl.google.com/linux/linux_signing_key.pub | apt-key add -
echo "deb [arch=amd64] https://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list
apt update -y && apt install -y google-chrome-stable
and then specified the path when launching the browser.
You also have to run it in headless and with args "--no-sandbox"
browser = await launch(executablePath='/usr/bin/google-chrome-stable', headless=True, args=['--no-sandbox'])
Hope this will help!
If anybody is running on Heroku and facing the same error:
Add the buildpack : The url for the buildpack is below :
https://github.com/jontewks/puppeteer-heroku-buildpack
Ensure that you're using --no-sandbox mode
launch({ args: ['--no-sandbox'] })
Make sure all the necessary dependencies are installed. You can run ldd /path/to/your/chrome | grep not on a Linux machine to check which dependencies are missing.
In my case, i get this:
libatk-bridge-2.0.so.0 => not found
libgtk-3.so.0 => not found
and then install dependencies:
sudo apt-get install at-spi2-atk gtk3
and now it works!

How do I setup Airflow's email configuration to send an email on errors?

I'm trying to make an Airflow task intentionally fail and error out by passing in a Bash line (thisshouldnotrun) that doesn't work. Airflow is outputting the following:
[2017-06-15 17:44:17,869] {bash_operator.py:94} INFO - /tmp/airflowtmpLFTMX7/run_bashm2MEsS: line 7: thisshouldnotrun: command not found
[2017-06-15 17:44:17,869] {bash_operator.py:97} INFO - Command exited with return code 127
[2017-06-15 17:44:17,869] {models.py:1417} ERROR - Bash command failed
Traceback (most recent call last):
File "/home/ubuntu/.local/lib/python2.7/site-packages/airflow/models.py", line 1374, in run
result = task_copy.execute(context=context)
File "/home/ubuntu/.local/lib/python2.7/site-packages/airflow/operators/bash_operator.py", line 100, in execute
raise AirflowException("Bash command failed")
AirflowException: Bash command failed
[2017-06-15 17:44:17,871] {models.py:1433} INFO - Marking task as UP_FOR_RETRY
[2017-06-15 17:44:17,878] {models.py:1462} ERROR - Bash command failed
Traceback (most recent call last):
File "/home/ubuntu/.local/bin/airflow", line 28, in <module>
args.func(args)
File "/home/ubuntu/.local/lib/python2.7/site-packages/airflow/bin/cli.py", line 585, in test
ti.run(ignore_task_deps=True, ignore_ti_state=True, test_mode=True)
File "/home/ubuntu/.local/lib/python2.7/site-packages/airflow/utils/db.py", line 53, in wrapper
result = func(*args, **kwargs)
File "/home/ubuntu/.local/lib/python2.7/site-packages/airflow/models.py", line 1374, in run
result = task_copy.execute(context=context)
File "/home/ubuntu/.local/lib/python2.7/site-packages/airflow/operators/bash_operator.py", line 100, in execute
raise AirflowException("Bash command failed")
airflow.exceptions.AirflowException: Bash command failed
Will Airflow send an email for these kind of errors? If not, what would be the best way to send an email for these errors?
I'm not even sure if airflow.cfg is setup properly... Since the ultimate goal is to test the email alerting notification, I want to make sure airflow.cfg is setup properly. Here's the setup:
[email]
email_backend = airflow.utils.email.send_email_smtp
[smtp]
# If you want airflow to send emails on retries, failure, and you want to use
# the airflow.utils.email.send_email_smtp function, you have to configure an
# smtp server here
smtp_host = emailsmtpserver.region.amazonaws.com
smtp_starttls = True
smtp_ssl = False
# Uncomment and set the user/pass settings if you want to use SMTP AUTH
# smtp_user = airflow_data_user
# smtp_password = password
smtp_port = 587
smtp_mail_from = airflow_data_user#domain.com
What is smtp_starttls? I can't find any info for it in the documentation or online. If we have 2-factor authentication needed to view emails, will that be an issue here for Airflow?
Here's my Bash command:
task1_bash_command = """
export PATH=/home/ubuntu/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin
export rundate=`TZ='America/Los_Angeles' date +%F -d "yesterday"`
export AWS_CONFIG_FILE="/home/ubuntu/.aws/config"
/home/ubuntu/bin/snowsql -f //home/ubuntu/sql/script.sql 1> /home/ubuntu/logs/"$rundate"_dev.log 2> /home/ubuntu/logs/"$rundate"_error_dev.log
if [ -e /home/ubuntu/logs/"$rundate"_error_dev.log ]
then
exit 64
fi
And my task:
task1 = BashOperator(
task_id = 'run_bash',
bash_command = task1_bash_command,
dag = dag,
retries = 2,
email_on_failure = True,
email = 'username#domain.com')
smtp_starttls basically means Use TLS
Set this to False and set smtp_ssl to True if you want to use SSL instead. You probably need smtp_user and smtp_password for either.
Airflow will not handle 2 step authentication. However, is you are using AWS you likely don't need it as your SMTP (SES) credentials are different from your AWS credentials.
See here.
EDIT:
For airflow to send an email on failure, there are a couple things that need to be set on your task, email_on_failure and email.
See here for example:
def throw_error(**context):
raise ValueError('Intentionally throwing an error to send an email.')
t1 = PythonOperator(task_id='throw_error_and_email',
python_callable=throw_error,
provide_context=True,
email_on_failure=True,
email='your.email#whatever.com',
dag=dag)
Use below link for creating airflow dag.
How to trigger daily DAG run at midnight local time instead of midnight UTC time
Approach 1 :
You can setup SMTP locally and make it send email on jobs failure.
[email]
email_backend = airflow.utils.email.send_email_smtp
[smtp]
smtp_host = localhost
smtp_starttls = False
smtp_ssl = False
smtp_port = 25
smtp_mail_from = noreply#company.com
Approach 2 : You can use Gmail to send email.
I have written an article to do this.
https://helptechcommunity.wordpress.com/2020/04/04/airflow-email-configuration/
If we have 2-factor authentication needed to view emails, will that be an issue here for Airflow?
You can use google app password to get your way around 2 factor authentication
https://support.google.com/mail/answer/185833?hl=en-GB
Source - https://docs.aws.amazon.com/mwaa/latest/userguide/configuring-env-variables.html

AviSynth script with subtitles errors

Win7
FFmpeg version: 20170223-dcd3418 win32 shared
AVISynth version: 2.6
Calling ffmpeg in a Visual Studio 2015 C# Forms Application and using process.StartInfo.Arguments to pass arguments and read an avs script. Works fine.
The avs script:
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\VSFilter.dll")
a=ImageSource("01.png").trim(1,24)
b=ImageSource("02.png").trim(1,36)
c=ImageSource("03.png").trim(1,40)
d=ImageSource("04.png").trim(1,72)
e=ImageSource("05.png").trim(1,36)
f=ImageSource("06.png").trim(1,40)
video = a + b + c + d + e + f
return video
I'd like to add subtitles using the avs script but it is not working. Adding the subtitle argument immediately before the "return video" argument results in:
subtitle("day 111", align=2, first_frame=0, halo_color=$00FF00FF, text_color=$0000FF00, size=36, last_frame=100)
Result error: [avisynth # 003cdf20] Script error: Invalid arguments to function "subtitle"
Using video.subtitle results in:
video.subtitle("day 111", align=2, first_frame=0, halo_color=$00FF00FF, text_color=$0000FF00, size=36, last_frame=100)
No error, script completes but no subtitle on output video.
Using subtitle(clip) results in:
subtitle(video, "day 111", align=2, first_frame=0, halo_color=$00FF00FF, text_color=$0000FF00, size=36, last_frame=100)
The script exits abnormally but there is no error message.
Any guidance would be greatly appreciated. Please let me know if I can clarify anything.
Thanks, that worked.
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\VSFilter.dll")
a=ImageSource("01.png").trim(1,24)
b=ImageSource("02.png").trim(1,36)
c=ImageSource("03.png").trim(1,40)
d=ImageSource("04.png").trim(1,72)
e=ImageSource("05.png").trim(1,36)
f=ImageSource("06.png").trim(1,40)
subtitle(a + b + c + d + e + f, "day 111", align=9, first_frame=0, halo_color=$00FF00FF, text_color=$0000FF00, size=36, last_frame=100)

Resources