Youtube iframe API on Xbox One? - javascript

I am trying to integrate the Youtube iframe API on Xbox One to be able to play Youtube videos from an application, but so far did not manage to make it work. Is it even possible ?
It seems that windows store apps imposes a lot of restrictions compared to a web app (for very understandable security reasons).
The first problem when porting the web app is the local context / web context. There seems to be two options there:
grab a version of Youtube's code (at least the part that loads the library) and integrate it into the app (this way, we control more of the code at certification time, but it could eventually not be in sync anymore with the rest of the web code)
load all Youtube's code from the web in a web context (by putting the YT.player inside another iframe) and then do a proxy in the local context to post messages to the equivalent web context.
What method is the recommended one ?
The second problem is that IE in the application seems to load YouTube's videos in Flash, because it complains about ActiveX not being there. I get the following error:
Exception was thrown at line 328, column 376 in
https://s.ytimg.com/yts/jsbin/www-embed-player-new-vflRnMsMv/www-embed-player-new.js
0x800a1391 - JavaScript runtime error: 'ActiveXObject' is undefined
Is there a way to force the app to load videos in HTML5 instead of flash ? I tried setting html5=1 in the playerVars, like in the following code (as suggested in http://jsfiddle.net/rocha/eMAU5/), but it didn't help:
player = new YT.Player('player', {
height: '390',
width: '640',
videoId: 'OEoXaMPEzfM',
playerVars: {
html5: 1,
}
Or maybe I am not interpreting correctly the reason for the loading of this ActiveX ? I know that ActiveX are deactivated in windows store applications (and X1 apps). Anyway, how can I make this work (if at all possible) ?
Thank you

This is not supported behavior. Not only is ActiveX not supported in ADK apps, but loading in remote code is against XR-010. I suggest launching the browser with the YouTube video url using Launcher.LaunchUriAsync:
// The URI to launch
var uriToLaunch = "https://www.youtube.com/user/xbox";
// Create a Uri object from a URI string
var uri = new Windows.Foundation.Uri(uriToLaunch);
// Launch the URI
Windows.System.Launcher.launchUriAsync(uri).then(
function (success) {
if (success) {
// URI launched
} else {
// URI launch failed
}
});
Lastly, please post your Xbox specific questions to the appropriate Xbox forums. I will be happy to answer them there, and more thoroughly. NDA protected program information should not be discussed on a public forum.

Related

Open video URL in native player from Google Chrome

I'm trying to open a remote video (let's say it's located at http://www.example.com/video.mp4) with the default Android player launched directly from Google Chrome, making use of the brand new intent://.
This is the URI I called through an href tag:
intent://www.example.com/video.mp4#Intent;scheme=file;action=android.intent.action.VIEW;end;
Of course, this URI doesn't work, and Chrome returns error "Unable to perform navigation". I've also tried the same URI omitting scheme=file.
Here's the documentation I've been following: https://developer.chrome.com/multidevice/android/intents
Thanks in advance!
A quick browse of the Gallery App in AOSP shows that it can be launched from a browser. It has a category of BROWSABLE and DEFAULT. This means given the correct intent URL you should be able to launch it.
Obviously specifying a package should work, but that is not flexible, what if there are two gallery apps.
The following Intent scheme url works:
intent://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_1mb.mp4#Intent;action=android.intent.action.VIEW;scheme=http;type=video/mp4;end
Note:
scheme = http (it needs to be that or https),
there is a // before the domain, if that is not there the URL is not constructed correctly in the player
action = android.intent.action.VIEW
type = video/mp4 - if this is not in place the video will open in the browser
I have created a demo that works

How can I allow JavaScript to run in the background, in Firefox? [duplicate]

In app I can use http://developer.android.com/reference/android/os/PowerManager.WakeLock.html
but is there a way to keep webpage running and prevent from going to sleep?
It would be nice if it runs at least on android.
You can use: https://github.com/richtr/NoSleep.js
Prevent display sleep and enable wake lock in any Android or iOS web browser.
Note that the library has some reliability/performance issues on some platforms/browsers. Users have found solutions that are listed in the issue comments and pull requests, but they have not been added since the repo owner appears not to be active currently.
It's recommended that you check those pull requests (and/or issues) for potential improvements before using in production.
You can use the Wake Lock web API (check support)
https://web.dev/wakelock/
In an app there are a couple of ways you can do it, but I guess you mean just in a mobile web page, viewed in any browser via Android. With normal HTML/Javascript/etc., I really, really doubt it.
It actually may be possible using Flash (on flash-enabled phones with plugins enabled), though, at least in specific circumstances. I say this because, in a test app without the WAKE_LOCK permission, loading this swf file into a WebView caused the following exception on some devices:
java.lang.SecurityException: Neither
user ##### nor current process has
android.permission.WAKE_LOCK
Even if this did work, however, it would run the risk of crashing apps or browsers that did not have the WAKE_LOCK permission. It may be possible due to bad code in the Adobe Flash Player plugin, rather than any intentional functionality.
Play fake looped VIDEO or AUDIO on your page
You can use this a quick example to add a looped video with fake data to your page and prevent mobile device from sleep:
// Create the root video element
var video = document.createElement('video');
video.setAttribute('loop', '');
// Add some styles if needed
video.setAttribute('style', 'position: fixed;');
// A helper to add sources to video
function addSourceToVideo(element, type, dataURI) {
var source = document.createElement('source');
source.src = dataURI;
source.type = 'video/' + type;
element.appendChild(source);
}
// A helper to concat base64
var base64 = function(mimeType, base64) {
return 'data:' + mimeType + ';base64,' + base64;
};
// Add Fake sourced
addSourceToVideo(video,'webm', base64('video/webm', 'GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA='));
addSourceToVideo(video, 'mp4', base64('video/mp4', 'AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAAG21kYXQAAAGzABAHAAABthADAowdbb9/AAAC6W1vb3YAAABsbXZoZAAAAAB8JbCAfCWwgAAAA+gAAAAAAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIVdHJhawAAAFx0a2hkAAAAD3wlsIB8JbCAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAIAAAACAAAAAABsW1kaWEAAAAgbWRoZAAAAAB8JbCAfCWwgAAAA+gAAAAAVcQAAAAAAC1oZGxyAAAAAAAAAAB2aWRlAAAAAAAAAAAAAAAAVmlkZW9IYW5kbGVyAAAAAVxtaW5mAAAAFHZtaGQAAAABAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAEcc3RibAAAALhzdHNkAAAAAAAAAAEAAACobXA0dgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAIAAgASAAAAEgAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABj//wAAAFJlc2RzAAAAAANEAAEABDwgEQAAAAADDUAAAAAABS0AAAGwAQAAAbWJEwAAAQAAAAEgAMSNiB9FAEQBFGMAAAGyTGF2YzUyLjg3LjQGAQIAAAAYc3R0cwAAAAAAAAABAAAAAQAAAAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAFHN0c3oAAAAAAAAAEwAAAAEAAAAUc3RjbwAAAAAAAAABAAAALAAAAGB1ZHRhAAAAWG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAK2lsc3QAAAAjqXRvbwAAABtkYXRhAAAAAQAAAABMYXZmNTIuNzguMw=='));
// Append the video to where ever you need
document.body.appendChild(video);
// Start playing video after any user interaction.
// NOTE: Running video.play() handler without a user action may be blocked by browser.
var playFn = function() {
video.play();
document.body.removeEventListener('touchend', playFn);
};
document.body.addEventListener('touchend', playFn);
If you build a WebViewGold/WebView app on Android (while having the actual webpage/web app in such a wrapper), all these mentioned approaches here will not work. But then you can also do set
PREVENT_SLEEP = TRUE;
in Config.java which should do the trick.
On iOS devices, just refreshing the page in Javascript every few seconds will keep the screen awake. This seems to be the correct strategy, hopefully Android will adopt this in a future version.

Facebook app browser debugging [duplicate]

I'm developing website with a lot of HTML5 and CSS3 features. I'm also using iframe to embed several content on my website. It works fine if I open it using Chrome/Firefox/Safari mobile browser. However, if I share on facebook (post/page) and I opened it up with Facebook application with Facebook Internal Browser, my website is messed up.
Is there any tools or way to debug on Facebook Browser? Thanks.
This is how you can do the debugging yourself. It's painful, but the only way I've come across so far.
tl;dr Get the Facebook App loading a page on your local server so you can iterate quickly. Then print debug statements directly to the page until you figure out what is going on.
Get a link to a page on your local server that you can access on your mobile device (test in mobile safari that it works). See this to find out your local IP address How do you access a website running on localhost from iPhone browser. It will look something like this
http://192.xxx.1.127:3000/facebook-test
Post that link on your Facebook page (you can make it private so your friends aren't all like WTF?)
Click the posted link in the Facebook mobile App and it will open up in Facebook's mobile browser
Since you don't have a console, you basically need to print debug statements directly to the page so it is visible. Put debug statements all over your code. If your problems are primarily related to CSS, then you can iteratively comment out stuff until you've found the issue(s) or print the relevant CSS attributes using JavaScript. Eg something like (using JQuery)
function debug(str){$('body').append("<br>"+str);}
Quite possibly the most painful part. The Facebook browser caches very aggressively. If you are making changes and nothing has happened, it's because the content is cached. You can sometimes resolve this by updating the URLs, eg /facebook-test-1, /facebook-test-2, or adding dummy parameters eg /facebook-test?dummy=1. But if the changes are in external css or js sheets it sometimes will still cache. To 100% clear the cache, delete the Facebook App from your mobile device and reinstall.
The internal browser the Facebook app uses is essentially a uiWebView. Paul Irish has made a simple iOS app that lets you load any URL into a uiWebView which you then can debug using Safari's Developer Tools.
https://github.com/paulirish/iOS-WebView-App
I found a way how to debug it easier. You will need to install the Ghostlab app (You have a 7-day free trial there, however it's totally worth paying for).
In Ghostlab, add the website address (or a localhost address) you want to debug and start the session.
Ghostlab will generate a link for access.
Copy that link and post it on Facebook (as a private post)
Open the link on mobile and that's it! Ghostlab will identify you once you open that link, and will allow you to debug the page.
For debugging, you will have all the same tools as in the Chrome devtools (how cool is that!). For example, you can tweak CSS and see the changes applied live.
If you want to debug a possible error, you can try to catch it and display it.
Put this at the very top of your code:
window.onerror = function (msg, url, lineNo, columnNo, error) {
var string = msg.toLowerCase();
var substring = "script error";
if (string.indexOf(substring) > -1){
alert('Script Error: See Browser Console for Detail');
} else {
var message = [
'Message: ' + msg,
'URL: ' + url,
'Line: ' + lineNo,
'Column: ' + columnNo,
'Error object: ' + JSON.stringify(error)
].join(' - ');
alert(message);
}
}
(Source: MDN)
This will catch and alert your errors.
Share a link on Facebook (privately), or send yourself a message on Facebook Messenger (easier). To break the cache, create a new URL every time, e.g. by appending a random string to the URL.
Follow the link and see if you can find any errors.
With help of ngrok create temporary http & https adress instead of your ordinary localhost:3000(or other port) and you could run your app on any devices. It is super easy to use.
and as it was written above all other useful information you should write somewhere inside div element (in case of React I recommend to put onClick on that div with force update or other function for getting info, sometimes it helps because JS in FB could be executed erlier than your information appears). Keep in mind that alerts are not reliable, sometimes they are blocked
bonus from ngrok that in console you will see which files was
requested and response code (it will replace lack of network tab)
and about iFrame.If you use it on other domain and you rely on cookies - you should know that facebook in-app browser blocks 3rd party cookies
test on Android and iOS separately because technicaly they use different browsers

Chrome extensions for silent print?

I have made a silent print web application that prints a PDF file. The key was to add JavaScript to the PDF file that silently print itself.
To do this I open the PDF with acrobat reader in chrome, that allow me to execute the script (with the proper permissions).
But as it was announced this solution won't work after chrome 45 because the npapi issue.
I guess a possible solution could be to use the recently release printProvider of chrome extensions.
Nevertheless I can't imagine how to fire any of the printProvider events.
So the question is: Is ok to think in chrome extensions to make a silent print web application, and how can I fire and handle a print job for an embedded PDF of a HTML Page.
Finally I reached an acceptable solution for this problem, as I couldn't find it out there, but read to many post with the same issue I will leave my solution here.
So first you need to add your printer to the Google Cloud Print and then you will need to add a proyect to the Google Developers Console
Then add this script and any time you need to print something execute the print() function. This method will print the document indicated in the content
The application will ask for your permission once to manage your printers.
function auth() {
gapi.auth.authorize({
'client_id': 'YOUR_GOOGLE_API_CLIENT_ID',
'scope': 'https://www.googleapis.com/auth/cloudprint',
'immediate': true
});
}
function print() {
var xhr = new XMLHttpRequest();
var q = new FormData()
q.append('xsrf', gapi.auth.getToken().access_token);
q.append('printerid', 'YOUR_GOOGLE_CLOUD_PRINTER_ID');
q.append('jobid', '');
q.append('title', 'silentPrintTest');
q.append('contentType', 'url');
q.append('content',"http://www.pdf995.com/samples/pdf.pdf");
q.append('ticket', '{ "version": "1.0", "print": {}}');
xhr.open('POST', 'https://www.google.com/cloudprint/submit');
xhr.setRequestHeader('Authorization', 'Bearer ' + gapi.auth.getToken().access_token);
xhr.onload = function () {
try {
var r = JSON.parse(xhr.responseText);
console.log(r.message)
} catch (e) {
console.log(xhr.responseText)
}
}
xhr.send(q)
}
window.addEventListener('load', auth);
<script src="https://apis.google.com/js/client.js"></script>
Anyway this script throw a 'Access-Control-Allow-Origin' error, even though this appears in the documentation... I couldn't make it work :(
Google APIs support requests and responses using Cross-origin Resource Sharing (CORS). You do not need to load the complete JavaScript client library to use CORS. If you want your application to access a user's personal information, however, it must still work with Google's OAuth 2.0 mechanism. To make this possible, Google provides the standalone auth client — a subset of the JavaScript client.
So to go throw this I had to install this chrome extension CORS. I'm sure that some one will improve this script to avoid this chrome extension.
You can register an Application to a URI Scheme to trigger the local application to print silently. The setting is pretty easy and straightforward. It's a seamless experience. I have posted the solution here with full example:
https://stackoverflow.com/a/37601807/409319
After the removal of npapi, I don't believe this is possible solely programmatically. The only current way I know to get chrome to print silently is using chrome kiosk mode, which is a flag (mode) you have to set when starting chrome.
Take a look at these SO posts:
Silent printing (direct) using KIOSK mode in Google Chrome
Running Chrome with extension in kiosk mode
This used to be possible using browser plugins (e.g. Java + NPAPI, ActiveX) but has been blacklisted by most browsers for several years.
If interested in modern solutions that use similar techniques, the architecture usually requires the following:
WebSocket, HTTP or Custom URI connection back to localhost
API that talks through web transport (JavaScript or custom URI scheme) to an app running locally.
A detail of projects (several of them are open source) that leverage these technologies are available here:
https://stackoverflow.com/a/28783269/3196753
Since the source code of these projects can vary (hundreds of lines to tens-of-thousands of lines), a code snippet would be too large unless a inquiring about a specific project's API.
Side note: Some technologies offer dedicated cloud resources, which add convenience at the expense of potential latency and privacy. At the time of writing this, the most popular "free" cloud solution -- Google Cloud Print -- is slated to be retired in December 2020.

SoundManager2 onid3() not firing

I'm building a simple Javascript jukebox using the latest SoundManager2 for audio playback, with local MP3 files being the source. I've got file loading and playing sorted, and at the moment I'm trying to get access to the ID3 info of these MP3 files, but the onid3() callback is not firing. I'm using Flash and have verified that ID3 info is present in the files. Below is my implementation of onid3():
function playNextSongInQueue()
{
// Get the first element of the songQueue array
var nextSongInQueue = songQueue.shift();
// Start playback from the queue
var jukeboxTune = soundManager.createSound({
id: 'currentTune',
url: 'audio/' + nextSongInQueue.name,
onload: function() {
this.play();
},
onid3: function() {
alert('ID3 present!');
},
onfinish: function() {
this.destruct(); // Destroy this sound on finish
songFinish(); // Run the songFinish() function, so decide what to do next
}
});
jukeboxTune.load();
//jukeboxTune.play(); // The jukebox running!
songPlaying = true; // Set songPlaying flag
updateSongQueueDisplay(); // Refresh the song queue display (for debug)
return nextSongInQueue.name;
}
The other callbacks work fine, but the onid3() alert never comes up. I even separated the load and play portions of audio playback to see if that helped. SoundManager spots that onid3() is there because it switches usePolicyFile to true - seeing as the MP3s are local I am assuming I don't need to worry about the cross-domain XML file.
Can anybody shed light on why this isn't working? I've scoured Google looking for implementations that work but have come up with nothing helpful. I've seen Jacob Seidelin's pure Javascript workaround but would rather stick with SoundManager if possible, and would rather not use a PHP solution.
Thanks,
Adam
This problem is probably too esoteric for any solid answers, so I decided to investigate possible Javascript solutions outside the SM2 library.
I started with Nihilogic's library for reading ID3v1 tags (at http://blog.nihilogic.dk/2008/08/reading-id3-tags-with-javascript.html), but moved to antimatter15's js-id3v2 library (https://github.com/antimatter15/js-id3v2) as it can read ID3v2 tags. Adapting code from the provided example I have managed to successfully parse the main tags required when the MP3s are loaded via the <input> control.
For local files, i speak of "user local files" (not "server" local files) i get some success with id3v2.js
To get ID3, SM2 need a cross domain on the mp3 host, if it's another domain.
Plus i have encountered difficulties with Soundcloud as they redirect MP3 to dynamic Amazon S3 storage... so i have to do a PHP script to guest final URL and then SM2 can get proper crossdomain.xml (Check https://getsatisfaction.com/schillmania/topics/displaying_waveformdata_of_soundcloud_hosted_track_prompts_securityerror_error_2122 )
The problem is both S3 links and local user files (blob) do have a short expiration delay.
Good luck !

Categories

Resources