WinRT Toolkit Windows Phone 8.1 save video wth CameraCaptureControl - windows-phone-8.1

I'm pretty new on Windows Phone 8.1 development and what I'm currently trying is recording a video and store it on the Windows Phone. However, I don't have any idea how that can be done. I have some code excerpt below which is the code executed when the start/stop record button is pressed. The code is taken from an example.
My questions:
How _videoFile can be saved to the VideoLibrary?
Preferably I would like the program to execute a method when recording is stopped. How I get the video filename inside this method?
private async void OnCaptureVideoButtonClick(object sender, RoutedEventArgs e)
{
if (!_capturingVideo)
{
//BtnStartStop.Content = "Stop";
StartAppBarButton.Icon = new SymbolIcon(Symbol.Stop);
_capturingVideo = true;
_videoFile = await TestedControl.StartVideoCaptureAsync(KnownFolders.VideosLibrary, "capture.mp4");
CapturedVideoElement.Visibility = Visibility.Visible;
IRandomAccessStreamWithContentType stream;
try
{
stream = await TryCatchRetry.RunWithDelayAsync<Exception, IRandomAccessStreamWithContentType>(
_videoFile.OpenReadAsync(),
TimeSpan.FromSeconds(0.5),
10);
}
catch (Exception ex)
{
#pragma warning disable 4014
new MessageDialog(ex.Message, "Error").ShowAsync();
#pragma warning restore 4014
return;
}
CapturedVideoElement.SetSource(stream, _videoFile.ContentType);
}
else
{
StartAppBarButton.Icon = new SymbolIcon(Symbol.Camera);
_capturingVideo = false;
#pragma warning disable 4014
await TestedControl.StopCapture();
#pragma warning restore 4014
}
}

Using the await keyword, StartVideoCaptureAsync is called asynchronously.
So the next line of code will be executed only once this asynchronous task is finished.
It means that the line of code below (and all the next ones):
CapturedVideoElement.Visibility = Visibility.Visible
will be executing at the end of the recording.
So if you need to execute a method after the recording is done, you can just put it after the call of StartVideoCaptureAsync.

Related

Reading data from Arduino Bluetooth on Windows Phone 8.1

I am developing a code that will allow me to send small amounts of data between my arduino mega and my windows 8.1 phone using a HC-05 bluetooth module.
Sending data from the phone to the arduino was pretty simple, but I am having a dire time attempting to read data that comes back from the arduino that I send on the serial port.
For testing purposes my code is simple, sending ascii charaters 'a' & 'b' to turn an LED on & off, this could not work any better, but I am having trouble trying to figure out how to correctly read the data that I send back to my phone.
I send a single arbitrary ascii character back to the phone but I cannot for the life of me figure out the correct way of reading this data from the bluetooth stream I have setup.
I have been trying for nearly two days, but everything I try ends up freezing my phone with no exceptions thrown? A lot of posts online send me to the Nokia dev site which is now inactive.
I have tried using the 'datareader' and the 'streamreader' classes to do this but it always freezes, does anyone know how to make this work? And why my streamreader keeps freezing my phone?
I have tried to annotate my code appropriatley (seen below). The problem occurs in the 'Tick' event handler at the bottom of the code.
(FYI: All capabilities have been added to the manifest files so this shouldn't be the problem).
Thank you.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Bluetooth_SL.Resources;
using Windows.Networking;
using Windows.Networking.Proximity;
using Windows.Networking.Sockets;
using Windows.Devices.Bluetooth;
using System.IO;
using Microsoft.Xna.Framework;
using System.Windows.Threading;
using Windows.Storage.Streams; // <-- for the datareader class
namespace Bluetooth_SL // silverlight, does this matter?
{
public partial class MainPage : PhoneApplicationPage
{
DispatcherTimer Timer = new DispatcherTimer();
StreamSocket socket = new StreamSocket();
StreamWriter writer;
StreamReader reader;
public MainPage()
{
InitializeComponent();
Timer.Interval = TimeSpan.FromMilliseconds(1000); // dispatcher timer used to check for incoming data from arduino
Timer.Tick += Timer_Tick; // event handler for dispatcher timer
}
protected override void OnNavigatedFrom(NavigationEventArgs e) // frees up memory
{
socket.Dispose();
}
private void Connect_But_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
ConnectToBluetooth();
}
private async void ConnectToBluetooth() // sets up the connection // this works fine
{
// Configure PeerFinder to search for all paired devices.
PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
var pairedDevices = await PeerFinder.FindAllPeersAsync();
if (pairedDevices.Count == 0)
{
Debug_Block.Text = "No paired devices were found.";
}
else
{
Debug_Block.Text = "Found";
PeerInformation selectedDevice = pairedDevices[0]; // pick the first paired device
try // 'try' used in the case the socket has already been connected
{
await socket.ConnectAsync(selectedDevice.HostName, "1");
writer = new StreamWriter(socket.OutputStream.AsStreamForWrite());
writer.AutoFlush = true;
reader = new StreamReader(socket.InputStream.AsStreamForRead());
Debug_Block.Text = "Connected";
}
catch (Exception x)
{
Debug_Block.Text = x.ToString();
}
}
}
private void SendButton_Tap(object sender, System.Windows.Input.GestureEventArgs e) // this works perfectly
{
try { writer.WriteLine("a"); } // attempts to write the ascii 'a' to the arduino which turns on the on-board LED
catch { Debug_Block.Text = "Failed to write"; }
}
private void SendButton_Off_Tap(object sender, System.Windows.Input.GestureEventArgs e) // this works perfectly
{
try { writer.WriteLine("b"); } // attempts to write the ascii 'b' to the arduino which turns off the on-board LED
catch { Debug_Block.Text = "Failed to write"; }
}
private void ReadButtonToggle_Tap(object sender, System.Windows.Input.GestureEventArgs e) // toggles the timer on and off
{
if(Timer.IsEnabled == true)
{
Timer.Stop();
Debug_Block.Text = "Timer Stopped";
}
else
{
Timer.Start();
Debug_Block.Text = "Timer Started";
}
}
void Timer_Tick(object sender, EventArgs e) // THIS IS THE PROBLEM
{
Debug_Block.Text = "Tick";
Debug_Block.Text = reader.ReadLine(); // <-- ALWAYS FREEZES HERE
Timer.Stop(); // This line is temporary for debugging
}
}
}

