Choose default webcam for node-webkit - google-chrome

I have a node-webkit application that is using RecordRTC to capture a snippet of video. I'm running the application on a Windows Surface Pro 3, and need the front-facing webcam to be used instead of the back-facing one. I know there is a setting in Chrome to change the default webcam, but how do I configure this in node-webkit?

I don't have a device to test this on but it should work. I believe mobile devices will return either 'user' or 'environment' to determine if it's front or rear facing.
var devices = function (devices) {
for (var i = 0; i !== devices.length; ++i) {
var camera = devices[i];
if (camera.kind === 'video' && camera.facing === 'user') {
createStream(camera.id);
} else {
console.log('No front facing camera');
}
}
}
var createStream = function(id) {
var settings = {video: {optional: {sourceId: id} }};
navigator.webkitGetUserMedia(settings, successCallback, errorCallback);
};
MediaStreamTrack.getSources(devices);
This basically loops through all of the available devices and checks if it's a video source and that it is facing the user. It will then use the id of that device to create the media stream.

Related

Offline Ready using Service worker

I built an offline first app using the appcache a while ago and wanted to convert it to using the service-worker (my clients all use the latest chrome so I don't have any browser compatibility issues).
I'm using sw-precache to generate a service-worker that caches my local assets (specifically, my html/css/fonts and also some js) and it looks like when the service-worker installs, it does successfully add all the assets to cache storage and it does successfully start (install and activate both fire and complete successfully. And I have the self.skipWaiting() at the end of the install event to start the service-worker (which it does successfully as well)).
The issue is that the "fetch" event doesn't seem to ever fire. As such, if I go offline or open a browser (while already offline) and navigate to the site, I get the Chrome offline dinosaur. When I look at the network tab, it looks like the browser is trying to hit a server to retrieve the pages. I'm not sure what I'm doing wrong and I didn't touch the fetch method that was generated by the sw-precache utility...so I'm not sure what I'm missing. Any help would be greatly appreciated. My fetch event is below:
self.addEventListener('fetch', function(event) {
if (event.request.method === 'GET') {
var urlWithoutIgnoredParameters = stripIgnoredUrlParameters(event.request.url,
IgnoreUrlParametersMatching);
var cacheName = AbsoluteUrlToCacheName[urlWithoutIgnoredParameters];
var directoryIndex = 'index.html';
if (!cacheName && directoryIndex) {
urlWithoutIgnoredParameters = addDirectoryIndex(urlWithoutIgnoredParameters, directoryIndex);
cacheName = AbsoluteUrlToCacheName[urlWithoutIgnoredParameters];
}
var navigateFallback = '';
// Ideally, this would check for event.request.mode === 'navigate', but that is not widely
// supported yet:
// https://code.google.com/p/chromium/issues/detail?id=540967
// https://bugzilla.mozilla.org/show_bug.cgi?id=1209081
if (!cacheName && navigateFallback && event.request.headers.has('accept') &&
event.request.headers.get('accept').includes('text/html') &&
/* eslint-disable quotes, comma-spacing */
isPathWhitelisted([], event.request.url)) {
/* eslint-enable quotes, comma-spacing */
var navigateFallbackUrl = new URL(navigateFallback, self.location);
cacheName = AbsoluteUrlToCacheName[navigateFallbackUrl.toString()];
}
if (cacheName) {
event.respondWith(
// Rely on the fact that each cache we manage should only have one entry, and return that.
caches.open(cacheName).then(function(cache) {
return cache.keys().then(function(keys) {
return cache.match(keys[0]).then(function(response) {
if (response) {
return response;
}
// If for some reason the response was deleted from the cache,
// raise and exception and fall back to the fetch() triggered in the catch().
throw Error('The cache ' + cacheName + ' is empty.');
});
});
}).catch(function(e) {
console.warn('Couldn\'t serve response for "%s" from cache: %O', event.request.url, e);
return fetch(event.request);
})
);
}
}
});

chrome app bluetooth api

I am trying to get the list of bluetooth devices paired with my windows 7 machine. I took the code from here https://developer.chrome.com/apps/app_bluetooth
var device_names = {};
var updateDeviceName = function(device) {
device_names[device.address] = device.name;
};
var removeDeviceName = function(device) {
delete device_names[device.address];
}
// Add listeners to receive newly found devices and updates
// to the previously known devices.
chrome.bluetooth.onDeviceAdded.addListener(updateDeviceName);
chrome.bluetooth.onDeviceChanged.addListener(updateDeviceName);
chrome.bluetooth.onDeviceRemoved.addListener(removeDeviceName);
// With the listeners in place, get the list of devices found in
// previous discovery sessions, or any currently active ones,
// along with paired devices.
chrome.bluetooth.getDevices(function(devices) {
for (var i = 0; i < devices.length; i++) {
updateDeviceName(devices[i]);
}
});
// Now begin the discovery process.
chrome.bluetooth.startDiscovery(function() {
// Stop discovery after 30 seconds.
setTimeout(function() {
chrome.bluetooth.stopDiscovery(function() {});
}, 30000);
});
In the manifest file i gave bluetooth permission
"bluetooth": {
"uuids": [ "1105", "1106" ]
}
But getDevices always return empty list even after startDiscovery is initiated.
I have enabled bluetooth in my mobile and paired it with my windows 7 as well even then its not showing the paired device when getdevice is called.
The chrome app is frameless and running in developer mode.
BTW my windows bluetooth UI shows my mobile device and some other devices as well
I will be grateful if anyone can suggest where i am making a mistake?

how to turn on flashlight on windows phone 8.1

I created project based on:
https://github.com/Microsoft/real-time-filter-demo/tree/master/RealtimeFilterDemoWP
My question is how to enable flash light (torch) on WP8.1
Should I use MediaCapture() ?
var mediaDev = new MediaCapture();
await mediaDev.InitializeAsync();
var videoDev = mediaDev.VideoDeviceController;
var tc = videoDev.TorchControl;
if (tc.Supported)
{
if (tc.PowerSupported)
tc.PowerPercent = 100;
tc.Enabled = true;
}
when I used it it crash on
var videoDev = mediaDev.VideoDeviceController;
by unhandled exception
How to add flashlight to this sample project ?
You haven't initialized the MediaCaptureSettings, thus when you attempt to initialize the videoController the exception occurs. You need to initialize the settings, let MediaCapture know what device you'd like to use, and setup the VideoDeviceController. In addition, for Windows Phone 8.1 camera drivers, some require you to start the preview, or others require you to start video recording to turn on flash. This is due to the flash being tightly coupled with the camera device.
Here's some general code to give you the idea. *Disclaimer, this is untested. Best sure to call this in an async Task method so you can assure the awaited calls complete before you attempt to toggle the Torch Control property.
private async Task InitializeAndToggleTorch()
{
// Initialize Media Capture and Settings Objects, mediaCapture declared global outside this method
mediaCapture = new MediaCapture();
MediaCaptureInitializationSettings settings = new MediaCaptureInitializationSettings();
// Grab all available VideoCapture Devices and find rear device (usually has flash)
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
DeviceInformation device = devices.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back);
// Set Video Device to device with flash obtained from DeviceInformation
settings.VideoDeviceId = device.Id;
settings.AudioDeviceId = "";
settings.PhotoCaptureSource = PhotoCaptureSource.VideoPreview;
settings.StreamingCaptureMode = StreamingCaptureMode.Video;
mediaCapture.VideoDeviceController.PrimaryUse = Windows.Media.Devices.CaptureUse.Video;
// Initialize mediacapture now that settings are configured
await mediaCapture.InitializeAsync(settings);
if (mediaCapture.VideoDeviceController.TorchControl.Supported)
{
// Get resolutions and set to lowest available for temporary video file.
var resolutions = mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.VideoRecord).Select(x => x as VideoEncodingProperties);
var lowestResolution = resolutions.OrderBy(x => x.Height * x.Width).ThenBy(x => (x.FrameRate.Numerator / (double)x.FrameRate.Denominator)).FirstOrDefault();
await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoRecord, lowestResolution);
// Get resolutions and set to lowest available for preview.
var previewResolutions = mediaCapture.VideoDeviceController.GetAvailableMediaStreamProperties (MediaStreamType.VideoPreview).Select(x => x as VideoEncodingProperties);
var lowestPreviewResolution = previewResolutions.OrderByDescending(x => x.Height * x.Width).ThenBy(x => (x.FrameRate.Numerator / (double)x.FrameRate.Denominator)).LastOrDefault();
await mediaCapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, lowestPreviewResolution);
// Best practice, you should handle Media Capture Error events
mediaCapture.Failed += MediaCapture_Failed;
mediaCapture.RecordLimitationExceeded += MediaCapture_RecordLimitationExceeded;
}
else
{
// Torch not supported, exit method
return;
}
// Start Preview
var captureElement = new CaptureElement();
captureElement.Source = mediaCapture;
await mediaCapture.StartPreviewAsync();
// Prep for video recording
// Get Application temporary folder to store temporary video file folder
StorageFolder tempFolder = ApplicationData.Current.TemporaryFolder;
// Create a temp Flash folder
var folder = await tempFolder.CreateFolderAsync("TempFlashlightFolder", CreationCollisionOption.OpenIfExists);
// Create video encoding profile as MP4
var videoEncodingProperties = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto);
// Create new unique file in the Flash folder and record video
var videoStorageFile = await folder.CreateFileAsync("TempFlashlightFile", CreationCollisionOption.GenerateUniqueName);
// Start recording
await mediaCapture.StartRecordToStorageFileAsync(videoEncodingProperties, videoStorageFile);
// Now Toggle TorchControl property
mediaCapture.VideoDeviceController.TorchControl.Enabled = true;
}
Phew! That's a lot of code just to toggle flash huh? Good news is this is fixed in Windows 10 with new Windows.Devices.Lights.Lamp API. You can do same work in just a few lines of code:
Windows 10 Sample for Windows.Devices.Lights.Lamp
For reference, check this thread:
MSDN using Win8.1 VideoDeviceController.TorchControl

