Something with my queue is just not working, when I try to add a song to queue it's just skipping the current song - queue

I followed an old video that shows how to create music bot, I fixed most problems, but the part of the queue I couldn't fix.
switch (args[0]) {
case 'play':
function play(connection, message) {
var server = servers[message.guild.id];
server.dispatcher = connection.play(ytdl(server.queue[0], { filter: "audio" }));
message.reply("have a good listening sir!")
server.queue.shift();
server.dispatcher.on("end", function () {
if (server.queue[0]){
play(connection, message);
} else {
connection.disconnect();
}
});
}
if (!args[1]) {
message.channel.send("you need to provide a link! sir");
return;
}
if (!message.member.voice.channel) {
message.channel.send("you must be in a channel to play the bot sir!);
return;
}
if (!servers[message.guild.id]) servers[message.guild.id] = {
queue: []
}
var server = servers[message.guild.id];
server.queue.push(args[1]);
if (!message.guild.voiceConnection) message.member.voice.channel.join().then(function(connection) {
play(connection, message);
})
break;
case 'skip':
var server = servers[message.guild.id];
if (server.dispatcher) server.dispatcher.end();
message.channel.send("Skipping the song sir!")
break;
case 'leave':
var server = servers[message.guild.id];
if (message.guild.voiceConnection) {
}
server.dispatcher.end();
message.channel.send('leaving the voice channel sir have a great day! :wave_tone1: ')
console.log('stopped the queue')
}
if (message.guild.connection)message.guild.voiceConnection.disconnect();
There are no errors it is just skipping to the next song, I would appreciate the help. I have tried anything and nothing works.
Sorry if my code is bad I am new to coding.
Note:I am using ytdl-core

Related

Mute video stream from ApiRTC in Ionic 5

I am looking for ways to do Audio call only in ApiRTC but cannot seem to do it right as the streams keep on appearing. Hoping someone could assist. Thanks in advance. Below is my code
startVoiceCall() {
//apiRTC.setLogLevel(10);
this.ua = new apiRTC.UserAgent({
uri: "apzkey:xxxx",
});
let registerInformation = {
cloudUrl: "https://cloud.apizee.com",
};
this.ua
.register(registerInformation)
.then((session) => {
this.isDisabled = false;
console.log("User registered with session: ", session);
session
.on("contactListUpdate", (updatedContacts) => {
console.log("contactListUpdate", updatedContacts);
})
.on("incomingCall", (invitation) => {
var answerOptions = {
mediaTypeForIncomingCall : 'AUDIO'
};
invitation.accept(null, answerOptions).then((call) => {
this.currentCall = call;
this.setAudioCallListeners();
this.onCall = true;
});
});
//session.allowMultipleCalls(true);
this.connectedSession = session;
});
this.checkPermissions();
}
When subscribing to a stream, you can pass SubscribeOptions as second parameter with :
conversation.subscribeToStream(streamId, { audioOnly: true })
ApiRTC reference : https://dev.apirtc.com/reference/Conversation.html#subscribeToStream
This will make the subscriber receive audio only.

SAPUI5 how to provide Busy Indicator for POST call in for loop

I have an issue in displaying BusyIndicator for post call in for loop. Before posting this question i have explored all possible ways and didnt find any solution. Hence im posting here. Please apologize if this is silly question..
For one of the requirement, i have to call ODataModel POST call for 10 times in a for loop.
Here im able to get the results perfectly without any issue. But the problem is to fire all 10 services, it is taking nearly 20 seconds to finish execution of all services.
So i want to display BusyDialog before executing services. Below is my code..
var payload = {
"sectionIndex": 3,
"ratingType": "overall",
"userId": "",
"rating": "76",
"ratingKey": "wf_sect_3_rating"
};
//var busy = new sap.m.BusyDialog();
//busy.open();
for (var i = 0; i < 10; i++) {
//var busy = new sap.m.BusyDialog();
//busy.open();
var that = this;
oModel.create("/URL", payload, {
success: function (oData, oResponse) {
if (oData.results[0].status === "OK") {
that.getView().getModel("employeesModel").refresh(true);
} else {
MessageBox.error("Error : " + oData.results[0].message);
}
},
error: function (e) {
MessageBox.error("Error : " + e);
}
});
busy.close();
}
I also tried with sap.ui.core.BusyIndicator.show(), hide(), creating separate BusyDialog.fragment and calling explicitly in controller. But none of the ways worked.
But when i try to debug, then im not getting any issue. BusyIndicator is loading perfectly if im keeping breakpoint.
Can someone help me to load BusyDialog at the before calling POST call and close BusyDialog once the execution of services finished.
For this scenario I would recommend using Promises
var payload = {
sectionIndex: 3,
ratingType: "overall",
userId: "",
rating: "76",
ratingKey: "wf_sect_3_rating"
};
//var busy = new sap.m.BusyDialog();
//busy.open();
var aPromises = [];
// Open your busy dialog
for (var i = 0; i < 10; i++) {
//var busy = new sap.m.BusyDialog();
//busy.open();
var that = this;
var pCall = new Promise(function(resolve, reject) {
oModel.create("/URL", payload, {
success: function(oData, oResponse) {
resolve();
if (oData.results[0].status === "OK") {
that
.getView()
.getModel("employeesModel")
.refresh(true);
} else {
MessageBox.error("Error : " + oData.results[0].message);
}
},
error: function(e) {
reject();
MessageBox.error("Error : " + e);
}
});
aPromises.push(pCall);
}).bind(this);
Promise.all(aPromises).then(function() {
// Happy case
// Close your busy dialog
}, function() {
// At least one of the promises went wrong
});
//busy.close();
}
Note that once one of the Promises is rejected, it will go into the second function of Promise.all(), so maybe just use resolve()
Please use batch requests instead of single requests in loops.
var sError;
var aErrorMessages = [];
var payload = {
"sectionIndex": 3,
"ratingType": "overall",
"userId": "",
"rating": "76",
"ratingKey": "wf_sect_3_rating"
};
var busy = new sap.m.BusyDialog();
busy.open();
oModel.setUseBatch(true);
oModel.setDeferredGroups(["myBatchRequest"]);
for (var i = 0; i < 10; i++) { //Loop
oModel.create("/URL", payload, { //Create request without sending
groupId: "myBatchRequest",
changeSetId: "myChangeSet",
single: false,
success: function(oData, oResponse) { //Catch error for each request
if (oData.results[0].status !== "OK") {
aErrorMessages.push("Error : " + oData.results[0].message); //store error message for each request
}
}.bind(this),
error: function(e) {
aErrorMessages.push(e);
}
});
}
oModel.submitChanges({ //Send all requests at once
groupId: "myBatchRequest",
success: function(oResponse) {
if (aErrorMessages.length > 0) { //Are there any errors...
for (var i = 0; i < aErrorMessages.length; i++) {
sError += aErrorMessages[i]; //...put it in string
}
MessageBox.error(sError); //Show all errors
busy.close(); //Close Busy Dialog
} else {
this.getView().getModel("employeesModel").refresh(true);
}
}.bind(this),
error: function(oError) {
MessageBox.error(oError);
busy.close(); //Close Busy Dialog
}
});
You can solves it by using oData model method attachRequestCompleted. An easy way would be.
if(i == 10) {
oModel.attachRequestCompleted(function(oEvent) {
busy.close();
});
}
Of course that's not a perfect solution because it could be, that the 9th request is later finished than your 10th etc.
Normally you need to check every request and if every request is completed successfully, the busy dialog get closed. if one or more of them got an error, you can close if all 10 requests are completed you can close the busy dialog and you show an error message or sth.
so normally on every attachRequestCompleted you need to check your loop counter if it's size is 10 and if yes, you can close the dialog.

PWA Saving a photo taken without download prompt

I am trying to build a progressive web app that utilizes the device camera to take pictures but want it to save to their Photos gallery without being prompted to download like the native camera app does..Is this even possible..I haven't discovered a way yet and not much info on google about it would it be different if it was uploaded to the cloud?
Thanks
The link at https://whatwebcando.today/photos.html suggests that this may be possible.
capturer = ImageCapture(streamVideoTrack)
Creates an image capturer out of the Media Stream Video Track.
capturer.takePhoto()
Returns a Promise resolved with the photo taken with the current settings.
capturer.setOptions(photoSettings)
Configures the photoSettings for subsequent captures; if visible, the effects of the configuration can be seen in the Track used as input.
This is the example code:
function getUserMedia(options, successCallback, failureCallback) {
var api = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia;
if (api) {
return api.bind(navigator)(options, successCallback, failureCallback);
}
}
var theStream;
function getStream() {
if (!navigator.getUserMedia && !navigator.webkitGetUserMedia &&
!navigator.mozGetUserMedia && !navigator.msGetUserMedia) {
alert('User Media API not supported.');
return;
}
var constraints = {
video: true
};
getUserMedia(constraints, function (stream) {
var mediaControl = document.querySelector('video');
if ('srcObject' in mediaControl) {
mediaControl.srcObject = stream;
mediaControl.src = (window.URL || window.webkitURL).createObjectURL(stream);
} else if (navigator.mozGetUserMedia) {
mediaControl.mozSrcObject = stream;
}
theStream = stream;
}, function (err) {
alert('Error: ' + err);
});
}
function takePhoto() {
if (!('ImageCapture' in window)) {
alert('ImageCapture is not available');
return;
}
if (!theStream) {
alert('Grab the video stream first!');
return;
}
var theImageCapturer = new ImageCapture(theStream.getVideoTracks()[0]);
theImageCapturer.takePhoto()
.then(blob => {
var theImageTag = document.getElementById("imageTag");
theImageTag.src = URL.createObjectURL(blob);
})
.catch(err => alert('Error: ' + err));
}
So it seems like you can take a photo... I can't see anywhere to indicate that you can then persist this photo in the users storage though. I'd love to be wrong.

RTCMultiConnection, failing to set up and connect to rooms.

I am trying to test a real-time data connection between peers using RTCMultiConnection.
Setting up a session/room seems to work, but once it has been made, peers cannot seem to join. If I run this function again from another browser, while a session is opened, it still says the room does not exist and it opens up a new one, rather than joining in.
The channel and session id's are identical, so why does the peer not find the session?
function makeOrJoinRoom(id){
channelid = 'channel'+id;
roomid = 'room'+id;
sessionMedia = {audio: false, video: false, data: true};
var connection = new RTCMultiConnection(channelid);
connection.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/';
connection.checkPresence( roomid, function(roomExists, roomid) {
alert('checking presence...');
alert('Room exists='+roomExists);
if(roomExists) {
alert('I am a participant');
connection.join({
sessionid: roomid,
session: sessionMedia
});
} else {
alert('I am the moderator');
connection.session = sessionMedia;
connection.open({
sessionid: roomid
});
}
});
}
Please replace your function with this:
function makeOrJoinRoom(roomid) {
var connection = new RTCMultiConnection();
connection.session = {
data: true
};
connection.socketURL = 'https://rtcmulticonnection.herokuapp.com:443/';
alert('checking presence...');
connection.checkPresence(roomid, function(roomExist, roomid) {
alert('Room exists=' + roomExist);
if (roomExist === true) {
alert('I am a participant');
connection.join(roomid);
} else {
alert('I am the moderator');
connection.open(roomid);
}
});
connection.onopen = function(event) {
alert('WebRTC chat opened!');
};
}
// call above function like this
makeOrJoinRoom('your-unique-room-id');

Video.js player add chromecast button?

I have tried numerous ways of adding a cast button to video.js player but cannot do this for the life of me. Can anyone help?
I'm using the hellovideo cms for videos and need plugins added but have no idea about jquery etc.. so please if anyone can help?
There is a really nice plugin for this: https://github.com/kim-company/videojs-chromecast
Just follow the setup instructions (adding the js and css to your page).
I tried kim-company/videojs-chromecast. It only works with an older version of videojs, I used 5.4.6. It's quite buggy. Another I tried was benjipott/video.js-chromecast, which claims to work with newer videojs, but I didn't like it at all. So I gave up on videojs, I always found the native HTML5 video player more reliable and easier to work with (videojs just wraps this anyway). For the chromecast stuff, I provide a nearby button that links to chromecast.link, where I wrote a full web chromecast sender app. Pass the video and poster URL in the fragment, per this example:
https://chromecast.link/#content=http://host/some.mp4,poster=http://host/poster.jpg,subtitles=http://host/webvtt.srt
I recently answered this question, you can check it out here: How to implement chromecast support for html5 player for more information
var session = null;
$( document ).ready(function(){
var loadCastInterval = setInterval(function(){
if (chrome.cast.isAvailable) {
console.log('Cast has loaded.');
clearInterval(loadCastInterval);
initializeCastApi();
} else {
console.log('Unavailable');
}
}, 1000);
});
function initializeCastApi() {
var applicationID = chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;
var sessionRequest = new chrome.cast.SessionRequest(applicationID);
var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
sessionListener,
receiverListener);
chrome.cast.initialize(apiConfig, onInitSuccess, onInitError);
};
function sessionListener(e) {
session = e;
console.log('New session');
if (session.media.length != 0) {
console.log('Found ' + session.media.length + ' sessions.');
}
}
function receiverListener(e) {
if( e === 'available' ) {
console.log("Chromecast was found on the network.");
}
else {
console.log("There are no Chromecasts available.");
}
}
function onInitSuccess() {
console.log("Initialization succeeded");
}
function onInitError() {
console.log("Initialization failed");
}
$('#castme').click(function(){
launchApp();
});
function launchApp() {
console.log("Launching the Chromecast App...");
chrome.cast.requestSession(onRequestSessionSuccess, onLaunchError);
}
function onRequestSessionSuccess(e) {
console.log("Successfully created session: " + e.sessionId);
session = e;
}
function onLaunchError() {
console.log("Error connecting to the Chromecast.");
}
function onRequestSessionSuccess(e) {
console.log("Successfully created session: " + e.sessionId);
session = e;
loadMedia();
}
function loadMedia() {
if (!session) {
console.log("No session.");
return;
}
var videoSrc = document.getElementById("myVideo").src;
var mediaInfo = new chrome.cast.media.MediaInfo(videoSrc);
mediaInfo.contentType = 'video/mp4';
var request = new chrome.cast.media.LoadRequest(mediaInfo);
request.autoplay = true;
session.loadMedia(request, onLoadSuccess, onLoadError);
}
function onLoadSuccess() {
console.log('Successfully loaded video.');
}
function onLoadError() {
console.log('Failed to load video.');
}
$('#stop').click(function(){
stopApp();
});
function stopApp() {
session.stop(onStopAppSuccess, onStopAppError);
}
function onStopAppSuccess() {
console.log('Successfully stopped app.');
}
function onStopAppError() {
console.log('Error stopping app.');
}