play music on windows phone 8.1

I tried to get all the music files into listbox and play the selected file.
The below code is what i did to play music but unfortunately it doesn't play. Can anyone tell me what the mistake is?
private async void button1_Click(object sender, RoutedEventArgs e)
{
StorageFolder folder = Windows.Storage.KnownFolders.MusicLibrary;
IReadOnlyList<StorageFile> files = await folder.GetFilesAsync();
foreach (var file in files)
{
MusicProperties music = await file.Properties.GetMusicPropertiesAsync();
listBox2.Items.Add(music.Title);
}
}
private async void listBox2_Tapped(object sender, TappedRoutedEventArgs e)
{
try
{
StorageFolder folder = Windows.Storage.KnownFolders.MusicLibrary;
IReadOnlyList<StorageFile> files = await folder.GetFilesAsync();
if (files.Count > 0)
{
var file = files[listBox2.SelectedIndex];
mediaElement1.Source = new Uri(files[listBox2.SelectedIndex].Path);
textBlock1.Text = files[listBox2.SelectedIndex].Path;
mediaElement1.Play();
}
}
catch(Exception ex)
{
textBlock1.Text = ex.Message;
}
}
Instead mediaElement1.Source = new Uri(files[listBox2.SelectedIndex].Path); you need use the code bellow:
var fileStream = await file.OpenReadAsync();
mediaElement.SetSource(fileStream, file.ContentType);
You need to use BackgroundMediaPlayer with background task.
MSDN
You can write apps for Windows Phone 8.1 that play audio in the background. This means that even after the user has left your app by pressing the Back button or the Start button on their device, your app can continue to play audio.
Scenarios for background audio playback include:
Long-running playlists The user briefly brings up a foreground app to select and start a playlist, after which the user expects the playlist to continue playing in the background.
Using task switcher The user briefly brings up a foreground app to start playing audio, then switches to another open app using the task
switch. The user expects the audio to continue playing in the
background.

CameraPreviewImageSource empty preview frame