CaptureElement preview not available sometimes

I have problem with initialization camera on Windows Universal Apps. This code works and never throw any exception, but i have wrapped it into dialog control. Problem is sometimes (1/10 dialog openings) i don't see preview from camera. Have you any idea how to fix that or at least check if preview is displayed?
private async Task InitCameraAsync()
{
var devices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
var backCam = devices.FirstOrDefault(q => q.EnclosureLocation != null && q.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back);
var mediaCapture = new MediaCapture();
if (backCam != null)
{
await mediaCapture.InitializeAsync(new MediaCaptureInitializationSettings()
{
VideoDeviceId = backCam.Id,
AudioDeviceId = String.Empty,
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview
});
}
else
{
await mediaCapture.InitializeAsync();
}
CameraControl.Source = mediaCapture;
SetImageEncodingProperties(); // get encoding properties to save images
await SetPreviewResolutionAsync();
await CameraControl.Source.StartPreviewAsync();
}
}
Are you sure that you are calling the function from the UI thread to access the camera for the API to run reliably?
https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.core.coredispatcher.runasync.aspx

Adobe DPS HTML Alert when tapping link that no internet connection available

I created an HTML page that has some external links, when the user taps the external link how can I prompt the user that there is no internet connection available? Thanks.
You will probably need some JavaScript and Adobe's store api (for banners or store) or reading api (for html articles or web view in folios). The api provides the singleton object adobeDPS.deviceService which can tell you if the device is online or not. Additionally it provides a signal to indicate a change.
For each link element you register an onclick event handler that checks online state and either passes the click through or catches it and gives a message to the user.
The following code could work:
<script src="js/AdobeLibraryAPI.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", myLinkChecker.register, false);
var myLinkChecker = {
register: function(){
if (typeof(adobeDPS) !== 'object') {
console.log("Adobe Library not loaded :-(");
this.check = function() { return true } // Fallback
}
var linkList = document.querySelectorAll("a, map > area");
for (var i=0; i < linkList.length; i++){
var e = linkList[i];
if (e.hasAttribute('href'))
e.addEventListener('click', myLinkChecker.check, false);
}
},
check: function(ev){
if (adobeDPS.deviceService.isOnline) { // let <a> process the click
console.log("online");
return true
} else { // cancel click event and show message
event.stopPropagation();
event.preventDefault();
alert("Sorry, your device is not online")
return false;
}
}
}
</script>
Remote debugging html in DPS apps can be done using iOS developer apps and desktop Safari, or Android apps with Google Chrome.