GStreamer: activate/deactivate a specific tee src at runtime - c

I have the following pipeline (important to leave it as descriptor and not build at runtime):
videotestsrc ! tee name=t t. ! queue ! ... t. ! queue ! ...
I need a simple way (which is also correct architecturally) of "deactivating" the second tee src before changing the pipeline's state to PLAYING, and then at some point "activate" it and "deactivate" it on demand. I'm not sure if activating/deactivating should be accomplished by actually linking/unlinking or by setting some pad's property/state.
Thanks!

Yes, this can be done. In JS, this looks like this:
Adding a client:
const pipelineSegment = Gst.parseBinFromDescription('queue name=q ! fakesink', false);
pipelineSegment.name = `subpipe_${someId}`;
setPipelineState(pipelineSegment, 'PAUSED');
globalPipeline.add(pipelineSegment);
const tee = globalPipeline.getByName('tee');
const q = pipelineSegment.getByName(`q`);
tee.link(q);
setPipelineState(globalPipeline, 'PLAYING');
Removing it:
globalPipeline.remove( pipelineSegment );
setPipelineState(pipelineSegment, 'NULL');
With this helper function:
/** Set gst pipeline's state to the given Gst.State name, e.g., PAUSED */
const setPipelineState = (pipeline, stateName) => {
const state = Gst.State[stateName];
if (state === undefined) {
log.error("No such state", state);
return;
}
const result = pipeline.setState(state);
if (result == Gst.StateChangeReturn.Failure) {
log.error("Failed to set pipeline's state to", stateName);
} else {
log.debug('pipeline set to', stateName);
}
};
This is the example (in C++) I followed:
https://tewarid.github.io/2011/06/06/gstreamer-pipeline-with-tee.html

Related

Volume command in discord.js

