windows phone 7 Recording Issue - windows-phone-7

I will working on the Recording functionality in my windows phone 7 app.
I implemented the Recording functionality through this reference link.
It completely works fine at there and in my case also.
Actually the scenario is, In my application i created first page that will works as the recording screen as same as above referred link.
and when we stop the recording i redirected to the second page and saved that recording in Isolated storage and at the second page i bound the recorded sounds. At here i played the recorded sounds at it works fine.
Now, when i m again go to the recording screen(first page) and starts another recording. it will some times records fine and some times it will skip the some sounds during recording as like beep sounds and it will looks like a extra noise in recording and not getting properly recording sounds.
My Code is like,
public partial class NikhilRecord : PhoneApplicationPage
{
//XNA Objects for Record And Playback
Microphone mphone;
//Used for Storing captured buffers
List<byte[]> memobuffercollection = new List<byte[]>();
//Used for displaying stored memos
ObservableCollection<MemoInfo> memofiles = new ObservableCollection<MemoInfo>();
SpaceTime spaceTime = new SpaceTime();
public NikhilRecord()
{
InitializeComponent();
//Create new Microphone and set event handler.
mphone = Microphone.Default;
mphone.BufferReady += OnMicrophoneBufferReady;
String FileName = PhoneApplicationService.Current.State["MySelectedSong"].ToString();
using (IsolatedStorageFile IsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
try
{
using (IsolatedStorageFileStream fileStream = IsolatedStorage.OpenFile(FileName, FileMode.Open, FileAccess.Read))
{
MyMedia.SetSource(fileStream);
MyMedia.CurrentStateChanged += new RoutedEventHandler(mediaPlayer_CurrentStateChanged);
fileStream.Close();
fileStream.Dispose();
//Start Recording
OnRecordButtonClick();
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message);
}
}
void UpdateRecording(bool isRecording)
{
if (!isRecording)
{
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
spaceTime.Space = storage.AvailableFreeSpace;
}
}
else
{
spaceTime.Space = memobuffercollection.Count * mphone.GetSampleSizeInBytes(mphone.BufferDuration);
}
spaceTime.Time = mphone.GetSampleDuration((int)Math.Min(spaceTime.Space, Int32.MaxValue));
}
void OnMicrophoneBufferReady(object sender, EventArgs e)
{
// Get buffer from microphone and add to collection
byte[] buffer = new byte[mphone.GetSampleSizeInBytes(mphone.BufferDuration)];
int bytesreturned = mphone.GetData(buffer);
memobuffercollection.Add(buffer);
UpdateRecording(true);
// To be Continue...
if (spaceTime.Time > TimeSpan.FromMinutes(10))
{
StopRecording();
UpdateRecording(false);
}
}
void OnRecordButtonClick()
{
if (mphone.State == MicrophoneState.Stopped)
{
// Clear the collection for storing the buffers
memobuffercollection.Clear();
// Start Recording
mphone.Start();
MyMedia.Play();
}
else
{
MyMedia.Stop();
//mphone.Stop();
PopUpGrid.Visibility = Visibility.Visible;
RecordGrid.Opacity = 0.5;
RecordGrid.IsHitTestVisible = false;
}
bool isRecording = mphone.State == MicrophoneState.Started;
UpdateRecording(isRecording);
}
void StopRecording()
{
// Get the last partial buffer
int sampleSize = mphone.GetSampleSizeInBytes(mphone.BufferDuration);
byte[] extraBuffer = new byte[sampleSize];
int extraBytes = mphone.GetData(extraBuffer);
// Stop Recording
mphone.Stop();
//Stop the Song
MyMedia.Stop();
// Create MemoInfo object and add at top of collection
int totalSize = memobuffercollection.Count * sampleSize + extraBytes;
TimeSpan duration = mphone.GetSampleDuration(totalSize);
MemoInfo memoInfo = new MemoInfo(DateTime.UtcNow, totalSize, duration);
memofiles.Insert(0, memoInfo);
// Save Data in IsolatedStorage
using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
{
string[] alldirectories = storage.GetDirectoryNames("NikDirectory");
if (alldirectories.Count() == 0)
storage.CreateDirectory("NikDirectory");
try
{
using (IsolatedStorageFileStream stream = storage.CreateFile("NikDirectory\\" + memoInfo.FileName))
{
// Write buffers from collection
foreach (byte[] buffer in memobuffercollection)
stream.Write(buffer, 0, buffer.Length);
// Write partial buffer
stream.Write(extraBuffer, 0, extraBytes);
stream.Close();
stream.Dispose();
}
Uri url = new Uri("/Gallery.xaml", UriKind.Relative);
NavigationService.Navigate(url);
memobuffercollection.Clear();
}
catch (Exception ees)
{
MessageBox.Show(ees.Message);
Uri url = new Uri("/Karaoke.xaml", UriKind.Relative);
NavigationService.Navigate(url);
}
}
bool isRecording = mphone.State == MicrophoneState.Started;
UpdateRecording(isRecording);
}
}
So, please help me out the problem. I heard at somewhere that you have to dispose all the objects of the microphone when you redirect to another screen. is it true ? or anything else.
Please help me.
Looking Forward.

