nodeJS - Unhandled rejection RequestError: Error: socket hang up - javascript

I have this code that is working fine for the first part. I'm tryng to send a video to the user after it select what video want to see. The problem is that I'm unable to achive it because I get always this error Unhandled rejection RequestError: Error: socket hang up.
#!/usr/bin/env node
const TelegramBot = require('node-telegram-bot-api');
const TorrentSearchApi = require('torrent-search-api');
const TorrentStream = require('torrent-stream');
const bot = new TelegramBot('5xxxx', {polling: true});
const providers = TorrentSearchApi.getProviders();
//console.log(providers);
TorrentSearchApi.enablePublicProviders();
let magnetLinks = []
let response = 'Here are your search results: \n';
let engine;
let stream;
// Matches "/echo [whatever]"
bot.onText(/\/search (.+)/, async (msg, match) => {
// 'msg' is the received Message from Telegram
// 'match' is the result of executing the regexp above on the text content
// of the message
console.log(match[1]);
TorrentSearchApi.search(match[1], 'All', 10).then( (results) => {
results.forEach( (item, index) => {
if( item.seeds > 1 ){
response += `${index}) ${item.title}\n`;
magnetLinks.push(item.magnet);
}
});
bot.sendMessage(msg.chat.id, response).then( (message) => {
bot.sendMessage(msg.chat.id, 'Use the /stream command followed by the number of the torrent file you want to play');
});
});
});
bot.onText(/\/stream (.+)/, async (msg, match) => {
console.log(magnetLinks[match[1]]);
engine = TorrentStream(magnetLinks[match[1]]);
engine.on('ready', () => {
engine.files.forEach( (file) => {
console.log('filename:', file.name);
stream = file.createReadStream();
console.log(stream);
// stream is readable stream to containing the file content
bot.sendVideo(msg.chat.id, stream);
});
});
});
How I can solve the problem and let the telegram bot send the video file to the user?Is possible to stream a video file with a telegram bot?

Related

UnhandledPromiseRejectionWarning: Error: Evaluation failed: u when using Whatsapp-web.js in Node.js

I'm trying to use Whatsapp-web.js to programmatically send messages in a Node.js environment. i am trying to send a sound file that got from api. this is the code for requests to api
const fakeVoiceTextToSpeech = async (text, person, pathVoice) => {
const result = {
'status': false,
'message': '',
}
//https://tts-fake-voice-api.qadrillahstorag.repl.co/speak?text=halo&person=1
return await axios.get(`https://tts-fake-voice-api.qadrillahstorag.repl.co/speak?text=${text}&person=${person}`, {
responseType: 'stream'
}).then(async (response) => {
await new Promise((resolve, reject) => {
response.data.pipe(fs.createWriteStream(`${pathVoice}.mp3`))
response.data.on('end', resolve)
response.data.on('error', reject)
})
result.status = true
return result
}).catch((error) => {
result.message = error.message
return result
})
}
the .mp3 file was successfully saved. but when sending it to the user I get an error like this
(node:9501) UnhandledPromiseRejectionWarning: Error: Evaluation failed: u
at ExecutionContext._evaluateInternal (/home/runner/Whatsapp-Bot/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:221:19)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async ExecutionContext.evaluate (/home/runner/Whatsapp-Bot/node_modules/puppeteer/lib/cjs/puppeteer/common/ExecutionContext.js:110:16)
at async Client.sendMessage (/home/runner/Whatsapp-Bot/node_modules/whatsapp-web.js/src/Client.js:686:28)
this is the code to send the .mp3 file
const fakeVoiceTextToSpeechHandler = async (text, client, msg, MessageMedia) => {
const pathVoice = msg.from
const command = splitCommandWithParam(text)
const response = await fakeVoiceTextToSpeech(command.prompt, command.param, pathVoice)
if (!response.status) {
return client.sendMessage(msg.from, response.message)
}
setTimeout(() => {
try {
const media = MessageMedia.fromFilePath(`${pathVoice}.mp3`)
console.log(media)
client.sendMessage(msg.from, media, { sendAudioAsVoice: true } )
} catch (error) {
client.sendMessage(msg.from, "gagal mengubah teks jadi suara 😢")
client.sendMessage(msg.from, "silahkan coba lagi ✨")
console.log(error)
throw error
} finally {
fs.unlinkSync(`${pathVoice}.mp3`)
}
}, 5000)
}
I have tried to provide a delay before the .mp3 file is converted to base64. and when I print the media variable the value matches i.e. it is successfully read. but when sent it always fails. but for the user who gives the command, the message is marked with two blue ticks (readable message)
this is the code that triggers the command
...
if (text.includes("#fakespeech")){
console.log(`${ msg.from } fake text to speech`)
await fakeVoiceTextToSpeechHandler(text, client, msg, MessageMedia)
}

