Unable to connect to styled receiver - javascript

I am trying to build a simple JS based web app that starts a styled media receiver(hosted by Google, reads your custom CSS file). I have a developer account set up and have gone through adding the app in my account. I made sure to select the "Styled Media Receiver" type when I created it.
I am using the basic setup described here to construct my sender. I was able to get this code to work with a custom receiver. I can see in my log that the extension is detected.
Found cast extension: boadgeojelhgndaghljhdicfkmllpafd
I set up my session request with the app ID provided on the Cast developer's console.
var sessionRequest = new chrome.cast.SessionRequest(id);
Then I call:
var apiConfig = new chrome.cast.ApiConfig(this.sessionListener.bind(this),
this.receiverListener.bind(this));
Which returns the value "unavailable" to the "receiverListener" function. When I try to request a session it returns the error callback with the following data:
Object {code: "receiver_unavailable", description: null, details: null}
So, I am trying to figure out what I might be missing. Like I said I've used the same code to launch a custom receiver successfully. Here is the full code that I am using:
Polymer({
ready: function(){
window['__onGCastApiAvailable'] = function(loaded, errorInfo){
if(loaded){
this.initCast();
}
else{
console.log(errorInfo);
}
}.bind(this);
},
initCast: function(){
var id = "731AC858";
var sessionRequest = new chrome.cast.SessionRequest(id);
var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
this.sessionListener.bind(this),
this.receiverListener.bind(this));
chrome.cast.initialize(apiConfig,
this.initCastSuccess.bind(this),
this.initCastError.bind(this));
},
initCastSuccess: function(){
this.castReady = true;
},
initCastError: function(e){
console.log(e);
},
startCast: function(){
chrome.cast.requestSession(this.startCastSuccess.bind(this),
this.startCastError.bind(this));
},
startCastSuccess: function(e){
console.log(e);
},
startCastError: function(e){
console.log(e); //returns Object {code: "receiver_unavailable", description: null, details: null} when "startCast" is called.
},
sessionListener: function(e){
console.log(e);
},
receiverListener: function(e){
console.log(e);//returns "unavailable"
},
});

Well it looks like I was either being impatient and it takes a while for the app to digest, or the server that hosts the Styled media receiver was down for a while. I tried it today and everything is working great.
----UPDATE----
I just tried creating a fresh styled media receiver app, and I can't get it to connect. So my guess is that there is something that has to be prepped before you can start using it.

Related

Can't get localhost mode to work in split.io

According to the documentation on split.io I should be able to create a Split client in 'localhost' mode, i.e. it will work offline. Here is the link: https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#localhost-mode
But nothing happens when I run this code:
// Import the SDK
var SplitFactory = require("#splitsoftware/splitio").SplitFactory;
// Instantiate the SDK
var factory = SplitFactory({
core: {
authorizationKey: "localhost",
},
features: {
"my-feature": "on",
},
});
// Get the client instance you'll use
var client = factory.client();
console.log("created the client");
// Set a callback to listen for the SDK_READY event, to make sure the SDK is properly loaded before asking for a treatment
client.on(client.Event.SDK_READY, function () {
console.log("SDK_READY");
var treatment = client.getTreatment("CUSTOMER_ID", "my-feature");
console.log(treatment);
});
client.on(client.Event.SDK_UPDATE, () => {
console.log("SDK_UPDATE");
});
client.once(client.Event.SDK_READY_TIMED_OUT, () => {
console.log("SDK_READY_TIMED_OUT");
});
client.once(client.Event.SDK_READY_FROM_CACHE, () => {
console.log("SDK_READY_FROM_CACHE");
});
"created the client" is logged but then nothing after that. How do I get SDK_READY to fire? It works fine if I give it a real API key.
I also put the code in a github project: https://github.com/philipbeber/splitlocalhost
It turns out that the Split SDK behaves differently if you are running from nodejs rather than in the browser. So if you use jest with its default settings then you need to reference different docs: https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK
There is no way to force the Split module to "client mode" which is infuriating.

Microsoft.Office.WebExtension not working when I use the Excel JavaScript API to build an add-in