Instead of using a collection, you should use following way to read your recorded bytes.
This should be done into the BufferReady event of your microphone object.
byte[] audioBuffer = new byte[microphone.GetSampleSizeInBytes(microphone.BufferDuration)];
microphone.GetData(audioBuffer);
RecordingStream.Write(audioBuffer, 0, audioBuffer.Length);
RecordingStream is a MemoryStream , should be declared globally.
I am not sure about this but as I have used it and it works completely fine in each case.
Try this.

Related

Xamarin Android image Capture by Camera using intent ActionImageCapture, the image quality is low

Im new to Xamarin Android. Now I was trying to capture the image by camera and displaying in imageview but I was facing the problem which is the image quality that captured from camera is low. And I was doing the research from google and i only found the solution which is save the image that captured in to file and retrieve from file. But the solution is only for android studio and xamarin form.
This is the coding for the intent that calling image captured
Intent intent = new Intent(MediaStore.ActionImageCapture);
StartActivityForResult(intent, 1000);
This is the coding for onactivityresult,
if ((requestCode == PickImageId) && (resultCode == Android.App.Result.Ok) && (data != null))
{
base.OnActivityResult(requestCode, resultCode, data);
bitmap = (Bitmap)data.Extras.Get("data");
var dir = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDcim);
string filename = System.DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg";
string filePath = System.IO.Path.Combine(dir + "/Camera/", filename);
using (var stream = new MemoryStream())
{
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 100, stream);
byte[] bitmapData = stream.ToArray();
try
{
System.IO.File.WriteAllBytes(filePath, bitmapData);
bitmap = BitmapFactory.DecodeByteArray(bitmapData, 0, bitmapData.Length);
imgview.SetImageBitmap(bitmap);
}
catch (Exception ex)
{
System.Console.WriteLine(ex.ToString());
}
}
}
I have try to save the image into phone folder which is 'DCIM/Camera/xxx.jpg'. The image that captured and save in folder is success but the image quality still low.
Is there have any solution to increase the quality of the image?
Sorry for my poor english, please provide me suggestion or solution.
Thanks for giving helps
Hello you can use Xamarin Essential Media Picker to take photo.
Here is an example code:
using Xamarin.Essentials;
string PhotoPath="";
public async Task TakePhotoAsync()
{
try
{
var photo = await MediaPicker.CapturePhotoAsync();
await LoadPhotoAsync(photo);
}
catch (FeatureNotSupportedException fnsEx)
{
// Feature is not supported on the device
}
catch (PermissionException pEx)
{
// Permissions not granted
}
catch (Exception ex)
{
Console.WriteLine($"CapturePhotoAsync THREW: {ex.Message}");
}
}
public async Task LoadPhotoAsync(FileResult photo)
{
// canceled
if (photo == null)
{
PhotoPath = null;
return;
}
// save the file into local storage
var newFile = Path.Combine(FileSystem.CacheDirectory, photo.FileName); //or any other Storage Directory
using (var stream = await photo.OpenReadAsync())
using (var newStream = File.OpenWrite(newFile))
await stream.CopyToAsync(newStream);
PhotoPath = newFile;
}

Download and open picture from url/http [Android Xamarin App]

