Turn on torch with MediaCapture on Windows Phone Silverlight 8.1 - c#

My problem is quite simple, I cannot turn on the flash light with the MediaCapture API from windows phone 8.1. (I succedded with the 8.0 API)
I built a very simple project with 2 buttons, one to toggle the FlashControl and the other one to toggle TorchControl.
There is no crash, no exception. My phones support FlashControl and TorchControl. I also debug step-by-step and everything looks good, values are changed when buttons are clicked.
Here is my code:
MediaCapture m_captureManager;
public MainPage()
{
InitializeComponent();
}
private static async Task<DeviceInformation> GetCameraID(Windows.Devices.Enumeration.Panel desiredCamera)
{
DeviceInformation deviceID = (await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture))
.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredCamera);
if (deviceID != null) return deviceID;
else throw new Exception(string.Format("Camera {0} doesn't exist", desiredCamera));
}
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);
m_captureManager = new MediaCapture();
await m_captureManager.InitializeAsync(new MediaCaptureInitializationSettings
{
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview,
AudioDeviceId = string.Empty,
VideoDeviceId = cameraID.Id
});
}
private void button_ClickTorch(object sender, RoutedEventArgs e)
{
var torch = m_captureManager.VideoDeviceController.TorchControl;
if (torch.Supported)
{
if (torch.Enabled)
torch.Enabled = false;
else
torch.Enabled = true;
}
}
private void button_ClickFlash(object sender, RoutedEventArgs e)
{
if (captureManager.VideoDeviceController.FlashControl.Supported)
{
if (captureManager.VideoDeviceController.FlashControl.Enabled)
captureManager.VideoDeviceController.FlashControl.Enabled = false;
else
captureManager.VideoDeviceController.FlashControl.Enabled = true;
}
}
It's a simple piece of code and I cannot make it works... I was quite desperate so I tried to toggle by using an intermediate object and without, as you can see, but it did not change the result (which is in conformity).

I finally found out what was wrong. To be able to use camera services, we have to start a preview.
Since with Silverlight we can’t use a CaptureElement, we have to use a CustomPreviewSink with a VideoBrush
This is how to do it ( from microsoft doc)
private async void StartPreview()
{
previewSink = new Windows.Phone.Media.Capture.MediaCapturePreviewSink();
// List of supported video preview formats to be used by the default preview format selector.
var supportedVideoFormats = new List<string> { "nv12", "rgb32" };
// Find the supported preview format
var availableMediaStreamProperties = mediaCaptureManager.VideoDeviceController.GetAvailableMediaStreamProperties(
Windows.Media.Capture.MediaStreamType.VideoPreview)
.OfType<Windows.Media.MediaProperties.VideoEncodingProperties>()
.Where(p => p != null
&& !String.IsNullOrEmpty(p.Subtype)
&& supportedVideoFormats.Contains(p.Subtype.ToLower()))
.ToList();
var previewFormat = availableMediaStreamProperties.FirstOrDefault();
// Start Preview stream
await mediaCaptureManager.VideoDeviceController.SetMediaStreamPropertiesAsync(
Windows.Media.Capture.MediaStreamType.VideoPreview, previewFormat);
await mediaCaptureManager.StartPreviewToCustomSinkAsync(
new Windows.Media.MediaProperties.MediaEncodingProfile { Video = previewFormat }, previewSink);
// Set the source of the VideoBrush used for your preview
Microsoft.Devices.CameraVideoBrushExtensions.SetSource(viewfinderBrush, previewSink);
}
Add this piece of code to previous code and it will work. The important point is to start the preview before changing any parameters

Related

Xamarin MediaElement: setDataSource failed on URL

