Camera capture didn't work - c#

I try to use camera in WP 8.1 universal app. But app crash.
I try di this:
private MediaCapture mediaCaptureMgr = null;
async void ShowPreview()
{
if (mediaCaptureMgr == null)
{
mediaCaptureMgr = new MediaCapture();
await mediaCaptureMgr.InitializeAsync();
myCaptureElement.Source = mediaCaptureMgr;
await mediaCaptureMgr.StartPreviewAsync();
}
}
and I try this example:
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh868171.aspx
but both crash app when I initialize MediaCapture
await mediaCaptureMgr.InitializeAsync();
VS output windows show me message
WinRT information: The text associated with this error code could not be found.
Can anybody help?

Related

Windows Phone 8.1 MediaCapture's FocusAsync does not work

I'm implementing a Windows Phone 8.1 App with a QR Code reader. I use ZXing.NET to analyze the taken image and try to parse the QR. To increase it's efficiency I also set autofocus to the camera. It works pretty well at the first start, but not with the second try (f.e. after suspend - resume or restart capturing). As I tested, the FocusAsync method doesn't return sometimes and blocks everything.
What happens here? What could be the problem?
Here is my current code.
Focus
var focusSettings = new Windows.Media.Devices.FocusSettings();
focusSettings.AutoFocusRange = Windows.Media.Devices.AutoFocusRange.Normal;
focusSettings.Mode = Windows.Media.Devices.FocusMode.Auto;
CaptureManager.VideoDeviceController.FocusControl.Configure(focusSettings);
MainProcess
... Initialization ...
ImageEncodingProperties imaggeProperties = ImageEncodingProperties.CreateJpeg();
imaggeProperties.Width = ViewModel.ImageWidth;
imaggeProperties.Height = ViewModel.ImageHeight;
InMemoryRandomAccessStream memoryStream = new InMemoryRandomAccessStream();
LoggingAdapter.Instance.WriteDebugLog("Scanning is in progress. " + Environment.CurrentManagedThreadId);
await CaptureManager.VideoDeviceController.FocusControl.FocusAsync();
await CaptureManager.CapturePhotoToStreamAsync(imaggeProperties, memoryStream);
LoggingAdapter.Instance.WriteDebugLog("Photo captured.");
var bcReader = new BarcodeReader();
... Processing the barcode ...
Cleaning
if (CaptureManager != null)
{
if (InProgress)
{
InProgress = false;
await CaptureManager.StopPreviewAsync();
}
CaptureManager.Dispose();
Capture.Source = null;
}
Thanks for advance!
I succeeded to implement a working solution. I set the the WaitForFocus to false in the FocusSettings and it seems to be working fine, also with suspending or cancelling.

Opening a PDF file using associated application in a Unity App for WindowsPhone 8.0