Hello, would any of you send a working code to download a photo from a given http address on android Xamarin c #?
First, I need to create a new folder for my application files.
My goal is to download the file from the internet to my Android folder (saving this file with its original name is best).
The next step is to display the image from that folder in "ImageView". It is also important that there are permissions in android and I do not fully understand it.
Could any of you send it to me or help me understand it and explain the topic?
*Actually i have this code:
string address = "https://i.stack.imgur.com/X3V3w.png";
using (WebClient webClient = new WebClient())
{
webClient.DownloadFileCompleted += WebClient_DownloadFileCompleted;
webClient.DownloadFile(address, Path.Combine(pathDire, "MyNewImage1.png"));
//System.Net.WebException: 'An exception occurred during a WebClient request.'
}
Loading image from url and display in imageview.
private void Btn1_Click(object sender, System.EventArgs e)
{
var imageBitmap = GetImageBitmapFromUrl("http://xamarin.com/resources/design/home/devices.png");
imagen.SetImageBitmap(imageBitmap);
}
private Bitmap GetImageBitmapFromUrl(string url)
{
Bitmap imageBitmap = null;
using (var webClient = new WebClient())
{
var imageBytes = webClient.DownloadData(url);
if (imageBytes != null && imageBytes.Length > 0)
{
SavePicture("ImageName.jpg", imageBytes, "imagesFolder");
imageBitmap = BitmapFactory.DecodeByteArray(imageBytes, 0, imageBytes.Length);
}
}
return imageBitmap;
}
download image and save it in local storage.
private void SavePicture(string name, byte[] data, string location = "temp")
{
var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
documentsPath = System.IO.Path.Combine(documentsPath, "Orders", location);
Directory.CreateDirectory(documentsPath);
string filePath = System.IO.Path.Combine(documentsPath, name);
using (FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate))
{
int length = data.Length;
fs.Write(data, 0, length);
}
}
you need to add permission WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE in AndroidMainfeast.xml, then you also need to Runtime Permission Checks in Android 6.0.
private void checkpermission()
{
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) == (int)Permission.Granted)
{
// We have permission, go ahead and use the writeexternalstorage.
}
else
{
// writeexternalstorage permission is not granted. If necessary display rationale & request.
}
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.ReadExternalStorage) == (int)Permission.Granted)
{
// We have permission, go ahead and use the ReadExternalStorage.
}
else
{
// ReadExternalStorage permission is not granted. If necessary display rationale & request.
}
}

How can I pass a captured image to a canvas?

