I am creating an HTML emailer for my client and they want one link for two buttons. when their users do not have their apps installed on their phones, they must be redirected to the default URL. I am not too bright in Javascript / jQuery because I am not able to find answers.
If users have installed their applications on their mobile devices so in this scenario we need the HREF attribute to be changed as per the Android / iOS devices and the application installed on their device if the application is not installed the user will be sent to the default URL.
I tried this method for the execution
<script language=javascript>
<!-- for button 1 -->
var windowsize = $(window).width();
$(document).resize(function () {
$(window).resize(function () {
var windowsize = $(window).width();
});
})
const getHref = () => {
const element = document.getElementById("link-change");
const IS_IPAD = navigator.userAgent.match(/iPad/i) != null;
const IS_IPHONE = (navigator.userAgent.match(/iPhone/i) != null) || (navigator.userAgent.match(/iPod/i) != null);
if (IS_IPAD || IS_IPHONE) {
element.href = "ios.com"; //
}
else {
element.href = "default.com"; // default
if (windowsize < 768) {
element.href = "android.com"; // default
}
else {
element.href = "default.com"; // default
}
};
};
getHref();
const getHref2 = () => {
const element = document.getElementById("link-change-first");
const IS_IPAD = navigator.userAgent.match(/iPad/i) != null;
const IS_IPHONE = (navigator.userAgent.match(/iPhone/i) != null) || (navigator.userAgent.match(/iPod/i) != null);
if (IS_IPAD || IS_IPHONE) {
element.href = "ios.com"; //
}
else {
element.href = "default.com"; // default
if (windowsize < 768) {
element.href = "android.com"; // default
}
else {
element.href = "default.com"; // default
}
};
};
getHref2();
</script>
this worked if the application was installed on the user's android device only and if the app is not installed on their devices it doesn't work at all.
for iOS somehow this method is not working at all please let me know how I can achieve the desired outcome
This question already has answers here:
What is the difference between client-side and server-side programming?
(3 answers)
Closed 3 years ago.
I have a problem I call the function (showpincode()) but the value is not working can you help me. I call it using backend but the value (txtRequestEncrypted.text) did not work
BACKEND C#
List<Upload> c = new List<Upload>();
c.Add(b);
a.UploadCardDetails = c;
a.ProgramName = null;
a.IPAddress = "111.222.33.444";
a.Authentication = "Basic RXFNzdzw==";
object obj = a;
string test = JsonConvert.SerializeObject(obj);
string pkey = "test";
string psalt = "test1";
string Result = Utilities.Utilities.test1(test, pkey, psalt);
txtRequestEncrypted.Text = Result.ToString();
this.Controls.Add(new LiteralControl("<script type='text/javascript'>ShowPINPad();</script>"));
JAVASCRIPT VALIDATION TO ACCESS THE PINCODE
<script type="text/javascript">
window.addEventListener("message", function (ev) {
"https://testtest.com.ph/index"
//event origin of virtual pin pad
$origin = ev.origin;
//event source of virtual pin pad
$source = ev.source;
//IMPORTANT: CHECK THE ORIGIN OF THE DATA!
if (ev.origin.indexOf($sourceURL)) {
if (ev.data.message === "deliverResult") {
ev.source.close();
}
else if (ev.data.message == "RESEND") {
txtResponse
try {
setTimeout(function () {
var requestData = $('#<%= txtRequestEncrypted.ClientID %>').val();
child.postMessage({ message: "requestResult", encryptedRequestData: requestData}, "*");
}, 3000);
} catch (e) {
//checking the virtual pin pad is closed
if (child.closed) {
console.log('Error encountered when calling virtual pinpad...');
clearTimeout(interval);
//do something
document.getElementById("txtResponse").value = "CLOSED";
document.getElementById("txtResponseEncrypted").value = "";
return;
}
}
}
}
});
THIS IS THE FUNCTION to Show Pinpad
var child = null;
function ShowPINPad() {
var height = 406;
var width = 450;
var left = Math.round((screen.width / 2) - (width / 2));
var top = Math.round((screen.height / 2) - (height / 2));
var targetURL = "https:test.com.ph/index"
child = window.open(targetURL, "_blank", "scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no,directories=no,copyhistory=no,height=" + height + ",width=" + width + ",left=" + left + ",top=" + top + ";");
// child.focus();
}
Page.ClientScript.RegisterStartupScript(this.GetType(),"CallMyFunction","MyFunction()",true);
check more Details On This Link
Calling JavaScript Function From CodeBehind
Please follow below code to call javascript function from code behind:
string jquery = "drawImage();"
ClientScript.RegisterStartupScript(typeof(Page), "a key",
"<script type=\"text/javascript\">"+ jquery +"</script>"
);
For more details:
Call javascript function from code behind
I am using openModal() javascript function ,its working fine in ie ,but in chrome and safari its appending base url with url i am sending,resulting in an error? Please Help!!
function OpenModalReplyDialog(url, SubscriberId) {
//Todo: Cleanup the unnecessary code.
var returnValue = new ModalReturnValue(null, null, null);
var retVal = null;
var urlredirect = url + '/UC_5_0_0.aspx?SubscriberId=' + SubscriberId;
returnValue = openModal(urlredirect, 350, 500);
return true;
}
This is code for openModal()
function openModal(url, width, height, args, options)
{
var returnValue = new ModalReturnValue(null, null, null);
var dialogArguments = self;
var defaultWindowOptions = 'center:yes;status:no;unadorned:yes;help:no;resizable:yes;';
if(args !=null)
{
dialogArguments = args;
}
var windowOptions = 'dialogHeight:' + height + 'px;dialogWidth:' + width + 'px;' + (options != null ? options : defaultWindowOptions);
returnValue = window.showModalDialog(url, dialogArguments, windowOptions);
if (returnValue != null)
{
if (returnValue.Command == "TimeOut") {
if (pageSessionTimeoutInfo != null) {
if (pageSessionTimeoutInfo.IsModal) {
closeModal(returnValue);
return;
}
}
redirectToUrl(returnValue.Url);
}
else
return returnValue;
}
else
return returnValue;
}
window.showModalDialog() is deprecated, it’s removed by Chrome & Firefox etc but works in IE. Please consider other options like Jquery dialog or bootstrap dialog or HTML5 dialog element. window.showModalDialog polyfill using a dialog element, click here for details.
I am trying to develop a Video Calling/Conferencing application using WebRTC and node.js.
Right now there is no facility to control bandwidth during during video call. Is there any way to control/reduce bandwidth.
(like I want make whole my web application to work on 150 kbps while video conferencing).
Any suggestions are highly appreciated.
Thanks in advance.
Try this demo. You can inject bandwidth attributes (b=AS) in the session descriptions:
audioBandwidth = 50;
videoBandwidth = 256;
function setBandwidth(sdp) {
sdp = sdp.replace(/a=mid:audio\r\n/g, 'a=mid:audio\r\nb=AS:' + audioBandwidth + '\r\n');
sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + videoBandwidth + '\r\n');
return sdp;
}
// ----------------------------------------------------------
peer.createOffer(function (sessionDescription) {
sessionDescription.sdp = setBandwidth(sessionDescription.sdp);
peer.setLocalDescription(sessionDescription);
}, null, constraints);
peer.createAnswer(function (sessionDescription) {
sessionDescription.sdp = setBandwidth(sessionDescription.sdp);
peer.setLocalDescription(sessionDescription);
}, null, constraints);
b=AS is already present in sdp for data m-line; its default value is 50.
Updated at Sept 23, 2015
Here is a library that provides full control over both audio/video tracks' bitrates:
// here is how to use it
var bandwidth = {
screen: 300, // 300kbits minimum
audio: 50, // 50kbits minimum
video: 256 // 256kbits (both min-max)
};
var isScreenSharing = false;
sdp = BandwidthHandler.setApplicationSpecificBandwidth(sdp, bandwidth, isScreenSharing);
sdp = BandwidthHandler.setVideoBitrates(sdp, {
min: bandwidth.video,
max: bandwidth.video
});
sdp = BandwidthHandler.setOpusAttributes(sdp);
Here is the library code. Its quite big but it works!
// BandwidthHandler.js
var BandwidthHandler = (function() {
function setBAS(sdp, bandwidth, isScreen) {
if (!!navigator.mozGetUserMedia || !bandwidth) {
return sdp;
}
if (isScreen) {
if (!bandwidth.screen) {
console.warn('It seems that you are not using bandwidth for screen. Screen sharing is expected to fail.');
} else if (bandwidth.screen < 300) {
console.warn('It seems that you are using wrong bandwidth value for screen. Screen sharing is expected to fail.');
}
}
// if screen; must use at least 300kbs
if (bandwidth.screen && isScreen) {
sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, '');
sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + bandwidth.screen + '\r\n');
}
// remove existing bandwidth lines
if (bandwidth.audio || bandwidth.video || bandwidth.data) {
sdp = sdp.replace(/b=AS([^\r\n]+\r\n)/g, '');
}
if (bandwidth.audio) {
sdp = sdp.replace(/a=mid:audio\r\n/g, 'a=mid:audio\r\nb=AS:' + bandwidth.audio + '\r\n');
}
if (bandwidth.video) {
sdp = sdp.replace(/a=mid:video\r\n/g, 'a=mid:video\r\nb=AS:' + (isScreen ? bandwidth.screen : bandwidth.video) + '\r\n');
}
return sdp;
}
// Find the line in sdpLines that starts with |prefix|, and, if specified,
// contains |substr| (case-insensitive search).
function findLine(sdpLines, prefix, substr) {
return findLineInRange(sdpLines, 0, -1, prefix, substr);
}
// Find the line in sdpLines[startLine...endLine - 1] that starts with |prefix|
// and, if specified, contains |substr| (case-insensitive search).
function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
var realEndLine = endLine !== -1 ? endLine : sdpLines.length;
for (var i = startLine; i < realEndLine; ++i) {
if (sdpLines[i].indexOf(prefix) === 0) {
if (!substr ||
sdpLines[i].toLowerCase().indexOf(substr.toLowerCase()) !== -1) {
return i;
}
}
}
return null;
}
// Gets the codec payload type from an a=rtpmap:X line.
function getCodecPayloadType(sdpLine) {
var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+');
var result = sdpLine.match(pattern);
return (result && result.length === 2) ? result[1] : null;
}
function setVideoBitrates(sdp, params) {
params = params || {};
var xgoogle_min_bitrate = params.min;
var xgoogle_max_bitrate = params.max;
var sdpLines = sdp.split('\r\n');
// VP8
var vp8Index = findLine(sdpLines, 'a=rtpmap', 'VP8/90000');
var vp8Payload;
if (vp8Index) {
vp8Payload = getCodecPayloadType(sdpLines[vp8Index]);
}
if (!vp8Payload) {
return sdp;
}
var rtxIndex = findLine(sdpLines, 'a=rtpmap', 'rtx/90000');
var rtxPayload;
if (rtxIndex) {
rtxPayload = getCodecPayloadType(sdpLines[rtxIndex]);
}
if (!rtxIndex) {
return sdp;
}
var rtxFmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + rtxPayload.toString());
if (rtxFmtpLineIndex !== null) {
var appendrtxNext = '\r\n';
appendrtxNext += 'a=fmtp:' + vp8Payload + ' x-google-min-bitrate=' + (xgoogle_min_bitrate || '228') + '; x-google-max-bitrate=' + (xgoogle_max_bitrate || '228');
sdpLines[rtxFmtpLineIndex] = sdpLines[rtxFmtpLineIndex].concat(appendrtxNext);
sdp = sdpLines.join('\r\n');
}
return sdp;
}
function setOpusAttributes(sdp, params) {
params = params || {};
var sdpLines = sdp.split('\r\n');
// Opus
var opusIndex = findLine(sdpLines, 'a=rtpmap', 'opus/48000');
var opusPayload;
if (opusIndex) {
opusPayload = getCodecPayloadType(sdpLines[opusIndex]);
}
if (!opusPayload) {
return sdp;
}
var opusFmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + opusPayload.toString());
if (opusFmtpLineIndex === null) {
return sdp;
}
var appendOpusNext = '';
appendOpusNext += '; stereo=' + (typeof params.stereo != 'undefined' ? params.stereo : '1');
appendOpusNext += '; sprop-stereo=' + (typeof params['sprop-stereo'] != 'undefined' ? params['sprop-stereo'] : '1');
if (typeof params.maxaveragebitrate != 'undefined') {
appendOpusNext += '; maxaveragebitrate=' + (params.maxaveragebitrate || 128 * 1024 * 8);
}
if (typeof params.maxplaybackrate != 'undefined') {
appendOpusNext += '; maxplaybackrate=' + (params.maxplaybackrate || 128 * 1024 * 8);
}
if (typeof params.cbr != 'undefined') {
appendOpusNext += '; cbr=' + (typeof params.cbr != 'undefined' ? params.cbr : '1');
}
if (typeof params.useinbandfec != 'undefined') {
appendOpusNext += '; useinbandfec=' + params.useinbandfec;
}
if (typeof params.usedtx != 'undefined') {
appendOpusNext += '; usedtx=' + params.usedtx;
}
if (typeof params.maxptime != 'undefined') {
appendOpusNext += '\r\na=maxptime:' + params.maxptime;
}
sdpLines[opusFmtpLineIndex] = sdpLines[opusFmtpLineIndex].concat(appendOpusNext);
sdp = sdpLines.join('\r\n');
return sdp;
}
return {
setApplicationSpecificBandwidth: function(sdp, bandwidth, isScreen) {
return setBAS(sdp, bandwidth, isScreen);
},
setVideoBitrates: function(sdp, params) {
return setVideoBitrates(sdp, params);
},
setOpusAttributes: function(sdp, params) {
return setOpusAttributes(sdp, params);
}
};
})();
Here is how to set advance opus bitrate parameters:
sdp = BandwidthHandler.setOpusAttributes(sdp, {
'stereo': 0, // to disable stereo (to force mono audio)
'sprop-stereo': 1,
'maxaveragebitrate': 500 * 1024 * 8, // 500 kbits
'maxplaybackrate': 500 * 1024 * 8, // 500 kbits
'cbr': 0, // disable cbr
'useinbandfec': 1, // use inband fec
'usedtx': 1, // use dtx
'maxptime': 3
});
A more up-to-date answer
const videobitrate = 20000;
var offer = pc.localDescription;
// Set bandwidth for video
offer.sdp = offer.sdp.replace(/(m=video.*\r\n)/g, `$1b=AS:${videobitrate}\r\n`);
pc.setLocalDescription(offer);
Explanation: a=mid:video is not a guaranteed tag. For receive only video, you might not see it or see a=mid:0. Generally it's a better bet to look for the m=video xxxx xxxx (or similar audio) tag and append the bandwidth parameters underneath
Not sure if this helps, but you can limit the video resolution from getUserMedia with constraints: see demo at simpl.info/getusermedia/constraints/.
My answer is not for node.js, but maybe someone stuck with controlling webrtc bandwidth while developing a native phone app (iOS, android).
So, at least in version GoogleWebRTC (1.1.31999) for iOS and org.webrtc:google-webrtc:1.0.22672 for android there is method in PeerConnection instance.
For iOS:
let updateBitrateSuccessful = pc.setBweMinBitrateBps(300000, currentBitrateBps: 1000000, maxBitrateBps: 3000000)
print("Update rtc connection bitrate " + (updateBitrateSuccessful ? "successful" : "failed"))
Respectively, for Android:
boolean updateBitrateSuccessful = pc.setBitrate(300000, 1000000, 3000000);
Log.d("AppLog", "Update rtc connection bitrate " + (updateBitrateSuccessful ? "successful" : "failed"));
It depends on what SFU media server you're using. But in short, your media server needs to tell the client browser what maximum bitrate it should send, by setting the bandwidth attribute in the answer SDP, as well as in the REMB message it periodically sends.
The REMB (receiver estimated maximum bitrate) applies separately to audio and video streams (at least on desktop Chrome and Firefox that I tested). So if REMB is set to 75kps and you have one audio and one video stream, then each will confine to 75kps for a total transport bitrate of 150kps. You should use chrome://webrtc-internals to test and verify this.
If you are using OPUS as the audio codec, you can control the audio bandwidth separately by setting the maxaveragebitrate attribute in the answer SDP. Setting this attribute will override the REMB value (verified on Chrome). So you can set audio bitrate to 16kps and the video bitrate (via REMB) to 134kps for a combined transport bitrate of 150.
Note that the REMB is sent by your server, so your server needs to support this. The other SDP attributes can be manipulated on the client side by modifying the answer SDP that you receive, right before passing it to setRemoteDescription().
This is my limited understanding based on online research. It's not based on deep knowledge of the technology stack, so please take it with a grain of salt.
You should also be able to use bandwidth constraints on the stream (see this demo), but it doesn't appear to be working, even in the latest canary (29.0.1529.3).
There's some discussion of the SDP-based approach on the discuss-webrtc mailing list, which links to WebRTC bug 1846.
I did it Yesterday and it works like a charm! in my case, it was needed to prevent slow and old phones get freeze during a videocall! have a look
function handle_offer_sdp(offer) {
let sdp = offer.sdp.split('\r\n');//convert to an concatenable array
let new_sdp = '';
let position = null;
sdp = sdp.slice(0, -1); //remove the last comma ','
for(let i = 0; i < sdp.length; i++) {//look if exists already a b=AS:XXX line
if(sdp[i].match(/b=AS:/)) {
position = i; //mark the position
}
}
if(position) {
sdp.splice(position, 1);//remove if exists
}
for(let i = 0; i < sdp.length; i++) {
if(sdp[i].match(/m=video/)) {//modify and add the new lines for video
new_sdp += sdp[i] + '\r\n' + 'b=AS:' + '128' + '\r\n';
}
else {
if(sdp[i].match(/m=audio/)) { //modify and add the new lines for audio
new_sdp += sdp[i] + '\r\n' + 'b=AS:' + 64 + '\r\n';
}
else {
new_sdp += sdp[i] + '\r\n';
}
}
}
return new_sdp; //return the new sdp
}
pc.createOffer(function(offer) {
offer.sdp = handle_offer_sdp(offer); //invoke function saving the new sdp
pc.setLocalDescription(offer);
}, function(error) {
console.log('error -> ' + error);
});
I recommend to change value of maxBitrate property as described here https://stackoverflow.com/a/71223675/1199820
Check this, this works for me.
Control your bitrate via getSenders(), after peer is connected then you can set your maximum bitrate.
This method allow you to control bitrate without renegotiation. so,
you can change the streaming quality during a call
//bandwidth => "unlimited", 75 kbps, 250 kbps, 1000 kbps, 2000 kbps
var bandwidth = 75;
const sender = pc1.getSenders()[0];
const parameters = sender.getParameters();
if (!parameters.encodings) {
parameters.encodings = [{}];
}
if (bandwidth === 'unlimited') {
delete parameters.encodings[0].maxBitrate;
} else {
parameters.encodings[0].maxBitrate = bandwidth * 1000;
}
sender.setParameters(parameters)
.then(() => {
// on success
})
.catch(e => console.error(e));
Reference code & demo
This way I get the reference to the open window:
var refWin = window.open("mypage1", "name_mypage");
if you want to close the window, I close with:
refWin.close();
if I do a screen refresh (F5) and run the same line, it opens in the same window, because I put the same name.
var refWin = window.open("mypage2", "name_mypage");
but with different reference (refWin).
Question: how I can make reference to the window based on the name?, I need to close the window before opening, with the same name.
do something like:
var refWin = window.open("about:blank", "name_mypage");
refWin.close();
refWin = window.open("mypage2", "name_mypage");
but without having to be a blank window for reference.
thanks
Based on andres's comment, here is the solution he's looking for:
refWin.location = "myurl";
refWin.focus();
This will open "myurl" in the window, and focus it.
Or.
var refWin = window.open("mypage1", "name_mypage");
refWin.focus();
Edit:
If you're not reloading the page again, there shouldn't be any reason you can't just do this:
var refWin = window.open("mypage1", "name_mypage");
refWin.close();
refWin = window.open("mypage1", "name_mypage");
If you're really concerned about it, you could make your own "windows" object:
var windows = {};
var refWin = window.open("mypage1", "name_mypage");
windows[refWin.name] = refWin;
windows("name_mypage").close(); // close the window
I don't think that's terribly productive, as you still can't focus it reliably, but maybe it fits your uses.
my solution based on another script:
Helper.window = new function () {
// Private fields
var w = window, s = screen, _self = this, whs = {}, isChrome = /chrome/.test(navigator.userAgent.toLowerCase());
// Public Members
this.focus = function (wh) {
if (!wh) return;
if (isChrome) wh.blur();
wh.focus();
};
this.windowExists = function (wt) {
return wt && whs[wt] && (typeof whs[wt]['closed'] != undefined) && !whs[wt].closed;
};
this.close = function (wt) {
if (typeof whs[wt][close] != undefined) whs[wt].close();
whs[wt] = null;
return _self;
};
this.properties = function (wp) {
wp = (wp || 'menubar=yes').toLowerCase();
if (!(/menubar/.test(wp)))
wp += 'menubar=yes';
if (!(/location/.test(wp)))
wp += ',location=yes';
if (!(/width/.test(wp)))
wp += ',width=' + (s.availWidth - 150);
if (!(/height/.test(wp)))
wp += ',height=' + (s.availHeight - 150);
if (!(/scrollbars/.test(wp)))
wp += ',scrollbars=yes';
if (!(/resizable/.test(wp)))
wp += ',resizable=yes';
return wp;
};
this.open = function (url, wt, wp) {
if (_self.windowExists(wt))
return _self.close(wt).open(url, wt, wp);
var urlOpen = '';
if (typeof url == 'string') {
urlOpen = url;
} else if (jQuery(url).get(0).tagName.toLowerCase() == 'a') {
urlOpen = jQuery(url).attr('href');
} else {
urlOpen = 'about:blank';
}
wp = _self.properties(wp);
wt = wt || "_blank";
var wh = wp ? w.open(urlOpen, wt, wp) : w.open(urlOpen, wt);
if (wh && "_blank" !== wt) {
whs[wt] = wh;
_self.focus(wh);
}
return wh;
};
};