I making discord bot and i am trying to move from youtube_dl to yt_dlp to get +18 videos from youtube, I am getting error Output file #0 does not contain any stream.
self.YTDL_OPTIONS = {'format': 'bestaudio', 'nonplaylist': 'True', 'youtube_include_dash_manifest': False}
self.FFMPEG_OPTIONS = {
'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
'options': '-vn'
}
with YoutubeDL(self.YTDL_OPTIONS) as ydl:
try:
info = ydl.extract_info(url, download=False)
except:
return False
return {
'link': 'https://www.youtube.com/watch?v=' + url,
'thumbnail': 'https://i.ytimg.com/vi/' + url + '/hqdefault.jpg?sqp=-oaymwEcCOADEI4CSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLD5uL4xKN-IUfez6KIW_j5y70mlig',
'source': info['formats'][0]['url'],
'title': info['title']
}
self.vc[id].play(discord.FFmpegPCMAudio(
song['source'], **self.FFMPEG_OPTIONS), after=lambda e: self.play_next(interaction))
This config works with youtube_dl, but not with yt_dlp. Any ideas what i should change?
Related
I'm using the https://www.npmjs.com/package/live-stream-radio module, but a few times i get this error using it. How could i solve it? My code:
const NodeMediaServer = require('node-media-server');
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8080,
allow_origin: '*',
mediaroot: 'F:/VMediaServer/mediaroot'
},
trans: { ffmpeg: 'C:/ffmpeg/bin/ffmpeg.exe', tasks: [ { app: 'live', ac: 'aac', vc: 'libx264', hls: true, hlsFlags: '[hls_time=2:hls_list_size=3:hls_flags=delete_segments]', dash: true, dashFlags: '[f=dash:window_size=3:extra_window_size=5]' } ] }
};
var nms = new NodeMediaServer(config)
nms.run();
I'm a beginner using tornado and WebSocket. I'm trying to write a websocket demo with tornado to send and receive messages. However, when the client was connected to the server and was waiting to receiving messages from the server, a close event occurred with 1006 code which isbelow.
CloseEvent {isTrusted: true, wasClean: false, code: 1006, reason: '',
type: 'close', …} bubbles: false cancelBubble: false cancelable: false
code: 1006 composed: false currentTarget: WebSocket {url:
'ws://localhost:9998/ws', readyState: 3, bufferedAmount: 0, onopen:
null, onerror: null, …} defaultPrevented: false eventPhase: 0
isTrusted: true path: [] reason: "" returnValue: true srcElement:
WebSocket {url: 'ws://localhost:9998/ws', readyState: 3,
bufferedAmount: 0, onopen: null, onerror: null, …} target: WebSocket
{url: 'ws://localhost:9998/ws', readyState: 3, bufferedAmount: 0,
onopen: null, onerror: null, …} timeStamp: 75840 type: "close"
wasClean: false [[Prototype]]: CloseEvent
When I'm trying to debug where caused the close event, I found that the code in the
tornado/web.py
caused the close event.
When this code self.request.connection.finish() was executed ,the close event occurred. I don't know why this code can cause close event.
future = self.flush(include_footers=True)
self.request.connection.finish()
self._log()
self._finished = True
self.on_finish()
self._break_cycles()
return future
Here is my demo code, is there anything wrong with my code that cause the close event?
The sever code:
import tornado.ioloop
import tornado.web
import tornado.websocket
import time
class ConnectHandler(tornado.websocket.WebSocketHandler) :
def simple_init(self):
self.last = time.time();
self.stop = False;
def check_origin(self, origin) :
return True
def open(self) :
self.simple_init();
print("New client connecting")
self.write_message('Welcome')
print("New client connected")
def on_close(self) :
print("connection is closed")
self.loop.stop();
def on_message(self, message) :
self.write_message('new message :' + message)
class Application(tornado.web.Application) :
def __init__(self) :
handlers = [
(r'/ws', ConnectHandler)
]
tornado.web.Application.__init__(self, handlers)
if __name__ == "__main__" :
app = Application()
app.listen(8889)
tornado.ioloop.IOLoop.current().start()
The client code:
from websocket import create_connection
def short_lived_connection():
ws = create_connection("ws://localhost:9998/ws");
print("send hello server");
ws.send("hello, server");
print("sent");
print("receiving...");
result = ws.recv();
print("Received '%s'" % result);
ws.close();
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
short_lived_connection()
When I use the stream command on my bot, it streams about 1min 30s of audio before cutting off and not playing audio, and it doesn't give error messages at the start or when cutting off. When I use the download and play command instead, it plays the whole song without errors or cutoffs.
Stream command:
async def play(ctx, *, search):
voiceChannel=ctx.message.author.voice.channel
await voiceChannel.connect()
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
query_string = urllib.parse.urlencode({
'search_query': search
})
htm_content = urllib.request.urlopen(
'http://www.youtube.com/results?' + query_string
)
search_results = re.findall(r"watch\?v=(\S{11})", htm_content.read().decode())
url = 'http://www.youtube.com/watch?v=' + search_results[0]
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
song_info = ydl.extract_info(url, download=False)
voice.play(discord.FFmpegPCMAudio(song_info["formats"][0]["url"]))
Download command:
async def download(ctx, *, search):
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=ctx.message.author.voice.channel
await voiceChannel.connect()
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
query_string = urllib.parse.urlencode({
'search_query': search
})
htm_content = urllib.request.urlopen(
'http://www.youtube.com/results?' + query_string
)
search_results = re.findall(r"watch\?v=(\S{11})", htm_content.read().decode())
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download(['http://www.youtube.com/watch?v=' + search_results[0]])
for file in os.listdir("./"):
if file.endswith(".mp3"):
os.rename(file, "song.mp3")
voice.play(discord.FFmpegPCMAudio("song.mp3"))
Alright, so I found the answer here on stackoverflow dot com at When playing audio, the last part is cut off. How can this be fixed? (discord.py). I quote, "This is a known issue when you try to make a bot which doesn't download the song it's playing. It is explained here : https://support.discord.com/hc/en-us/articles/360035010351--Known-Issue-Music-Bots-Not-Playing-Music-From-Certain-Sources"
Turns out you just needed to give FFMPEG options to reconnect and play the song as shown in the code below
FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
#client.command(
name='play',
description='Streams audio from Youtube. Syntax: w!play [keyword(s)].')
async def play(ctx, *, search):
voiceChannel=ctx.message.author.voice.channel
await voiceChannel.connect()
voice = discord.utils.get(client.voice_clients, guild=ctx.guild)
query_string = urllib.parse.urlencode({
'search_query': search
})
htm_content = urllib.request.urlopen(
'http://www.youtube.com/results?' + query_string
)
search_results = re.findall(r"watch\?v=(\S{11})", htm_content.read().decode())
url = 'http://www.youtube.com/watch?v=' + search_results[0]
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
song_info = ydl.extract_info(url, download=False)
voice.play(discord.FFmpegPCMAudio(song_info["formats"][0]["url"], **FFMPEG_OPTIONS))
For whatever reason, some
I'm coding my first music bot for discord and successfully tested it on the localhost. After that, I moved it on Heroku and installed FFmpeg buildpack for it. But for some reason, it doesn't work.
Here is proof that I installed FFmpeg buildpack on Heroku: Screen
Here is my code (that works well on localhost):
youtube_dl.utils.bug_reports_message = lambda: ''
ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(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'
}
ffmpeg_options = {
'options': '-vn'
}
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
self.title = data.get('title')
self.url = data.get('url')
#classmethod
async def from_url(cls, url, *, loop=None, stream=False):
loop = loop or asyncio.get_event_loop()
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))
if 'entries' in data:
data = data['entries'][0]
filename = data['url'] if stream else ytdl.prepare_filename(data)
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
#client.command()
async def join(ctx):
channel = ctx.message.author.voice.channel
if ctx.voice_client is not None:
return await ctx.voice_client.move_to(channel)
await channel.connect()
#client.command()
async def play(ctx, *, URL):
async with ctx.typing():
player = await YTDLSource.from_url(url)
ctx.voice_client.play(player, after=lambda e: print('Player error: %s' % e) if e else None)
await ctx.send('Now playing: {}'.format(player.title))
My best guess is that I have a promise issue in my code, but I guess it could be a ssh2-sftp-client issue in my code too.
I have written this 10 different ways. Think of this as Proof of Concept code and not the writings of a 12 year old. I dumbed it way down in this last iteration.
Batch job.
*Grabs files from S3
*Goes one by one (in this iteration at least I do) and SFTPs them to a vendor
*Deletes the file in S3
If I leave off the callback, I time out at 10 seconds but everything works. The files are moved up in less than 4 seconds. If I put a callback in, only the first two are processed. My outputs say the third file was processed, but it was not.
function processSingleFile(obj, fn, context)
{
return new Promise(async function(resolve, reject)
{
//process.nextTick(async function () {
try{
console.log(obj);
let pathVariables = obj.Key.split('/');
let filename = pathVariables[2];
let srcKeyString = pathVariables[1];
console.log("Beginning to process: " + filename);
/*
let buffer = s3.getObject({
Bucket: bucket_name,
Key: obj.Key
}).createReadStream();
*/
let buffer = await getS3File(bucket_name, obj.Key);
console.log("Got file info " + obj.Key );
let Client = require('ssh2-sftp-client');
let sftp = new Client();
let remoteFilePath = '/Import/30Automations/' + filename;
sftp.connect({
host: hostTargetName,
port: '22',
username: userName,
password: password
}).then(() => {
sftp.put(buffer, remoteFilePath);
}).then(() => {
sftp.end;
sftp.close;
//sftp.end(); //nothing works when I use this
}).then(() => {
Client.end; //not needed
}).then(() => {
deleteEncryptedlFile(obj.Key); //this part of code not shown
}).then(() => {
console.log("Successfully processed: " + filename);
resolve();
}).catch(err => {
console.error("ALERT in transfer for " + filename + ": " + err.message);
resolve();
});
}catch(err){
console.log("ALERT: processing single file: " + obj + "err: " + err);
resolve();
}
});
}
exports.handler = function(event, context, callback) {
context.callbackWaitsForEmptyEventLoop = false;
async function moveFiles(){
try{
var params = {
Bucket: bucketname,
Delimiter: '',
Prefix: 'outgoing'
}
let index = 0;
s3.listObjects(params, async function (err, data) {
if(err)throw err;
let rows = data.Contents.length;
while (index < rows){
var reply = await processSingleFile(data.Contents[index]);
index++;
if (index === rows){
console.log("JOB COMPLETED");
callback(null, JSON.stringify("success")); //if I comment out, all files are moved successfully but I time out.
}
}
});
}catch(err){
console.error("ALERT Error processing job. See logs " + err.message);
callback(JSON.stringify("Error"), null);
}
}
moveFiles();
};
Here is the output
2020-01-17T01:04:44.790Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO Beginning to process: 20200115_Ta11_file3.txt.pgp
2020-01-17T01:04:44.923Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO Got file info outgoing/professional/20200115_Ta11_file3.txt.pgp
2020-01-17T01:04:46.015Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO file deleted outgoing/professional/20200115_Ta11_file3.txt.pgp
2020-01-17T01:04:46.018Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO Successfully processed: 20200115_Ta11_file3.txt.pgp
2020-01-17T01:04:46.019Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO Beginning to process: 20200116_Ta11_file1.txt.pgp
2020-01-17T01:04:46.179Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO Got file info outgoing/professional/20200116_Ta11_file1.txt.pgp
2020-01-17T01:04:47.091Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO file deleted outgoing/professional/20200116_Ta11_file1.txt.pgp
2020-01-17T01:04:47.093Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO Successfully processed: 20200116_Ta11_file1.txt.pgp
2020-01-17T01:04:47.093Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO Beginning to process: 20200116_Ta11_file2.txt.pgp
2020-01-17T01:04:47.252Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO Got file info outgoing/professional/20200116_Ta11_file2.txt.pgp
2020-01-17T01:04:48.197Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO file deleted outgoing/professional/20200116_Ta11_file2.txt.pgp
2020-01-17T01:04:48.199Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO Successfully processed: 20200116_Ta11_file2.txt.pgp
2020-01-17T01:04:48.199Z 6630b8b7-764d-4940-87f8-d6ada6b6eb84 INFO JOB COMPLETED
END RequestId: 6630b8b7-764d-4940-87f8-d6ada6b6eb84
REPORT RequestId: 6630b8b7-764d-4940-87f8-d6ada6b6eb84 Duration: 3775.81 ms Billed Duration: 3800 ms Memory Size: 1536 MB Max Memory Used: 105 MB Init Duration: 541.10 ms
I left out the returns in the section below. The returns are there now.
sftp.connect({
host: hostTargetName,
port: '22',
username: userName,
password: password
}).then(() => {
return sftp.put(buffer, remoteFilePath);
}).then(() => {
return sftp.end();
}).then(() => {
return deleteEncryptedlFile(obj.Key); //this part of code not shown
}).then(() => {
console.log("Successfully processed: " + filename);
resolve();
}).catch(err => {
console.error("ALERT in transfer for " + filename + ": " + err.message);
resolve();
});