I am pretty new in WindowsPhone applications development. I am currently developing a Unity application for Windows Phone 8.0. Inside this app I would like to open a PDF using the appropriate application on the phone (Acrobat Reader, Windows Reader, etc...)
First, I tried this :
void PDFButtonToggled(bool i_info)
{
Dispatcher.BeginInvoke(() =>
{
DefaultLaunch();
});
}
async void DefaultLaunch()
{
// Path to the file in the app package to launch
string PDFFilePath = #"Data/StreamingAssets/ImageTest.jpg";
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(PDFFilePath);
if (file != null)
{
// Set the option to show the picker
var options = new Windows.System.LauncherOptions();
options.DisplayApplicationPicker = true;
// Launch the retrieved file
bool success = await Windows.System.Launcher.LaunchFileAsync(file, options);
if (success)
{
// File launched
}
else
{
throw new Exception("File launch failed");
}
}
else
{
throw new Exception("Could not find file");
}
}
It returned me an exception so I searched why. I found that topic (written in 2013 :/) about async functions / threads : LINK. To sumarize, here the answer of Unity staff :
It will only work on Windows Store Apps, and you'll have to wrap the code in #if NET_FX/#endif. On other platforms, you cannot use async/.NET 4.5 code in scripts. If you want to use it for windows phone, you'll have to write that code in separate visual studio solution and compile it to DLL, so unity can use it as a plugin.
So I decided to create the double DLL solution described in the Unity Manual here : LINK. But when I complete the class of the first DLL with the "async void DefaultLaunch()" function given above I don't have references about Windows.ApplicationModel.etc... and Windows.System.etc... .
And here I am, a little bit lost between WP, Unity, 8.0 apps, StoreApps, etc...
If anyone has advices, questions, anything that can help me, it's welcome. :)
Crèvecoeur
I found a solution by myself but on a WindowsPhone8.1 application.
Here it is :
async void PDFButtonToggled(bool i_info)
{
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
DefaultLaunchFile();
});
}
async void DefaultLaunchFile()
{
StorageFolder dataFolder = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFolderAsync("Data");
StorageFolder streamingAssetsFolder = await dataFolder.GetFolderAsync("StreamingAssets");
// Path to the file in the app package to launch
string filePath = "PDFTest.pdf";
var file = await streamingAssetsFolder.GetFileAsync(filePath);
if (file != null)
{
// Launch the retrieved file
bool success = await Windows.System.Launcher.LaunchFileAsync(file);
if (success)
{
// File launched
}
else
{
throw new Exception("File launch failed");
}
}
else
{
throw new Exception("File not found");
}
}

Recording Audio and Playing sound at the same time - C# - Windows Phone 8.1