I made cut and paste of the code below about how to use CameraPreviewImageSource and access to preview buffer frames, but do not work and it seems the frame buffer size is 0x0 reading the value of IImageSize parameter of OnPreviewFrameAvailable event.
How to get preview buffer of MediaCapture - Universal app
protected override void OnNavigatedTo(NavigationEventArgs e)
{
InitializeAsync();
}
public async void InitializeAsync()
{
_cameraPreviewImageSource = new CameraPreviewImageSource();
await _cameraPreviewImageSource.InitializeAsync(string.Empty);
var properties = await _cameraPreviewImageSource.StartPreviewAsync();
var width = 640.0;
var height = 480;
_writeableBitmap = new WriteableBitmap((int)width, (int)height);
_writeableBitmapRenderer = new WriteableBitmapRenderer(_cameraPreviewImageSource, _writeableBitmap);
Initialized = true;
_cameraPreviewImageSource.PreviewFrameAvailable += OnPreviewFrameAvailable;
}
private async void OnPreviewFrameAvailable(IImageSize args)
{
System.Diagnostics.Debug.WriteLine("ww:"+args.Size.Width+" hh:"+args.Size.Height);
// Prevent multiple rendering attempts at once
if (Initialized && !_isRendering)
{
_isRendering = true;
try
{
await _writeableBitmapRenderer.RenderAsync();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("\n\n"+ex.Message);
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
_isRendering = false;
}
}
Capabilities (webcam & microphone) on Package.appxmanifest has been selected
Implementing CameraPreviewImageSource on a Silverlight app works great!
I am afraid you are (were) seeing a bug in Lumia Imaging SDK 2.0.184. The problem only occured on some camera models and only on 8.1/universal applications. Silverlight applications were not affected by the problem.
The bug has been fixed in the newly released Lumia Imaging SDK 2.0.208. From release notes:
Fixed ArgumentOutOfRangeException being thrown by CameraPreviewImageSource when used with certain camera models.

Display splash page only on the 1st launch, or after a crash or a kill of the app

Could you please explain how to display splash page when only first launch or crash or kill the app in windows phone.
You could use the IsolatedStorage to check if the app was opened before or not
private static bool hasSeenIntro;
/// <summary>Will return false only the first time a user ever runs this.
/// Everytime thereafter, a placeholder file will have been written to disk
/// and will trigger a value of true.</summary>
public static bool HasUserSeenIntro()
{
if (hasSeenIntro) return true;
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.FileExists(LandingBitFileName))
{
// just write a placeholder file one byte long so we know they've landed before
using (var stream = store.OpenFile(LandingBitFileName, FileMode.Create))
{
stream.Write(new byte[] { 1 }, 0, 1);
}
return false;
}
hasSeenIntro = true;
return true;
}
}
For the crash system, you could use BugSense for Windows Phone

Infinite wait loading remote image into BitmapImage() in Background Agent

I have a valid URL for a remote JPEG which I'm trying to load in the background. But I find I never get control back after invoking the BitmapImage() constructor. My question is, should this approach work, or should I pitch it all, load up BcpAsync project from NuGet and start working with WebClient asynch methods?
A sample URL for which it fails is
http://image.weather.com/images/maps/current/garden_june_720x486.jpg
It is valid. .UpdateAsync() references it from AppViewModel.Instance, it's not explicitly referenced here.
Here's the background agent:
protected override async void OnInvoke(ScheduledTask task)
{
AppViewModel.LoadData();
await AppViewModel.Instance.RemoteImageProxy.UpdateAsync();
AppViewModel.Instance.ImageUrl = AppViewModel.Instance.RemoteImageProxy.LocalFileUri;
AppViewModel.Instance.UpdateCount++;
PinnedTile.Update();
}
AppViewModel.SaveData();
#if DEBUG
ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(AppViewModel.Instance.BgAgentInterval));
#endif
NotifyComplete();
}
Here's the invoked method:
public Task<double> UpdateAsync() {
LastCheckedTime = DateTime.UtcNow;
CompletionTask = new TaskCompletionSource<double>();
// Not usually called on UI thread, not worth optimizing for that case here.
Deployment.Current.Dispatcher.BeginInvoke(() => { //todo determine whether System.Windows.Deployment.Dispatcher can be called from main app, or just bgAgent.
HelperImageControl = new Image();
HelperImageControl.Loaded += im_Loaded;
HelperImageControl.ImageFailed += im_ImageFailed;
HelperImageControl.ImageOpened += im_ImageOpened;
// breakpoint here
HelperImageControl.Source = new BitmapImage(SourceUri);
// stepping over the function, control does not return here. Nor are any of the above events fired.
});
return CompletionTask.Task; // this will be completed in one of the subsequent control events...
}
You need to call CompletionTask.SetResult(); to return control back to the caller method.
This works (I'm returning 100 in case of successful download because you set the task to return double).
TaskCompletionSource<double> CompletionTask;
public Task<double> UpdateAsync()
{
CompletionTask = new TaskCompletionSource<double>();
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
var HelperImageControl = new Image();
var bmp = new BitmapImage();
bmp.ImageOpened += bmp_ImageOpened;
bmp.ImageFailed += bmp_ImageFailed;
bmp.CreateOptions = BitmapCreateOptions.None;
bmp.UriSource = new Uri("http://image.weather.com/images/maps/current/garden_june_720x486.jpg", UriKind.Absolute);
HelperImageControl.Source = bmp;
});
return CompletionTask.Task;
}
void bmp_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
CompletionTask.SetException(e.ErrorException);
}
void bmp_ImageOpened(object sender, RoutedEventArgs e)
{
CompletionTask.SetResult(100);
}