integrate node-telegram-bot-api with nlp.js QnA

I'm creating a telegram bot. I want to integrate nlp.js to have a QnA.
At the moment I have this code:
#!/usr/bin/env node
const TelegramBot = require('node-telegram-bot-api');
const process = require('process');
const path = require('path');
const { dockStart } = require('#nlpjs/basic');
const axios = require('axios').default;
//const qnaFile = path.dirname()
let chatId;
let currentUser;
let incomingMessage;
let response;
let dock;
let nlp;
// replace the value below with the Telegram token you receive from #BotFather
const token = process.env.TELEGRAM_BOT_TOKEN || '5252802474:AA';
// Create a bot that uses 'polling' to fetch new updates
const bot = new TelegramBot(token, {polling: true});
bot.onText(/\/echo(.+)/, async (msg, match) => {
// 'msg' is the received Message from Telegram
// 'match' is the result of executing the regexp above on the text content
// of the message
//const chatId = msg.chat.id;
console.log(`CONSOLE LOG onText: \n ${match, msg}`);
});
bot.on('message', async (msg) => {
chatId = msg.chat.id;
currentUser = msg.from.first_name;
incomingMessage = msg.text;
dock = await dockStart();
const nlp = await dock.get('nlp');
await nlp.train();
response = await nlp.process('en', incomingMessage);
// Listen for any kind of message. There are different kinds of messages.
console.log(response);
console.log(msg);
// send a message to the chat acknowledging receipt of their message
await bot.sendMessage(chatId, `${response.answer}`);
});
How I can add new intents and utterances by using the user input incoming messages? From the documentation of the libary I don't see any reference about dynamically updating the corpus file?

ffmpeg error when generating screenshots from videos in Node js

I have a function that is supposed to generate a thumbnail from a mp4 file with fluent-ffmpeg in Node, and store it as a jpg file.
In my first function I tried to solve this by creating a stream of the external url:
const got = require('got');
const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');
const fs = require('fs');
function generateThumbnail() {
const url = 'https://gateway.pinata.cloud/ipfs/QmUWD7dewFZB9bFamyvR5uEUpX1FEkjuoZYzhUZBm8U4mT/nft.mp4'
const request = await got.stream(url);
function asyncThumbnail() {
return new Promise((resolve, reject) => {
ffmpeg(request)
.setFfmpegPath(ffmpeg_static)
.screenshots({
size: '?x512',
count: 1,
timemarks: ['3'],
filename: `filename.jpg`,
folder: __dirname + '/../ffmpeg/output',
})
.on('end', function () {
resolve();
console.log('Thumbnail created');
})
.on('error', (err) => {
return reject(new Error(err));
});
});
}
}
A thumbnail is generated for a lot of videos I have tested, but not for this video (the video loads a bit slow because it's hosted on IPFS, but it doesn't have anything to do with my error), which returns the following error:
ffmpeg exited with code 1: pipe:0: Invalid data found when processing input
Cannot determine format of input stream 0:0 after EOF
After reading that ffmpeg is supposed to work better if I download a video locally before converting it (link), I changed my code to do that:
const got = require('got');
const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');
const fs = require('fs');
function generateThumbnail() {
const url = 'https://gateway.pinata.cloud/ipfs/QmUWD7dewFZB9bFamyvR5uEUpX1FEkjuoZYzhUZBm8U4mT/nft.mp4'
const request = await got.stream(url);
await request.pipe(
fs.createWriteStream(
__dirname + `/../ffmpeg/input/fileName.mp4`
)
);
function asyncThumbnail() {
return new Promise((resolve, reject) => {
ffmpeg(__dirname + `/../ffmpeg/input/filename.mp4`)
.setFfmpegPath(ffmpeg_static)
.screenshots({
size: '?x512',
count: 1,
timemarks: ['3'],
filename: `filename.jpg`,
folder: __dirname + '/../ffmpeg/output',
})
.on('end', function () {
resolve();
console.log('Thumbnail created');
})
.on('error', (err) => {
return reject(new Error(err));
});
});
}
await asyncThumbnail();
}
This gives me a similar error, but for every video I have tested, without generating a single thumbnail:
ffmpeg exited with code 1: C:\path\src/../ffmpeg/input/baroque-fndnft-945.mp4: Invalid data found when processing input
Running the last function with fs.createReadStream() as the ffmpeg() input istead gives me this error:
ffmpeg exited with code 1: pipe:0: Invalid data found when processing input

How do I playback .m4s files. And turn them into a binary stream for a Discord Bot