I'm using the Office JS library to create an Excel add-in, and the Microsoft object is not being recognized. All the other classes from the library seem to to work fine, but when I call dialog.addEventHandler(Microsoft.Office.WebExtension.EventType.DialogMessageReceived,processMessage the Microsoft object is not evaluated properly. This is despite every other object from this library working fine.
I'm following this tutorial https://learn.microsoft.com/en-us/office/dev/add-ins/tutorials/excel-tutorial
I'm using CDN from this link: https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js
The method that calls Microsoft.Office.WebExtension fails, and I knew it would because WebStorm tells me its not recognized.
All of the other objects from Office JS work fine though...here's an example of working code:
function sortTable() {
Excel.run(function (context) {
// Queue commands to sort the table by merchant name
var currentWorkbook = context.workbook.worksheets.getActiveWorksheet();
var expensesTable = currentWorkbook.tables.getItem('ExpensesTable');
var sortFields = [
{
key: 1,
ascending: false,
}
];
expensesTable.sort.apply(sortFields);
return context.sync();
}).catch(function (error) {
console.log("Error" + error);
if (error instanceof OfficeExtension.Error) {
console.log("Debug info: " + JSON.stringify(error.debugInfo));
}
});
}
I've review in detail the Office JavaScript API documentation: https://learn.microsoft.com/en-us/office/dev/add-ins/reference/overview/excel-add-ins-reference-overview
I've reviewed that there is an older common API: https://learn.microsoft.com/en-us/javascript/api/office?view=word-js-preview
I have suspected that I need access to this older common API, but the only documentation I've found says that you are just supposed to use the office.js library I've linked above.
Here's the whole function I'm trying to use:
function openDialog() {
//Call the Office Common API that opens a dialog
Office.context.ui.displayDialogAsync(
'https://localhost:3000/popup.html',
{height: 45, width:55},
function (result) {
dialog = result.value;
dialog.addEventHandler(Microsoft.Office.WebExtension.EventType.DialogMessageReceived,processMessage);
}
)
}
It does in fact open a dialog box as the Office.context.ui.displayDialogAsync method works. But as soon as you get to Microsoft.Office.WebExtension.EventType.DialogMessageReceived WebStorm tells me that the element Microsoft is an unresolved reference.
And here's the function it should call if it worked, processMessage. Because it does not get this far, the element does not get updated, and the dialog box does not close. I'm near 100% certain the issue is not with the function below, but I'm not ruling it out yet.
function processMessage(arg) {
console.log("made it inside processMessage")
document.getElementById("user-name").innerHTML = arg.message;
console.log("made ti just before dialog.close")
dialog.close();
}
The full name has been shortened to Office.EventType.DialogMessageReceived. Here's the GitHub issue: https://github.com/OfficeDev/office-js-docs-pr/issues/1710

Implementing Dropbox API V2 in Cordova Application

