UWP MediaCapture initialization fails - c#

I'm developing a WPF application where I'm recording audio data with the Windows.Media.Capture.MediaCapture class. It's working if I initialize with or without parameters:
var mediaCapture = new MediaCapture();
await mediaCapture.InitializeAsync();
or I can add which microphone to use (if there are more than one):
var allAudioDevices = await DeviceInformation.FindAllAsync(DeviceClass.AudioCapture);
DeviceInformation microphone = allAudioDevices.FirstOrDefault();
MediaCaptureInitializationSettings mediaInitSettings = new MediaCaptureInitializationSettings {
AudioDeviceId = microphone.Id,
StreamingCaptureMode = StreamingCaptureMode.Audio
};
await _mediaCapture.InitializeAsync(mediaInitSettings);
The problem comes when I run my app as a UWP application (with desktop bridge). As a UWP app when it calls the InitializeAsync() method, it always throws an exception with the following (verbose :) ) error message: Element not found. The DeviceInformation object of the microphone is found correctly, so something happens during the initialization of the MediaCapture.
The Microphone capability is set in the manifest file of the bridge project.
What am I doing wrong? I'm also open to use other methods to record the voice.

I figured out that if I run the initialization on the UI thread, it works well:
await Application.Current.Dispatcher.InvokeAsync(async () => {
await mediaCapture.InitializeAsync();
});

Related

Custom NSSM windows service cannot access webcam, windows,

So I can't find any information on this one and was wondering if anyone has encountered the same issue.
I'm using "c#" , with "Windows.Media.Capture" in a dot net core 3.1 build.
When I use the build as an exe, I can communicate with the webcam and acquire images and record video.
However when I bundle the exe into a service( i'm using NSSM), I get an Unauthorized access exception on initialization.
I have changed the camera privacy settings to allow all desktop apps etc to use the camera.
I cannot find an option for services to access the camera. I have also changed the registry setting and created a group policy, but with no luck.
I believe it is a privacy setting of some form as the application works fine when run as a desktop application.
Any help would be greatly appreciated.
Thanks
Rob
Also here is the initialization code I'm using (straight from the Microsoft website). Just for transparency.
/// <summary>
/// Initializes the MediaCapture, registers events, gets camera device information for mirroring and rotating, starts preview and unlocks the UI
/// </summary>
/// <returns></returns>
private async Task InitializeCameraAsync()
{
Debug.WriteLine("InitializeCameraAsync");
var picturesLibrary = await
StorageLibrary.GetLibraryAsync(KnownLibraryId.Pictures);
// Fall back to the local app storage if the Pictures Library is not available
_captureFolder = picturesLibrary.SaveFolder ?? ApplicationData.Current.LocalFolder;
if (_mediaCapture == null)
{
// Attempt to get the back camera if one is available, but use any camera device if not
var cameraDevice = await FindCameraDeviceByPanelAsync(Windows.Devices.Enumeration.Panel.Back);
if (cameraDevice == null)
{
Debug.WriteLine("No camera device found!");
return;
}
// Create MediaCapture and its settings
_mediaCapture = new MediaCapture();
// Register for a notification when video recording has reached the maximum time and when something goes wrong
// _mediaCapture.RecordLimitationExceeded += MediaCapture_RecordLimitationExceeded;
// _mediaCapture.Failed += MediaCapture_Failed;
var settings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id };
settings.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.Video;
// Initialize MediaCapture
try
{
await _mediaCapture.InitializeAsync(settings);
_isInitialized = true;
}
catch (UnauthorizedAccessException)
{
Debug.WriteLine("The app was denied access to the camera");
throw new Exception("The app was denied access to the camera");
}
}
}
I believe it is a privacy setting of some form as the application works fine when run as a desktop application.
It's probably either User Interface Privilege Isolation or Session 0 Isolation. There are a few Vista-era hacks to try to get around them that may or may not work on Win10, but none of those hacks were ever recommended and would certainly be frowned on these days.
The best solution is probably to replace the Win32 service with an auto-started app. If you absolutely need a Win32 service, then you'll probably need to use a lower-level API.

Getting SpeechRecognizer to correctly utilize timeouts for EndSilenceTimeout

I'm trying to re-purpose a code-snippet for a UWP app using Windows.Media.SpeechRecognition's SpeechRecognizer class.
The problem is that it doesn't seem to utilize the timeout that I set for EndSilenceTimeout -- yet both BabbleTimeout and InitialSilenceTimeout appear to be working just fine. Basically, a 1-2 second pause will always end the session, and I'm trying to figure out how to fix or work around this.
I've tried with both RecognizeAsync and RecognizeWithUIAsync but neither made a difference.
private async void StartRecognizing()
{
var speechRecognizer = new SpeechRecognizer();
speechRecognizer.Timeouts.EndSilenceTimeout = TimeSpan.FromSeconds(10);
speechRecognizer.Timeouts.BabbleTimeout = TimeSpan.FromSeconds(10);
speechRecognizer.Timeouts.InitialSilenceTimeout = TimeSpan.FromSeconds(10);
await speechRecognizer.CompileConstraintsAsync();
SpeechRecognitionResult speechRecognitionResult = await speechRecognizer.RecognizeAsync();
var messageDialog = new Windows.UI.Popups.MessageDialog(speechRecognitionResult.Text, "Text spoken");
await messageDialog.ShowAsync();
}
To test this, just make a new UWP app in Visual Studio and grant yourself permission to access the microphone in the package app manifest; additionally you'll need to make sure your OS itself allows for this in the Speech, inking, & typing settings on Windows 10 v1803.