I am trying to record audio and play it directly (I want to hear my voice in the headphone without saving it) however the MediaElement and the MediaCapture seems non to work at the same time.
I initialized my MediaCapture so:
_mediaCaptureManager = new MediaCapture();
var settings = new MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
settings.MediaCategory = MediaCategory.Other;
settings.AudioProcessing = AudioProcessing.Default;
await _mediaCaptureManager.InitializeAsync(settings);
However I don't really know how to proceed; I am wonderign if one of these ways could work (I tryied implement them without success, and I have not found examples):
Is there a way to use StartPreviewAsync() recording Audio, or it only works for Videos? I noticed that I get the following error:"The specified object or value does not exist" while setting my CaptureElement Source; it only happens if I write "settings.StreamingCaptureMode = StreamingCaptureMode.Audio;" while everyting works for .Video.
How can I record to a stream using StartRecordToStreamAsync(); I mean, how have I to initialize the IRandomAccessStream and read from it? Can I write on a stream while I keep reading for it?
I read that changing AudioCathegory of the MediaElement and the MediaCathegory of the MediaCapture to Communication there is a possibility it could work. However, while my code works (it just have to record and save in a file) with the previous setting, it don't works if I wrote "settings.MediaCategory = MediaCategory.Communication;" instead of "settings.MediaCategory = MediaCategory.Other;". Can you tell me why?
Here is my current program that just record, save and play:
private async void CaptureAudio()
{
try
{
_recordStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName);
MediaEncodingProfile recordProfile = MediaEncodingProfile.CreateWav(AudioEncodingQuality.Auto);
await _mediaCaptureManager.StartRecordToStorageFileAsync(recordProfile, this._recordStorageFile);
_recording = true;
}
catch (Exception e)
{
Debug.WriteLine("Failed to capture audio:"+e.Message);
}
}
private async void StopCapture()
{
if (_recording)
{
await _mediaCaptureManager.StopRecordAsync();
_recording = false;
}
}
private async void PlayRecordedCapture()
{
if (!_recording)
{
var stream = await _recordStorageFile.OpenAsync(FileAccessMode.Read);
playbackElement1.AutoPlay = true;
playbackElement1.SetSource(stream, _recordStorageFile.FileType);
playbackElement1.Play();
}
}
If you have any suggestion I'll be gratefull.
Have a good day.
Would you consider targeting Windows 10 instead? The new AudioGraph API allows you to do just this, and the Scenario 2 (Device Capture) in the SDK sample demonstrates it well.
First, the sample populates all output devices into a list:
private async Task PopulateDeviceList()
{
outputDevicesListBox.Items.Clear();
outputDevices = await DeviceInformation.FindAllAsync(MediaDevice.GetAudioRenderSelector());
outputDevicesListBox.Items.Add("-- Pick output device --");
foreach (var device in outputDevices)
{
outputDevicesListBox.Items.Add(device.Name);
}
}
Then it gets to building the AudioGraph:
AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media);
settings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.LowestLatency;
// Use the selected device from the outputDevicesListBox to preview the recording
settings.PrimaryRenderDevice = outputDevices[outputDevicesListBox.SelectedIndex - 1];
CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);
if (result.Status != AudioGraphCreationStatus.Success)
{
// TODO: Cannot create graph, propagate error message
return;
}
AudioGraph graph = result.Graph;
// Create a device output node
CreateAudioDeviceOutputNodeResult deviceOutputNodeResult = await graph.CreateDeviceOutputNodeAsync();
if (deviceOutputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
{
// TODO: Cannot create device output node, propagate error message
return;
}
deviceOutputNode = deviceOutputNodeResult.DeviceOutputNode;
// Create a device input node using the default audio input device
CreateAudioDeviceInputNodeResult deviceInputNodeResult = await graph.CreateDeviceInputNodeAsync(MediaCategory.Other);
if (deviceInputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
{
// TODO: Cannot create device input node, propagate error message
return;
}
deviceInputNode = deviceInputNodeResult.DeviceInputNode;
// Because we are using lowest latency setting, we need to handle device disconnection errors
graph.UnrecoverableErrorOccurred += Graph_UnrecoverableErrorOccurred;
// Start setting up the output file
FileSavePicker saveFilePicker = new FileSavePicker();
saveFilePicker.FileTypeChoices.Add("Pulse Code Modulation", new List<string>() { ".wav" });
saveFilePicker.FileTypeChoices.Add("Windows Media Audio", new List<string>() { ".wma" });
saveFilePicker.FileTypeChoices.Add("MPEG Audio Layer-3", new List<string>() { ".mp3" });
saveFilePicker.SuggestedFileName = "New Audio Track";
StorageFile file = await saveFilePicker.PickSaveFileAsync();
// File can be null if cancel is hit in the file picker
if (file == null)
{
return;
}
MediaEncodingProfile fileProfile = CreateMediaEncodingProfile(file);
// Operate node at the graph format, but save file at the specified format
CreateAudioFileOutputNodeResult fileOutputNodeResult = await graph.CreateFileOutputNodeAsync(file, fileProfile);
if (fileOutputNodeResult.Status != AudioFileNodeCreationStatus.Success)
{
// TODO: FileOutputNode creation failed, propagate error message
return;
}
fileOutputNode = fileOutputNodeResult.FileOutputNode;
// Connect the input node to both output nodes
deviceInputNode.AddOutgoingConnection(fileOutputNode);
deviceInputNode.AddOutgoingConnection(deviceOutputNode);
Once all of that is done, you can record to a file while at the same time playing the recorded audio like so:
private async Task ToggleRecordStop()
{
if (recordStopButton.Content.Equals("Record"))
{
graph.Start();
recordStopButton.Content = "Stop";
}
else if (recordStopButton.Content.Equals("Stop"))
{
// Good idea to stop the graph to avoid data loss
graph.Stop();
TranscodeFailureReason finalizeResult = await fileOutputNode.FinalizeAsync();
if (finalizeResult != TranscodeFailureReason.None)
{
// TODO: Finalization of file failed. Check result code to see why, propagate error message
return;
}
recordStopButton.Content = "Record";
}
}

Toggle flashlight in Windows Phone 8.1

Can anyone say how to toggle flashlight in Windows Phone 8.1 using C#? It seems like there are lots of API changes in Windows Phone 8.1 and most of the API's in WP 8.0 are not supported. Answers are highly appreciated.
I'm able to use TorchControl on my Lumia 820 like this - first you have to specify which camera you will use - the default is front (I think that's why you may find some problems) and we want the back one - the one with flash light. Sample code:
// edit - I forgot to show GetCameraID:
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 of type {0} doesn't exist.", desiredCamera));
}
// init camera
async private void InitCameraBtn_Click(object sender, RoutedEventArgs e)
{
var cameraID = await GetCameraID(Windows.Devices.Enumeration.Panel.Back);
captureManager = new MediaCapture();
await captureManager.InitializeAsync(new MediaCaptureInitializationSettings
{
StreamingCaptureMode = StreamingCaptureMode.Video,
PhotoCaptureSource = PhotoCaptureSource.VideoPreview,
AudioDeviceId = string.Empty,
VideoDeviceId = cameraID.Id
});
}
// then to turn on/off camera
var torch = captureManager.VideoDeviceController.TorchControl;
if (torch.Supported) torch.Enabled = true;
// turn off
if (torch.Supported) torch.Enabled = false;
Note that it's a good idea to call captureManager.Dispose() after you finish with it.
Note also that on some phones to turn on torch/flashlight you will need to start preview first.
Windows Phone 8.1 is the first version with a dedicated API for controlling the camera light. This API stems from Windows 8.1 but is usable in Windows Phone 8.1 projects and in Windows Phone Silverlight 8.1 projects.
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;
}
Note:
Note: TorchControl.Supported returns false on most phones in WP8.1 developer preview. It is expected to be fixed by a firmware update by the time WP 8.1 is released. Tested Phones at the time of writing: Lumia 620, 822, 1020: not working, Lumia 1520: working.
In Nokia Lumia 1520, you use FlashControl to toggle the flash light instead of TorchControl.
//to switch OFF flash light
mediacapture.VideoDeviceController.FlashControl.Enabled = false;
//to switch ON flash light
mediacapture.VideoDeviceController.FlashControl.Enabled = true;
Doesn't work on my Lumia 1520. You need to start video recording to get flashlight working:
var videoEncodingProperties = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Vga);
var videoStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync("tempVideo.mp4", CreationCollisionOption.GenerateUniqueName);
await captureManager.StartRecordToStorageFileAsync(videoEncodingProperties, videoStorageFile);
In my Lumia 1520. I need to start video recording and start preview to get flashlight working:
await captureManager.StartPreviewAsync();