I have a Cordova application with previous Dropbox implementation using rossmartin/phonegap-dropbox-sync-android. Now as the API V1 is going to be deprecated I want to upgrade to Dropbox API V2. I have searched for plugins for Cordova applications using Dropbox API V2 but didn't find any.So I am trying to implement it using dropbox/dropbox-sdk-js.
For Authentication, I am using authenticateWithCordova method which returns me the Access token (Full documentation here).This method returns Access token once the user completes authentication with Dropbox and uses the redirect URL to redirect the user to Cordova application.
This method works perfectly when the user clicks the button for the first time, but when the user clicks the button again calling this method shows a blank screen and return a new access token. How to avoid seeing the blank screen?
This is the method from Dropbox-sdk.js file, which I have called from my application,
DropboxBase.prototype.authenticateWithCordova = function (successCallback, errorCallback)
{
var redirect_url = 'https://www.dropbox.com/1/oauth2/redirect_receiver';
var url = this.getAuthenticationUrl(redirect_url);
var browser = window.open(url, '_blank');
var removed = false;
var onLoadError = function(event) {
// Try to avoid a browser crash on browser.close().
window.setTimeout(function() { browser.close() }, 10);
errorCallback();
}
var onLoadStop = function(event) {
var error_label = '&error=';
var error_index = event.url.indexOf(error_label);
if (error_index > -1) {
// Try to avoid a browser crash on browser.close().
window.setTimeout(function() { browser.close() }, 10);
errorCallback();
} else {
var access_token_label = '#access_token=';
var access_token_index = event.url.indexOf(access_token_label);
var token_type_index = event.url.indexOf('&token_type=');
if (access_token_index > -1) {
access_token_index += access_token_label.length;
// Try to avoid a browser crash on browser.close().
window.setTimeout(function() { browser.close() }, 10);
var access_token = event.url.substring(access_token_index, token_type_index);
successCallback(access_token);
}
}
};
Here is my code which I use to call the method,
function authenticateWithCordova()
{
var dbx = new Dropbox({ clientId: CLIENT_ID });
dbx.authenticateWithCordova(AuthSuccess,AuthFail);
}
function AuthSuccess(accessToken)
{
localStorage.accessToken = accessToken;
}
function AuthFail()
{
alert("Auth Fail");
}
I have found an analog issue right yesterday. This is the way I solved it.
First, I have set var dbx as global. In my index.js I put these lines immediately after app.initialize():
var CLIENT_ID = 'xxxxxxxxxxxxxxx';
var dbxt;
var dbx = new Dropbox({clientId: CLIENT_ID});
Then I check if dbxt is null: if it is, I create a new Dropbox object using accessToken, otherwise I go with the dropbox connection already established:
if (dbxt == null) {
dbx.authenticateWithCordova(function (accessToken) {
dbxt = new Dropbox({accessToken: accessToken});
dbxt.filesUpload({
path: '/mydump.sql',
contents: sql,
mode: 'overwrite',
mute: true
}).then(function (response) {
alert('Your backup has been successfully uploaded to your Dropbox!')
}).catch(function (error) {
alert('Error saving file to your Dropbox!')
console.error(error);
});
}, function (e){
console.log("failed Dropbox authentication");
}
}else{//dbxt already created
dbxt.filesUpload... //and the rest
}
This is just to avoid to create a new connection and get a new access token everytime and I confess I'm not sure this is a good practice: I only know that before to apply this code I got a lot of bad requests responses by Dropbox server:)
When I used the above code, after the first login, I started to see the blank page: that's is the inappbrowser page which Dropbox OAuth2 uses as redirect URI (set to https://www.dropbox.com/1/oauth2/redirect_receiver in your Dropbox app page).
So the problem was how to make this page invisible. I found a dirty trick applying a small tweak to inappbrowser.js script.
Near the bottom of the script, immediately before this line:
strWindowFeatures = strWindowFeatures || "";
I have put this small block:
if (strUrl.indexOf('dropbox') > -1){
strWindowFeatures += "location=no,hidden=yes";
}
I would have expected to can just use 'hidden=yes' but surprisingly if I remoce 'location=no' the blkank page appears again.
Notice 1: you don't have to modify the script inappbrowser.js located at plugins\cordova-plugin-inappbrowser\www\ but the one you find in platforms\android\platform_www\plugins\cordova-plugin-inappbrowser\www\
Notice 2: I have found this workaround right now so I'm not 100% sure it works perfectly.
Notice 3: making the inappbrowser page invisible, depending on the Internet connection, it could look like nothing is happening for a while, so you'll have to add some loader to inform your user that the app is working.
Hope this help.
UPDATE
I've just realized we can tweak directly the dropbox-sdk instead of inappbrowser.
If you are using Dropbox with browserify you have to open dropbox-base.js and look for authenticateWithCordova() method (it should be at line 107. Then change the line
var browser = window.open(url, '_blank');
to
var browser = window.open(url, '_blank', "location=no,hidden=yes");
If you are using Dropbox-sdk.min.js, you have to look for 'window.open' using the search function of your code editor. It will be easy because 'window.open' is used only once. So you'll have to change the following:
i=window.open(n,"_blank"),
to
i=window.open(n,"_blank","location=no,hidden=yes"),
And this seems to work fine (I prefer to be careful before I get excited).
UPDATE 2
Forgive previous update. My previous check:
if (strUrl.indexOf('dropbox') > -1){
strWindowFeatures += "location=no,hidden=yes";
}
is wrong because it makes invisible any inappbrowser window which tries to connect to dropbox so it prevent us from even logging into Dropbox. So we need to change it to
if (strUrl == 'https://www.dropbox.com/1/oauth2/redirect_receiver') {
strWindowFeatures += "location=no,hidden=yes";
}
This way we can do the login correctly and next connections won't show the inappbrowser window, as we want.
So summarizing:
Ignore my first update
Use UPDATE 2 to modify the url check in inappbrowser.js
Forgive me for the confusion...

Accessing a media file created with Cordova plugin for local use in Meteor script with gifshotJS library

to make my question short and simple:
How can I access the mediaFile generated by cordova-plugin-media-capture's function capture.captureVideo() and convert it with gifShot JS' createGIF()function into a GIF on an Android device?
I ran into the problem, that neither the fullPath (file:/URI), nor the localURL (cdvfile://) of the generated mediaFile are permitted for the use, if I directly give one of them as path for the video file for gifshot, I receive following message:
Cross-origin image load denied by Cross-Origin Resource Sharing policy.
I know that the file plugin successfully creates the videos (I can see them in the galery, so they are saved on the device permanently).
And I also know that gifShot works with mp4 videos as I already created a folder inside the project directory containing a video which it rendered correctly. I also know that sadly JavaScript normally is not permitted to gain access to files on a device/PC, but isn't there a workaround provided with Cordova?
Can someone briefly explain me, how I could access the saved file? Do I need the cordova plugins "cordova-plugin-file" and "cordova-plugin-file-transfer" and how do I use them?
My code:
Javascript:
import gifshot from 'gifshot';
Template.gifshotTest.rendered = function () {
var $$ = Dom7;
var myapp = new Framework7();
};
Template.gifshotTest.events({
'click .gifShotUpload': function () {
Meteor.call("console", "Button clicked");
// capture callback
var captureSuccess = function (mediaFiles) {
path = mediaFiles[0].localURL;
Meteor.call("console", mediaFiles[0]);
gifshot.createGIF({video: path}, function(obj) {
Meteor.call("console", "---> gifshot obj:");
Meteor.call("console", obj);
if (!obj.error) {
var image = obj.image;
$('.giffy').attr("src", image);
Meteor.call("console", image);
}
});
};
// capture error callback
var captureError = function (error) {
navigator.notification.alert('Error code: ' + error.code, null, 'Capture Error');
};
// start video capture
navigator.device.capture.captureVideo(captureSuccess, captureError, {limit: 1, duration: 5, quality: 1});
}
});
Console logs
I20160421-15:25:36.283(2)? Button clicked
I20160421-15:25:42.158(2)? null
I20160421-15:25:42.166(2)? { name: 'VID_20160421_152544.mp4',
I20160421-15:25:42.167(2)? localURL: 'cdvfile://localhost/sdcard/DCIM/Camera/VID_20160421_152544.mp4',
I20160421-15:25:42.167(2)? type: 'video/mp4',
I20160421-15:25:42.168(2)? lastModified: null,
I20160421-15:25:42.168(2)? lastModifiedDate: 1461245147000,
I20160421-15:25:42.169(2)? size: 461498,
I20160421-15:25:42.169(2)? start: 0,
I20160421-15:25:42.169(2)? end: 0,
I20160421-15:25:42.170(2)? fullPath: 'file:/storage/emulated/0/DCIM/Camera/VID_20160421_152544.mp4' }
I20160421-15:25:44.656(2) (android:http://localhost:12680/:0) Cross-origin image load denied by Cross-Origin Resource Sharing policy.
Included Cordova Plugins (Cordova Version 3.8.3):
cordova-plugin-file#4.1.1
cordova-plugin-file-transfer#1.5.1
cordova-plugin-media-capture#1.2.0
Thanks to everyone who helps me understanding the way Cordova and other libraries handle files on a device.
If the file is successfully stored in device, you can open the same use using cordova-fileopener-plugin. I would also suggest you to update your cordova version as the one you are using is too old

Capture screen -- chrome.desktopCapture.chooseDesktopMedia fails -- PNacl extension

I'm trying to use the desktopCapture API in the following manner.
chrome.desktopCapture.chooseDesktopMedia(
["screen", "window"], onAccessApproved);
chrome.desktopCapture shows as undefined when I set a breakpoint and inspect it. Permissions in my manifest file are as follows:-
"permissions": ["desktopCapture", "notifications" ]
Common causes for failure of this API are listed here as
a permission is missing in the application's manifest.json file
the API is defined on a newer version of Chrome then the current runtime
docs inherited from ChromeApi
And I don't have those problems.
My Chrome version is 43.0.2357.124 m
Pepper version is 43
FYI, I am trying to develop a Chrome extension to capture the screen using PNacl, and have borrowed from the media_stream_video example downloaded from here. But I haven't even gotten to sending a message to the pexe side yet. I'm still stuck at chrome.desktopCapture.chooseDesktopMedia returning undefined.
You need to call chrome.desktopCapture.chooseDesktopMedia from the background script running in the context of the extension. This Sample shows a simple method to use the extension to get screen media.
Keep in mind that this is callback based, so you get access to the stream id from the callback.
This runs in the context of your page (see full example here):
// check that the extension is installed
if (sessionStorage.getScreenMediaJSExtensionId) {
// send a message to your extension requesting media
chrome.runtime.sendMessage(sessionStorage.getScreenMediaJSExtensionId,
{type:'getScreen', id: 1}, null,
function (data) {
if (data.sourceId === '') { // user canceled
// handle error
} else {
constraints.video.mandatory.chromeMediaSourceId = data.sourceId;
getUserMedia(constraints, callback);
}
}
);
}
And this run in the context of your extension (see full example here):
chrome.runtime.onMessageExternal.addListener(function (message, sender, callback) {
switch(message.type) {
case 'getScreen':
var pending = chrome.desktopCapture.chooseDesktopMedia(message.options || ['screen', 'window'],
sender.tab, function (streamid) {
// communicate this string to the app so it can call getUserMedia with it
message.type = 'gotScreen';
message.sourceId = streamid;
callback(message);
return false;
});
return true; // retain callback for chooseDesktopMedia result
}
});

Categories