I have a class that uses the devices camera to capture an image. My aim is to pass the captured image to a canvas on another layout.
This layout will then be saved along with a note entered into a textbox.I have figured out how to save the note and title and allow it to be opened but I'm not sure how I would go about passing the captured image to the layout and saving it along with the note.
Does anyone have any advice or pointers as to how I would go about this?
At the moment this is how I'm attempting to read the image file back to the layout after it is saved,but I'm not sure how to read a file into the canvas so obviously this solution isn't working yet:
if (NavigationContext.QueryString.ContainsKey("note"))
{
string s2 = ".jpg";
string filename = this.NavigationContext.QueryString["note"];
if (!string.IsNullOrEmpty(filename)) {
using (var store = System.IO.IsolatedStorage.IsolatedStorageFile .GetUserStoreForApplication())
using (var stream = new IsolatedStorageFileStream(filename, FileMode.Open, FileAccess.ReadWrite, store))
/*
if(filename.Contains(s2))
{
StreamReader reader = new StreamReader(stream);
this.capturedNoteCanvas = reader.ReadToEnd();
this.noteNameTb.Text = filename; reader.Close();
}
else
*/
{
StreamReader reader = new StreamReader(stream);
this.noteDataTb.Text = reader.ReadToEnd();
this.noteNameTb.Text = filename; reader.Close();
}
}
}
What I'm thinking is something like this:
Working wit CameraCaptureTask and Bitmaps
//Taking a writableBitmap object from cameracapturetask
void cameracapturetask_Completed(object sender, PhotoResult e)
{
try
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
WritableBitmap wb=new WritableBitmap (bmp.PixelWidth,bmp.PixelHeight);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
saving wb in storage
using (MemoryStream stream = new MemoryStream())
{
wb.SaveJpeg(stream, (int)bmp.PixelWidth, (int)bmp.PixelHeight, 0, 100);
using (IsolatedStorageFileStream local = new IsolatedStorageFileStream(App.PageName, FileMode.Create, mystorage))
{
local.Write(stream.GetBuffer(), 0, stream.GetBuffer().Length);
}
}
//Taking a WritableBitmap from canvas
If your canvas is containing the image, and also the canvas it attributed with some height and width properties then
WritableBitmap wb= new WritableBitmap(canvascontrol,null);
takes the canvas and saves it inside a writablebitmap object which can then be used for further image manipulations.

Sending Image with Exif info from Windows Phone to Java Server

I'm new in programming in Windows Phone (and StackOverflow tbh). Currently, I'm working on a task that concerns with sending images stored in the Windows Phone's storage (with Exif info) to a Java server. So far I have successfully send the byte stream from the Windows Phone client and construct the image on the Java side, however, the Exif information is somehow lost. I believe it's just the way I send it on Windows Phone that's causing the problem. Very much appreciated for any help or guidance !
Here's my code on the Windows Phone client:
// Windows Phone Client code (MainPage.xaml.cs)
// This function is called when an image is selected from
// the task PhotoChooserTask ptask, which brings
// a popup that allows the user to choose an image
// from the phone's storage
void ptask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK && e.ChosenPhoto != null)
{
//Take JPEG stream and decode into a WriteableBitmap object
App.CapturedImage = PictureDecoder.DecodeJpeg(e.ChosenPhoto);
// Attempt to send the image
WriteableBitmap pic = new WriteableBitmap(App.CapturedImage);
MemoryStream stream = new MemoryStream();
pic.SaveJpeg(stream, App.CapturedImage.PixelHeight, App.CapturedImage.PixelWidth, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
client.Send(stream);
// Close the socket connection explicitly
client.Close();
}
}
Here's the code in the SocketClient.cs
public string Send(MemoryStream data)
{
byte[] msData = data.ToArray();
if (_socket != null)
{
// Create SocketAsyncEventArgs context object
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
// Set properties on context object
socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
socketEventArg.UserToken = null;
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
_clientDone.Set();
});
// Add the data to be sent into the buffer
socketEventArg.SetBuffer(msData, 0, msData.Length);
// Sets the state of the event to nonsignaled, causing threads to block
_clientDone.Reset();
// Make an asynchronous Send request over the socket
_socket.SendAsync(socketEventArg);
}
else
{
response = "Socket is not initialized";
}
return response;
}
On the Java Server,
public static void main(String[] args) {
ServerSocket serverSocket;
Socket client;
try {
serverSocket = new ServerSocket(PORT_NUMBER);
while (true) {
client = serverSocket.accept();
// Extract exif info
InputStream inputStream = client.getInputStream();
InputStream stream = new BufferedInputStream(inputStream);
// Create file from the inputStream
File file = new File("image.jpg");
try {
OutputStream os = new FileOutputStream(file);
byte[] buffer = new byte[4096];
for (int n; (n = stream.read(buffer)) != -1;) {
os.write(buffer, 0, n);
}
}
The output image is identical to the one sent from the windows phone, just without any Exif information whatsoever. Anyone could point out what I did wrong that causes the information to be lost? I'm guessing because I called the SaveJpeg function in the windows phone code, rewriting the image file, and losing all information there, but I don't know how else to convert the image to byte and stream it.
Much help is appreciated ! Thank you.
I found the answer to my own problem. For those of you who might have a problem with this. I simply use:
Byte[] imageData = new byte[e.ChosenPhoto.Length];
e.ChosenPhoto.Position = 0;
e.ChosenPhoto.Read(imageData, 0, imageData.Length);
Then send the byte array in my send function:
socketEventArg.SetBuffer(imageData, 0, imageData.Length);

Want loading symbol until the storage process is completed in isolated storage

I have downloaded 200 images from absolute URL and stored in isolated storage. I want to display in my list or stackpanel one by one.I want the stack panel to show loading symbol until the download completes and the 200th image stored in isolated storage.
if (h < 150)
{
WebClient m_webClient = new WebClient();
Uri m_uri = new Uri("http://d1mu9ule1cy7bp.cloudfront.net/2012/media/catalogues/47/pages/p_" + h + "/IKEA_mobile_high.jpg");
m_webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
m_webClient.OpenReadAsync(m_uri);
}
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
int count;
try
{
Stream stream = e.Result;
byte[] buffer = new byte[1024];
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
//isf.Remove();
using (System.IO.IsolatedStorage.IsolatedStorageFileStream isfs = new IsolatedStorageFileStream("IMAGES" + loop2(k) + ".jpg", FileMode.Create, isf))
{
count = 0;
while (0 < (count = stream.Read(buffer, 0, buffer.Length)))
{
isfs.Write(buffer, 0, count);
}
stream.Close();
isfs.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
GetImages();
}
}
}
If all you want to do is show the progress of this long running task then simply add a ProgressBar. Set it's Minimum to 0, it's Maximum to 200 (or however many images you're going to download) then as each image download reports completion simply increase the Value of the ProgressBar by one.
Once all images have been downloaded (i.e. Value == Maximum) then you know you can remove your loading indicator.
You should probably also think about provding a way for the user to cancel the download and whether you really must download all the images before the app can be used.

Resources