I'm writing a video encoder/server to serve video to a web application intended to run on an iPad. The iPad uses an HTML5 video tag to retrieve and decode the video, and I'm running into issues where the encoded video isn't being decoded correctly.
Is there anything like a system log on the iPad where I can find any information about what the video decoder finds objectionable in my bitstream, or any other way of getting some visibility into the decoding process?
Older versions of IOS allowed you to turn on the Safari debug console (settings ->safari->advanced -> debug console). This was handy for logging errors etc. If you are a mac user apparently there is a nice interface for doing so.
If you have desktop Safari you can also fake the user agent see: http://www.dummies.com/how-to/content/how-to-activate-user-agent-switcher-in-safari.html this will allow you to use web debug tools to see whats going on.
Alternatively you can create a 'Debug' panel in your webapp and hijack the console.log function so you can see errors etc.
Example:
<div id="debug-info"></div>
<script>
(function(){
var oldLog = console.log;
console.log = function (message) {
// DO MESSAGE HERE.
oldLog.apply(console, arguments);
$('#debug-info').prepend('<p>'+message+'</p>')
};
})();
</script>
Related
Is there any way to open a window and playing a youtube video inside my hololens app?
I did search about opening youtube video page, but it will open outside of my, i want player to be inside of my app.
For HoloLens 1, the suggestions provided by Hernando in the comments are good.
I wanted to also share that it is possible to do this on HoloLens 2 and Windows Mixed Reality simply by launching a URI. This will launch a flat application window directly in your unity app. For example, have a look at "the Launch External Apps pull request" which shows the behavior in the HandInteractionExamples scene (available in MRTK RC2 release, or latest mrtk_development branch).
The code to launch an external URI within your app is as follows:
#if WINDOWS_UWP
UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
{
bool result = await global::Windows.System.Launcher.LaunchUriAsync(new System.Uri("https://youtu.be/SB-qEYVdvXA"));
}, false);
#else
Application.OpenURL("https://youtu.be/SB-qEYVdvXA");
#endif
This code was taken from LaunchUri.cs, modified to just launch a YouTube video.
As of iOS 12, navigator.mediaDevices.getUserMedia() is returning an error in Safari.
To recreate this, open iPhone Web Inspector, then run this snippet in the console:
var constraints = { audio: true, video: { width: 1280, height: 720 } };
navigator.mediaDevices.getUserMedia(constraints)
.then(function() {
console.log('getUserMedia completed successfully.');
})
.catch(function(error) {
console.log(error.name + ": " + error.message);
});
You'll see that this runs successfully in desktop browsers, and in iOS 11 Safari, but fails in iOS 12 Safari.
NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.
Any idea why?
note: This is happening prior to the user being asked if their camera can be accessed, ruling out the possibility of it being because the user denied permission.
Setting these three attributes before calling getUserMedia solved the problem for me:
video.setAttribute('autoplay', '');
video.setAttribute('muted', '');
video.setAttribute('playsinline', '');
For some reason video.setAttribute() works but trying to assign the value directly to the video object for example video.muted = '' does not.
Also it appears that it's not necessary to call video.play().
Simply setting the video.srcObject to the stream returned by getUserMedia worked for me.
This medium post has a link to a working demo & source code.
There are two possible reasons for immediate NotAllowedError at the moment:
1. getUserMedia requries https
Safari seems to require https for camera and mic access, both in iOS and OSX.
With an https link, iOS Safari 12 works for me; same link in http gets NotAllowedError.
Chrome has the same requirement. This is consistent with the direction of the specification, which recently has restricted getUserMedia to secure contexts. Browsers who have yet to update, still expose navigator.mediaDevices in http, but getUserMedia always rejects with NotAllowedError.
In the future, expect browsers to remove mediaDevices entirely in http, to comply with the spec.
2. getUserMedia requires feature policy in cross-origin iframes.
This appears new with Safari 12. In iframes, getUserMedia's feature policy is off by default for cross-origin content.
This works for me:
<iframe
allow="camera;microphone"
src="https://webrtc.github.io/samples/src/content/getusermedia/gum/">
</iframe>
This doesn't work:
<iframe src="https://webrtc.github.io/samples/src/content/getusermedia/gum/">
</iframe>
...and in addition to failing with NotAllowedError, Safari warns in web console:
The top-level frame has prevented a document with a different security origin to
call getUserMedia.
This is also a recent update to the spec.
Turns out my particular issue was a bug in 12.01. Every device with that version had the issue, and as soon as I updated them to a newer version it went away.
I am using cordova-plugin-wkwebview-engine in a phonegap app to open a web page:
ref = window.open(url, '_self', 'location=no,toolbar=no');
All is working fine thus far, page displays properly, iOS log says the app is using wkWebView, and the display is much faster than when using UIWebView.
I want to send a postmessage from the page in the WkWebView and handle the message in my index.js running on the device. From the WkWebView issues pages, I copied the following code into the webpage:
<button type="button" name="button" onclick="sayHello()">Say hello</button>
<script type="text/javascript">
window.addEventListener("message",function(event){
console.log("IFRAME");
console.log(event);
}, false);
function sayHello(){
parent.postMessage("Hello!","*")
}
</script>
I compile/install the app and run. I tap the button and the debugger says that parent.postMessage executes. So now I'm ready to code the message handler on the device side.
The copied code obviously assumes that it is running inside an iframe on what I assume is the main index.html launched by Phonegap.
Before I try the iframe approach, I want to know: Has anyone has found a way to use postmessage to communicate between index.js and the WkWebView WITHOUT resorting to iframes?
For example, my window.open creates object 'ref'. Can I simply add an event listener on 'ref' to capture the message? If so, then I suspect I'll need to use something other than 'parent' when calling 'parent.postmessage'. What would that be?
Suggestions are good, examples are better.
Note that this app has not yet required delving into native code... Phonegap Build has been doing just fine to create my installables. I'd like to keep it that way if possible.
How to make deferred deep linking and generate unique mobile signature. I try using IP Address, screen-size, OS version, device name but still not get succeed.
The comment links to a great answer, certainly. High level, here are the steps:
Your links should point to a page on your site that collects a digital fingerprint
That page should collect, at minimum, IP address, OS, OS version and screen size (width and height). Should send to your server and place in a persistent store. Redis works great for this because of its fast lookup times. Also record some sort of unique identifier for which link was clicked (that could be the value in redis).
Then redirect to the app (URI scheme) and have a fallback to the App Store/Play Store. Here's an example for iOS. The beauty of the iframe is that it kills the alertView if the app is not installed. This should be placed in the body:
<script type="text/javascript">
window.onload = function() {
// Deep link to your app goes here
document.getElementById("l").src = "my_app://";
setTimeout(function() {
// Link to the App Store should go here -- only fires if deep link fails
window.location = "https://itunes.apple.com/us/app/my.app/id123456789?ls=1&mt=8";
}, 500);
};
</script>
<iframe id="l" width="1" height="1" style="visibility:hidden"></iframe>
When a user opens your app, send up the same combination of params to your servers and search your persistent store to see if this device recently clicked on a link. Send a response down to your app (e.g. { link_id: "1234" } or { link_id: -1 }) Your app logic should then respond based on which link was clicked.
Hopefully this makes sense. We do this at Branch and can assure you that it's harder than it looks to roll this solution from scratch. There are a ton of edge cases introduced by individual browsers and even individual apps (e.g. when links are shared to Twitter and clicked on in the native Android app). But at it's core fingerprinting is relatively simple. Hopefully the above was helpful.
I have a desktop/mobile web app that needs to display a pdf stream on the target device. I now have this working on the desktop using the jquery dialog. For mobile tho...my html View page has the following link:
View PDF
And that correctly takes me into the Controller Action:
public ActionResult PdfView(string id = "")
{
PayStubDataEntity ps = PayStubAccess.GetPayStubByID(new Guid(id), new Guid(Session["Session_Application_UserID"].ToString()));
WebHelper.SetHeadersForDownload(System.Web.HttpContext.Current.Response, "application/pdf", "PayStub.pdf", false);
MemoryStream pdfMemoryStream = SendPayStubToBrowserAsPdf(ps);
//WebHelper.SendFile(System.Web.HttpContext.Current.Response, "application/pdf", "PayStub.pdf", false, pdfMemoryStream);
return File(pdfMemoryStream, "application/pdf");
}
But nothing ever shows up on my iphone emulator (electric plum). No error messages. I am not sure where the output s/b going or how to view it? Any ideas would be most appreciated.
We have this same issue with android phones and there can be two issues going on. If the website uses ssl and the phone you are on does not accept it as a valid ssl, it will say downloading pdf in the manager, but it never completes a download.
The second issue is the file you are sending to the phone needs to be named in order to download properly to the phone.
Ex: return File(pdfMemoryStream, "application/pdf", fileDownloadName:"PayStub.pdf");
I would suggest using Google Chrome for phone emulation. When you change the settings, it will behave similarly to the phone and you can debug easily.
For example, when I set Google Chrome to the mobile phone user agent Android 4.0.2, it will download the pdf, instead of displaying within the web browser. When it does that, I know it is working locally. It also has iPhone emulation.