Ive made the command and it works but it doesn't change the volume of the bot it keeps saying "Volume only can be set in a range of `1` - `100`"
but i typed "volume 1 and it didnt work
Command -
} else if (message.content.startsWith('"volume')) {
const args = message.content
if (!message.member.voice.channel) return message.channel.send("I'm sorry, but you need to be in a voice channel to set a volume!");
if (!serverQueue) return message.channel.send("There is nothing playing");
if (!args[1]) return message.channel.send(`The current volume is: **\`${!serverQueue.volume}%\`**`);
if (isNaN(args[1]) || args[1] > 100) return message.channel.send("Volume only can be set in a range of **\`1\`** - **\`100\`**");
serverQueue.volume = args[1];
serverQueue.connection.dispatcher.setVolume(args[1] / 100);
return message.channel.send(`I set the volume to: **\`${args[1]}%\`**`);
return;
Functions -
const dispatcher = serverQueue.connection
.play(ytdl(song.url))
.on("finish", () => {
if (!serverQueue.loop) serverQueue.songs.shift()
play(guild, serverQueue.songs[0]);
})
.on("error", error => console.error(error));
dispatcher.setVolumeLogarithmic(serverQueue.volume / 5);
serverQueue.textChannel.send(`Started playing: **${song.title}**`)
Isn't it because you are missing .split() when you are assigning to args?
const args = message.content.split(" ");
It will break the message content by spaces into an array. Your commands would look like this "volume 5.

Discord.js how to use bot mention and a set prefix as prefixes

I want to make it so that if I do [prefix] [command] it will give the same effect as [mention bot] [command] but the way I create commands and args makes that difficult:
The prefix is stored as var prefix = '!3';
And this is how I create commands:
bot.on('message', msg => {
if (!msg.content.startsWith(prefix) || msg.author.bot)
return;
//the first message after '!13 '
//!
let args = msg.content.toLowerCase().substring(prefix.length).split(" ");
//^
//any capitalisation is allowed (ping,Ping,pIng etc.)
switch(args[1]) {
case 'ping': //if user inputs '!3 ping'
msg.channel.send('Pong!') //send a message to the channel 'Pong!'
}//switch (command) ends here
};//event listener ends here
You can have a list of predefined prefixes and loop over that to determine if the msg has a prefix from that list.
let prefixList = ['!31 ', '!asdf ', `<#${bot.user.id}> `, `<#!${bot.user.id}> `]
function hasPrefix(str) {
for(let pre of prefixList)
if(str.startsWith(pre))
return true;
return false;
}
<#${bot.user.id}> , <#!${bot.user.id}> will set up bot mention as a prefix.
Here's the shorter version of secretlyrice's answer:
const startsWithPrefix = (command) =>
['!prefix1 ', '!prefix2', <#botId>, <#!botId>].some(p => command.startsWith(p))
Nice code, but change it 1 to 0
switch(args[0]) {
case 'ping': //if user inputs '!3 ping'
msg.channel.send('Pong!') //send a message to the channel 'Pong!'
}
I assume you are running on an older version of Discord.js cause if you are using v13 message is depricated and should be messageCreate but this is what I used when I wasn't using slash commands.
const escapeRegex = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
const prefix = '!'
bot.on('message', async msg => {
const prefixRegex = new RegExp(`^(<#!?${bot.user.id}>|${escapeRegex(prefix)})\\s*`)
if (!prefixRegex.test(message.content)) return
// checks for bot mention or prefix
const [, matchedPrefix] = message.content.match(prefixRegex)
const args = message.content.slice(matchedPrefix.length).trim().split(/ +/)
// removes prefix or bot mention
const command = args.shift().toLowerCase()
// gets command from next arg
if (command === 'ping') {
msg.channel.send('Pong!')
}
})

client.commands.has() not working with normal input

To get the files with commands (such as ping.js)
module.exports = {
name: 'ping',
description: 'Play some ping pong.',
execute(message, args) {
const bot = require('../bot.js');
message.channel.send('pong!');
bot.log(message, '$ping', message.guild.name);
},
};
I use this in bot.js
const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
for(const file of commandFiles){
const command_file = require(`./commands/${file}`);
client.commands.set(command_file.name, command_file);
}
I'm trying to set the variable for the command with this:
let command = '';
if(message.content.includes(' ')){
command = message.content.substr(1, message.content.indexOf(' ')).toLowerCase();
} else {
command = message.content.substr(1).toLowerCase();
}
which returns the name of the command as a string, like 'info' or 'ping'.
But, when I put that variable into client.commands.has() it doesnt find the command and returns back with this:
if(!client.commands.has(command)) return;
I cant find any answers to this online so I figured I'd ask, sorry if this doesnt fit
Try this instead:
const cmd =
message.client.commands.get(command) ||
message.client.commands.find(
(cmd) => cmd.aliases && cmd.aliases.includes(command) // if you're also using aliases
);
if (!command) return;

How to make this bot listen to argument after prefix and answer?

so i'm trying this 8ball bot, and everything is working fine, but i can't get how can i leave in the condition that only when the bot get "!verda arg1 arg2" it answers one of the replies in the array.
meanwhile my condition is if the user type the prefix "!verda" only, it replies , i want to include the argument too in the condition
const Discord = require("discord.js");
const client = new Discord.Client();
const cfg = require("./config.json");
const prefix = cfg.prefix;
client.on("message", msg => {
if (!msg.content.startsWith(prefix) || msg.author.bot) return;
const args = msg.content.slice(prefix.length).split(/ +/);
const command = args.shift().toLowerCase;
if (msg.content === prefix){
let replies = [
"Yes.",
"No.",
"I don't know.",
"Maybe."
];
let result = Math.floor((Math.random() * replies.length));
msg.channel.send(replies[result]);
}
else if (msg.content === "!help"){
msg.channel.send("I have only 1 command [!verda]");
}
})
client.login(cfg.token);
const command = args.shift().toLowerCase;
toLowerCase is a function and therefore should be
const command = args.shift().toLowerCase();
By doing msg.content === prefix, you are checking if the whole content of the message is equal to that of cfg.prefix
if(msg.content.startsWith(`${prefix}8ball`) {
}
The answer was simple as i figured it out, i simply had to join the spaces
if (msg.content === `${prefix} ${args.join(" ")}`)

How to change the commas to space?

So I created a poll command, but when I type in the command, there are commas between each word.
exports.run = async (bot, message, args) => {
let text = message.content.slice('__poll'.length);
if (!args) return message.reply("You must have something to vote for!")
message.channel.send(`:ballot_box: ${message.author.username} started a poll! React to my next message to vote on it. :ballot_box: `);
const pollTopic = await message.channel.send(`${args}`);
pollTopic.react(`✅`);
pollTopic.react(`⛔`);
};
when I want the question to be What is up, this happens
what,is,up!
By default, when translating an array into a string, JavaScript will separate each element by a comma. To change the delimiter, you can use Array.join().
Example:
const arr = ['How', 'are', 'you?'];
console.log(`Original: ${arr}`);
const str = arr.join(' ');
console.log(`Joined: ${str}`);

Resources