The following works ok:
using Plugin.FilePicker;
using Plugin.FilePicker.Abstractions;
using Xamarin.CommunityToolkit.Core;`
...
private void btnPlaySource_Clicked(object sender, EventArgs e)
{
FileData fileData = await CrossFilePicker.Current.PickFile();
if (fileData == null)
return; // user canceled file picking
mediaElement.Source = MediaSource.FromFile(fileData.FilePath);
mediaElement.Play();
}
But these lines throw an exception with a delay of ~7 secs (it's not immediately thrown):
private void btnPlayURL_Clicked(object sender, EventArgs e)
{
//http://docs.google.com/uc?export=open&id=XXXXXXXXXXXXXXXXXX
var fileURL = GetGDriveFileURL();
mediaElement.Source = MediaSource.FromUri(fileURL);
mediaElement.Play();
}
Java.Lang.RuntimeException: 'setDataSource failed: status = 0x80000000'
What could be the reason of the exception? The URL is 100% working, I tested it on a WPF application's MediaElement and it played fine. I also build the application for Android with Android API level 29 SDK.
<Grid><xct:MediaElement x:Name="mediaElement" Grid.Row="0" AutoPlay="False" ShowsPlaybackControls="True"/>
Some of the problems were solved using Xamarin.Essentials.FilePicker. It allows picking audio from Google Drive if it's connected to the Android device. Although, the problem with URL still remains.
//var fileResult = await App.PickAndShow(Xamarin.Essentials.PickOptions.Default);
//if (fileResult == null) return false;
public static async Task<string> PickAndShow(Xamarin.Essentials.PickOptions options)
{
try {
Xamarin.Essentials.FileResult result =
await Xamarin.Essentials.FilePicker.PickAsync(options);
if (result != null) {
// For certain types of files, like ".mp3"
if (result.FileName.EndsWith("mp3", StringComparison.OrdinalIgnoreCase) ||
result.FileName.EndsWith("wav", StringComparison.OrdinalIgnoreCase))
{
// for debug purposes
bool exists = File.Exists(result.FullPath);
}
}
return result.FullPath;
} catch (Exception ex) {
// The user canceled or something went wrong
}
return null;
}

NFC-reader on Win IOT: Pin ' is currently opened in an incompatible sharing mode

I am working on a NFC reader project based on Windows 10 IoT running on a Rasperry PI 3.
I use the library Mfrc522lib.cs found here: RFID RC522 Raspberry PI 2 Windows IOT.
I use an async task to wait for the card. It scans perfect the first time, but when I start the task again (for test puprose with button).
I get this:
Pin ' is currently opened in an incompatible sharing mode. Make sure this pin is not already in use by this application or another Application
Any idea?
public MainPage()
{
this.InitializeComponent();
startNFC();
}
public void startNFC()
{
var read = ReadNFCAsync();
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// Your UI update code goes here!
this.serial.Text = "Klar for å lese kortet ditt";
this.statusline.Fill = new SolidColorBrush(Colors.Green);
});
read.ContinueWith(prev => {
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() =>
{
// Your UI update code goes here!
this.serial.Text = prev.Result.ToString();
this.statusline.Fill = new SolidColorBrush(Colors.Orange);
});
});
}
public static async Task<String> ReadNFCAsync()
{
await Task.Delay(1000);
var mfrc = new Mfrc522();
await mfrc.InitIO();
while (true)
{
if (mfrc.IsTagPresent())
{
var uid = mfrc.ReadUid();
var serial= uid.ToString();
mfrc.HaltTag();
return serial;
}
}
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
startNFC();
}
This issue due to initializing GPIO pin is in use. Because every time you click the button the following line will be executed:
await mfrc.InitIO();
To solve this problem you can edit your code like this:
private Mfrc522 mfrc = new Mfrc522();
public static bool IsGpioInitialized = false;
public async Task ReadNFCAsync()
{
if (!IsGpioInitialized)
{
await mfrc.InitIO();
IsGpioInitialized = true;
}
}

MessageDialog confirmation does not work in Windows 10 Mobile but works in Windows 10

I want to ask for confirmation if the user wants to leave the page when the Back button (hardware or AppViewBackButton) is pressed using the following code in my App.xaml.cs
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
...
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
...
}
Private async void OnBackRequested(object sender, BackRequestedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame.Content.GetType() == typeof(GamePage))
{
var op = await ShowAsync("Do you want to exit?", "Exit?");
if (op == MessageBoxResult.OK)
{
rootFrame.GoBack();
e.Handled = true;
}
}
else
{
if (rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
}
}
}
public async Task<MessageBoxResult> ShowAsync(string messageBoxText, string caption)
{
MessageBoxResult result = MessageBoxResult.None;
MessageDialog md = new MessageDialog(messageBoxText, caption);
md.Commands.Add(new UICommand("OK",
new UICommandInvokedHandler((cmd) => result = MessageBoxResult.OK)));
md.Commands.Add(new UICommand("Cancel",
new UICommandInvokedHandler((cmd) => result = MessageBoxResult.Cancel)));
md.CancelCommandIndex = (uint)md.Commands.Count - 1;
var op = await md.ShowAsync();
return result;
}
The problem is var op = await md.ShowAsync(); does not await the result. The app showed the dialog briefly and without waiting for any input, just close the app.
I do not have my Windows 10 Mobile device to test at the moment so I am testing with the emulator. Is the problem with the emulator or the code?
This code works fine on my desktop though.

Flashlight App crashing every time in Windows Phone

I am trying to operate a flashlight app through TorchControl Class in Windows Phone application:
Here is my code
private static async Task<DeviceInformation> GetCameraID(Windows.Devices.Enumeration.Panel desiredCamera)
{
DeviceInformation deviceID = (await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture))
.FirstOrDefault(x => x.EnclosureLocation != null && x.EnclosureLocation.Panel == desiredCamera);
if (deviceID != null) return deviceID;
else throw new Exception(string.Format("Camera {0} doesn't exist", desiredCamera));
}
async private void Button_Click(object sender, RoutedEventArgs e)
{
var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);
var mediaDev = new MediaCapture();
await mediaDev.InitializeAsync(new MediaCaptureInitializationSettings
{
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview,
AudioDeviceId = String.Empty,
VideoDeviceId = cameraID.Id
});
var videoDev = mediaDev.VideoDeviceController;
var tc = videoDev.TorchControl;
if (tc.Supported)
tc.Enabled = true;
mediaDev.Dispose();
}
But the problem is that the app crashes everytime i click on the button second time. I have been told to use the mediaDev.Dispose() method but it is also not working.
Here's the exception:
A first chance exception of type 'System.Exception' occurred in
mscorlib.ni.dll WinRT information: The text associated with this error
code could not be found.
This is showing while the text in "initializeasync" is highlighted
MediaCapture will throw exception when it is re-initialized. To solve this issue, Just make sure you do not initialize MediaCapture twice when you navigate back to Camera page, or when you click the camera button.
MediaCapture mediacapture = new MediaCapture();
bool initialized;
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
if (initialized == false)
{
var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);
await mediacapture.InitializeAsync(new MediaCaptureInitializationSettings
{
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.Photo,
AudioDeviceId = string.Empty,
VideoDeviceId = cameraID.Id
});
}
//Selecting Maximum resolution for Video Preview
var maxPreviewResolution = mediacapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.VideoPreview).Aggregate((i1, i2) => (i1 as VideoEncodingProperties).Height > (i2 as VideoEncodingProperties).Height ? i1 : i2);
//Selecting 4rd resolution setting
var selectedPhotoResolution = mediacapture.VideoDeviceController.GetAvailableMediaStreamProperties(MediaStreamType.Photo).ElementAt(3);
await mediacapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.Photo, selectedPhotoResolution);
await mediacapture.VideoDeviceController.SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, maxPreviewResolution);
// in my .xaml <CaptureElement Name="viewfinder" />
viewfinder.Source = mediacapture;
mediacapture.SetPreviewRotation(VideoRotation.Clockwise90Degrees);
await mediacapture.StartPreviewAsync();
initialized = true;
}
Also, make sure the camera stops previewing before you navigate to other page, or before camera starts preview again. There's no need to dispose MediaCapture.
private async void GoBack_Click(object sender, RoutedEventArgs e)
{
await mediacapture.StopPreviewAsync();
this.Frame.Navigate(typeof(MainPage));
//Not needed
//mediacapture.Dispose();
}
GetCameraID method credit to Romasz's blog. http://www.romasz.net/how-to-take-a-photo-in-windows-runtime/
This issue may be related to multithreading: using the defaults (ie not changing the SynchronizationContext) calls to await will continue methods on another thread, something which is not always supported by graphics and media libraries (I have firsthand experience with SFML, WPF, and AutoCAD getting very crash-happy, to name a few). While the presence of an InitializeAsync method indicates otherwise, make sure disposal doesn't need to happen on the main thread or such.

Open Windows Form with opcv From wpf windows

note I am new in Wpf >
I have project that decode qr code by using opencv library throw web cam >
and it running successfully
now I wanna to using this project in new Wpf project >
after adding new wpf project and make reference to WinForms application >
and this my simple code to open WinForm >
public void runnow(){
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new CameraCapture.cameraCapture()); }
by ruining give me this exception >
The type initializer for 'Emgu.CV.CvInvoke' threw an exception.>
what can I do for solve this
C# code
public partial class CameraCapture : Form
{
Capture capture;
bool Capturing;
Bitmap bimap;
private Reader reader;
private Hashtable hint;
libAES libEncryption = new libAES();
string Mykey = "";
public static String dataDecrypted="";
public CameraCapture()
{
InitializeComponent();
}
private void Mains(object sender, EventArgs arg) // Start function main to encode Qr code
{
Image<Bgr, Byte> image = capture.QueryFrame();
if (image != null)
{
bimap = image.ToBitmap();
pictureBox1.Image = bimap;
reader = new QRCodeReader();
hint = new Hashtable(); // Add some elements to the hash table. There are no duplicate keys, but some of the values are duplicates.
hint.Add(DecodeHintType.POSSIBLE_FORMATS, BarcodeFormat.QR_CODE);
RGBLuminanceSource source = new RGBLuminanceSource(bimap, bimap.Width, bimap.Height); //This class is used to help decode images from files which arrive as RGB data from* Android bitmaps. It does not support cropping or rotation.
BinaryBitmap img = new BinaryBitmap(new GlobalHistogramBinarizer(source));
Result result = null;
try
{
result = reader.decode(img, hint);
dataDecrypted = libEncryption.Decrypt(result.Text, Mykey);
}
catch
{
dataDecrypted = "";
}
if (result == null)
{
label1.Text = " no decode";
}
else
{
label4.Text = result.Text;
label1.Text = dataDecrypted;
capture.Dispose();
}
}
} // end function Main
private void btnStart_Click(object sender, EventArgs e)
{
if (capture == null)
{
try
{
capture = new Capture(); // **the exption thown here**
}
catch (NullReferenceException exception)
{
MessageBox.Show(exception.Message);
}
}
if (capture != null)
{
if (Capturing)
{
btnStart.Text = "Start Capture";
Application.Idle -= Mains;
}
else
{
btnStart.Text = "Stop Capture";
Application.Idle += Mains;
}
Capturing = !Capturing;
}
}
private void Release()
{
if (capture != null)
capture.Dispose();
}}
If you want to host WinForm in WPF, you need to use host control System.Windows.Forms.Integration.WindowsFormsHost
WPF provides many controls with a rich feature set. However, you may
sometimes want to use Windows Forms controls on your WPF pages. For
example, you may have a substantial investment in existing Windows
Forms controls, or you may have a Windows Forms control that provides
unique functionality.
Example code
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// Create the interop host control.
System.Windows.Forms.Integration.WindowsFormsHost host =
new System.Windows.Forms.Integration.WindowsFormsHost();
// Create the MaskedTextBox control.
MaskedTextBox mtbDate = new MaskedTextBox("00/00/0000");
// Assign the MaskedTextBox control as the host control's child.
host.Child = mtbDate;
// Add the interop host control to the Grid
// control's collection of child controls.
this.grid1.Children.Add(host);
}
Check =>
http://msdn.microsoft.com/en-us/library/ms751761.aspx

Categories

Resources