I want to download the BBC radio 2 and stream it to a discord server. Each request is https://as-dash-uk-live.akamaized.net/pool_904/live/uk/bbc_radio_two/bbc_radio_two.isml/dash/bbc_radio_two-audio=320000-250636302.m4s However the Time stamp will change and they regularly delete content. I found a .dash file as well https://as-dash-uk-live.akamaized.net/pool_904/live/uk/bbc_radio_two/bbc_radio_two.isml/dash/bbc_radio_two-audio=320000.dash which is seems to request. However I can't find how to send it through a discord bot to a discord server. My code is
const axios = require('axios')
module.exports = {
play: async function (guild,message) {
const serverQueue = {};
const voiceChannel = message.member.voice.channel
serverQueue.connection = await voiceChannel.join();
plays(guild)
async function plays(guild) {
let data1 = new Date(1353439725);
let data2 = new Date(Date.now()/1000);
console.log(`https://as-dash-uk-live.akamaized.net/pool_904/live/uk/bbc_radio_two/bbc_radio_two.isml/dash/bbc_radio_two-audio=320000-${Math.floor((data2 - data1))-4000}.m4s`)
const dispatcher = serverQueue.connection.play((await axios.get(`https://as-dash-uk-live.akamaized.net/pool_904/live/uk/bbc_radio_two/bbc_radio_two.isml/dash/bbc_radio_two-audio=320000-${Math.floor((data2 - data1))-4000}.m4s`)).data)
.on('finish', () => {
console.log('Music ended!');
plays(guild);
return
})
.on('error', error => {
console.error(error);
plays(guild);
return
});
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
}
}
}
However no audio plays and the audio end event is always being called. Am I being really stupid or is there a way to do this.

Streaming ffmpeg output directly to dispatcher

I'm trying to play music with my discord bot and I want to use ffmpeg to specify the start of the music, which works perfectly fine, but I can only download the music with ffmpeg and then play it. I want ffmpeg to process it and then also stream it to play the music.
Here is the code I use to download and then play the music:
message.member.voiceChannel.join().then((con, err) => {
ytPlay.search_video(op, (id) => {
let stream = ytdl("https://www.youtube.com/watch?v=" + id, {
filter: "audioonly"
});
let audio = fs.createWriteStream('opStream.divx');
proc = new ffmpeg({
source: stream
})
proc.withAudioCodec('libmp3lame')
.toFormat('mp3')
.seekInput(35)
.output(audio)
.run();
proc.on('end', function() {
let input = fs.createReadStream('opStream.divx');
console.log('finished');
guild.queue.push(id);
guild.isPlaying = true;
guild.dispatcher = con.playStream(input);
});
});
})
Is it possible to do what I want and if yes how?
Instead of using ffmpeg to specify your starting point of the music you could use the seek StreamOptions of discord.js like:
const dispatcher = connection.play(ytdl(YOUR_URL, { filter: 'audioonly' }) , {seek:35})
This worked pretty fine for me
Yes is is possible, i made it in my bot.
First of all you need to install ytdl-core
Then create a play.js file where the stream function will be in.
This code will: take the youtube url and stream it without downloading the song, add the song to a queue, make the bot leave when the song is finished
Edit the code for what you need.
exports.run = async (client, message, args, ops) => {
if (!message.member.voiceChannel) return message.channel.send('You are not connected to a voice channel!');
if (!args[0]) return message.channel.send('Insert a URL!');
let validate = await ytdl.validateURL(args[0]);
let info = await ytdl.getInfo(args[0]);
let data = ops.active.get(message.guild.id) || {};
if (!data.connection) data.connection = await message.member.voiceChannel.join();
if(!data.queue) data.queue = [];
data.guildID = message.guild.id;
data.queue.push({
songTitle: info.title,
requester: message.author.tag,
url: args[0],
announceChannel: message.channel.id
});
if (!data.dispatcher) play(client, ops, data);
else {
message.channel.send(`Added to queue: ${info.title} | requested by: ${message.author.tag}`)
}
ops.active.set(message.guild.id, data);
}
async function play(client, ops, data) {
client.channels.get(data.queue[0].announceChannel).send(`Now Playing: ${data.queue[0].songTitle} | Requested by: ${data.queue[0].requester}`);
client.user.setActivity(`${data.queue[0].songTitle}`, {type: "LISTENING"});
data.dispatcher = await data.connection.playStream(ytdl(data.queue[0].url, {filter: 'audioonly'}));
data.dispatcher.guildID = data.guildID;
data.dispatcher.once('end', function() {
end(client, ops, this);
});
}
function end(client, ops, dispatcher){
let fetched = ops.active.get(dispatcher.guildID);
fetched.queue.shift();
if (fetched.queue.length > 0) {
ops.active.set(dispatcher.guildID, fetched);
play(client, ops, fetched);
} else {
ops.active.delete(dispatcher.guildID);
let vc = client.guilds.get(dispatcher.guildID).me.voiceChannel;
if (vc) vc.leave();
}
}
module.exports.help = {
name:"play"
}```

Categories