Windows Phone 8.1 app to share image - works fine on my phone with Visual Studio debugger attached, but crashes when run without the debugger

I'm trying to share an image through my app, everything works just fine when I run the app on my phone through visual studio, but when I try to run it from my phone, it crashes everytime I click the share button
private async void dataTransferManager_DataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
args.Request.Data.Properties.Title = "Let's Celebrate";
args.Request.Data.Properties.Description = "It's time to celebrate!";
DataRequestDeferral deferral = args.Request.GetDeferral();
try
{
var finalImg = await GenerateImage();
var folder = Package.Current.InstalledLocation;
const CreationCollisionOption option = CreationCollisionOption.ReplaceExisting;
var file = await folder.CreateFileAsync("letscelebrateshare.png", option);
var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
var pixelBuffer = await finalImg.GetPixelsAsync();
using (var stream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied,
(uint)finalImg.PixelWidth,
(uint)finalImg.PixelHeight,
logicalDpi,
logicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
StorageFile logoFile =
await Package.Current.InstalledLocation.GetFileAsync("letscelebrateshare.png");
List<IStorageItem> storageItems = new List<IStorageItem>();
storageItems.Add(logoFile);
args.Request.Data.SetStorageItems(storageItems);
}
}
finally
{
deferral.Complete();
}
}
private async void bla... [..]
{
Exception exc= null;
try
{
//All your stuff
}
catch(Exception ex)
{
exc = ex;
}
if(exc!=null)
await msg.ShowAsync();
}
Edit: Since I don't use WP in C#. I guess you could try this. Hope this helps ^^
I had the same issue while opening a file open picker. I found a weird solution. When I removed the navigation parameters in every pages and used static variables instead, worked fine for me. I guess this will help you
If the App is there crashing without debugger, try while debugging and the share targets are visible to "suspend and shutdown" ("Lifecycle Events" in visual studio). In most cases you app will then crash because it is suspended and serialize the data.

Categories

Resources