Windows 10 Universal App - Geofence Background task not being triggered

I'm trying to create a Windows UAP (C#) to constantly log location data in a background task, for now all I'm trying to do is start the background task off of a geofence trigger.
I've followed a lot of guides for how to do this, I've added the entry point in the Package.appxmanifest to "BackgroundTask.LocationBackgroundTask" and selected the location property.
I'm then registering the task using the following:
var result = await BackgroundExecutionManager.RequestAccessAsync();
var builder = new BackgroundTaskBuilder();
builder.Name = BackgroundTaskName;
builder.TaskEntryPoint = BackgroundTaskEntryPoint;
builder.SetTrigger(new LocationTrigger(LocationTriggerType.Geofence));
var geofenceTask = builder.Register();
I use the following code to verify if the background task is registered and it returns true to indicate that the task is registered:
public bool IsTaskRegistered()
{
var Registered = false;
var entry = BackgroundTaskRegistration.AllTasks.FirstOrDefault(keyval => keyval.Value.Name == BackgroundTaskName);
if (entry.Value != null)
Registered = true;
return Registered;
}
The problem I'm having is that the Run method in the background task is just not getting triggered.
To verify the background task itself is all good, I swapped out the trigger type for builder.SetTrigger(new SystemTrigger(SystemTriggerType.PowerStateChange, true)); (and updated the Package.appxmanifest to have the system event property). This then worked fine as the background task was triggered as I'd expect when I unplugged the power source from my laptop.
The other thing to note is that when debugging I don't see the background task under the Lifecycle Events whereas I do when testing with the SystemTrigger.
The problem does therefore seem to be specific to the geofence triggering. I'm starting to pull my hair out a bit over this so would be grateful for any suggestions.

Async calls referencing Devices are not completing

I'm working on a Windows Store App which will access the device's microphone. However, when I attempt to work with the media devices, execution gets lost in the await somewhere. So far, I've noticed this on the following three scenarios:
var devices = await DeviceInformation.FindAllAsync(DeviceClass.AudioCapture); // never returns
var inputDeviceId = MediaDevice.GetDefaultAudioCaptureId(AudioDeviceRole.Communications);
var device = await DeviceInformation.CreateFromIdAsync(inputDeviceId); // never returns
var mediaCapture = new MediaCapture();
var settings = new MediaCaptureInitializationSettings
{
StreamingCaptureMode = StreamingCaptureMode.Audio,
AudioProcessing = AudioProcessing.Default,
MediaCategory = MediaCategory.Other,
AudioDeviceId = inputDeviceId,
VideoDeviceId = "",
};
try
{
await _mediaCapture.InitializeAsync(settings); // never returns
}
catch (Exception ex)
{
throw new Exception("Microphone is not available.", ex);
}
I am using Visual Studio 2013 Update 2 RC and developing on a Surface Pro 2. I have tried debugging in Local Machine and Simulator modes but both with the same results. I do have the Microphone capability selected in the App's manifest. I expect the OS should be prompting me for access to the microphone device but I am not presented with that dialog.
Any help is greatly appreciated! Thanks in advance.
I suspect that further up your call stack, you are blocking the UI thread by calling Task.Wait or Task<T>.Result. This will cause a deadlock, as I explain on my blog.
The reason this deadlocks is because await captures a "context" (in this case, the UI context) and will use that to resume its async method. However, if the UI thread is blocked, then the async method cannot continue.

launching a uri from my app in half screen mode C# windows 8.1 app

I'm trying to launch a uri from my windows 8.1 app but can't get it to launch in UseHalf mode
I researched and found that it should be done like this
LauncherOptions lo = new LauncherOptions();
lo.DesiredRemainingView = ViewSizePreference.UseHalf;
lo.DisplayApplicationPicker = true;
await Windows.System.Launcher.LaunchUriAsync(new Uri("http://www.youtube.com"),lo);
but it keeps launching the web browser in full screen
I read that the launch depends on many variables and it is not insured that these settings will be applied
my question is there a way to insure that my app and the browser will open side by side in half screen mode?
It have to work:
Uri uri = new Uri("http://www.youtube.com");
LauncherOptions options = new LauncherOptions
{
DesiredRemainingView = ViewSizePreference.UseHalf
};
await Launcher.LaunchUriAsync(uri, options);
If not, please try this long code:
ApplicationView currentAppView = ApplicationView.GetForCurrentView();
CoreApplicationView newCoreAppView = CoreApplication.CreateNewView();
newCoreAppView.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal,
async () =>
{
// This executes on the new dispatcher so I assume that Window.Current and so on
// reflects the new Window associated with that dispatcher rather than the original
// dispatcher.
Window newWindow = Window.Current;
ApplicationView newAppView = ApplicationView.GetForCurrentView();
await ApplicationViewSwitcher.TryShowAsStandaloneAsync(
newAppView.Id,
ViewSizePreference.UseHalf,
currentAppView.Id,
ViewSizePreference.UseHalf);
});
from Here.
Well after consulting the msdn developers forum it turns out this is the only way to do it
and there is no way for an app to force this kind of behavior the result of this code depends on the setting of the browser and many other variables

Categories