private static async Task EchoRecording(HttpContext context, WebSocket webSocket)
{
//string path = #"E:\Recording.mp4";
var path = Path.Combine("wwwroot", "SaveRecord", "Recording.mp4");
var buffer = new byte[1024 * 8];
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
using (var stream = new FileStream(path, FileMode.Append))
try
{
await stream.WriteAsync(buffer, 0, result.Count);
}
catch (Exception ex)
{
}
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}
Stream is saving successfully, But duration and length of video is not saving when viewing.
Should i use anything instead of filestream?
Related
I'm trying voice recognition with a websocket enabled speech recognition API in C#.
According to this API, if voice data (binary) is sent sequentially, the recognition result at that time will be returned.
I send data continuously with the following code, but I can not get the preliminary recognition result.
Only the final recognition result is obtained.
I think that the part that sends voice data is inappropriate as a cause, but I do not understand how it is wrong.
I do not know so much about websokcet, and I think that there is a strange part in that sending part. Please tell me about the correct sending method.
This is the API I'm using.
https://mimi.readme.io/docs/mimi-websocket-api-spec
(old)
static async Task Send(ClientWebSocket ws)
{
ArraySegment<byte> closingMessage = new ArraySegment<byte>(Encoding.UTF8.GetBytes(
"{\"command\": \"recog-break\"}"
));
using (FileStream fs = File.OpenRead("voice.raw"))
{
byte[] b = new byte[3200];
while (fs.Read(b, 0, b.Length) > 0)
{
await ws.SendAsync(new ArraySegment<byte>(b), WebSocketMessageType.Binary, true, CancellationToken.None);
}
await ws.SendAsync(closingMessage, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
(new)
static async Task SendAudio(ClientWebSocket ws)
{
ArraySegment<byte> closingMessage = new ArraySegment<byte>(Encoding.UTF8.GetBytes(
"{\"command\": \"recog-break\"}"
));
using (FileStream fs = File.OpenRead("audio.raw"))
{
byte[] b = new byte[3200];
while (fs.Read(b, 0, b.Length) > 0)
{
await ws.SendAsync(new ArraySegment<byte>(b, 0, fs.Read(b, 0, b.Length)), WebSocketMessageType.Binary, true, CancellationToken.None);
}
await ws.SendAsync(closingMessage, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
(new2)
private async Task SendAudio(ClientWebSocket ws)
{
ArraySegment<byte> closingMessage = new ArraySegment<byte>(Encoding.UTF8.GetBytes(
"{\"command\": \"recog-break\"}"
));
using (FileStream fs = File.OpenRead("audio.raw"))
{
byte[] b = new byte[3200];
while (true)
{
int temp = fs.Read(b, 0, b.Length);
if (temp == 0)
break;
await ws.SendAsync(new ArraySegment<byte>(b, 0, temp), WebSocketMessageType.Binary, true, CancellationToken.None);
}
await ws.SendAsync(closingMessage, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
I am trying to get progress of an api along with the response. ResponseHeadersRead works fine to get the progress but I can't figure out why it doesn't return the response.
Download part
public async Task StartDownload()
{
_httpClient = new HttpClient { Timeout = TimeSpan.FromDays(1), };
using (var response = await _httpClient.GetAsync(_downloadUrl, HttpCompletionOption.ResponseHeadersRead))
{
await DownloadFileFromHttpResponseMessage(response);
string strResp = await response.Content.ReadAsStringAsync();
Debug.WriteLine(strResp); // Doesn't print anything
}
}
Reading Stream part
private async Task DownloadFileFromHttpResponseMessage(HttpResponseMessage response)
{
response.EnsureSuccessStatusCode();
var totalBytes = response.Content.Headers.ContentLength;
using (var contentStream = await response.Content.ReadAsStreamAsync())
{
await ProcessContentStream(totalBytes, contentStream);
}
}
The code is actually from another answer.
I am just not getting the response. If I use ResponseContentRead I get response but it defeats the purpose of progress.
EDIT
ProcessContentStream code - This part read the response as it comes bit by bit and posts the progress in TriggerProgressChanged
private async Task ProcessContentStream(long? totalDownloadSize, Stream contentStream)
{
var totalBytesRead = 0L;
var readCount = 0L;
var buffer = new byte[8192];
var isMoreToRead = true;
using (var fileStream = new FileStream(DestinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
{
do
{
var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
if (bytesRead == 0)
{
isMoreToRead = false;
//TriggerProgressChanged(totalDownloadSize, totalBytesRead);
continue;
}
await fileStream.WriteAsync(buffer, 0, bytesRead);
totalBytesRead += bytesRead;
readCount += 1;
if (readCount % 100 == 0)
{
//TriggerProgressChanged(totalDownloadSize, totalBytesRead);
}
}
while (isMoreToRead);
}
}
Post the progress
private void TriggerProgressChanged(long? totalDownloadSize, long totalBytesRead)
{
if (ProgressChanged == null)
return;
double? progressPercentage = null;
if (totalDownloadSize.HasValue)
progressPercentage = Math.Round((double)totalBytesRead / totalDownloadSize.Value * 100, 2);
ProgressChanged(totalDownloadSize, totalBytesRead, progressPercentage);
}
ProgressChanged is a delegate method.
Project link
Ok so I found the solution. I needed to read the file on which I wrote the bytes as it was coming in with a StreamReader. Reading file with StreamReader has been explained here.
private async Task DownloadFileFromHttpResponseMessage(HttpResponseMessage response)
{
response.EnsureSuccessStatusCode();
var totalBytes = response.Content.Headers.ContentLength;
using (var contentStream = await response.Content.ReadAsStreamAsync())
{
await ProcessContentStream(totalBytes, contentStream);
// Added code
char[] buffer;
using (StreamReader sr = new StreamReader(DestinationFilePath))
{
buffer = new char[(int)sr.BaseStream.Length];
await sr.ReadAsync(buffer, 0, (int)sr.BaseStream.Length);
}
Debug.WriteLine(new string(buffer)); // Now it prints the response
}
}
I want to take the screenshot in my application and want to save it in local folder of app with unique name.
so please help me.
You can capture you screen using RenderTargetBitmap. Try this code:
//create and capture Window
var renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(Window.Current.Content);
//create unique file in LocalFolder
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("screenshotCapture.jpg", CreationCollisionOption.GenerateUniqueName);
//create JPEG image
using (var stream = await file.OpenStreamForWriteAsync())
{
var logicalDpi = DisplayInformation.GetForCurrentView().LogicalDpi;
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream.AsRandomAccessStream());
encoder.SetPixelData(BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Straight,
(uint)renderTargetBitmap.PixelWidth,
(uint)renderTargetBitmap.PixelHeight, logicalDpi, logicalDpi,
pixelBuffer.ToArray());
await encoder.FlushAsync();
}
Or
public static async Task<StorageFile> AsUIScreenShotFileAsync(this UIElement elememtName, string ReplaceLocalFileNameWithExtension)
{
StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(ReplaceLocalFileNameWithExtension, CreationCollisionOption.ReplaceExisting);
try
{
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();
// Render to an image at the current system scale and retrieve pixel contents
await renderTargetBitmap.RenderAsync(elememtName);
var pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
// Encode image to an in-memory stream
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)renderTargetBitmap.PixelWidth, (uint)renderTargetBitmap.PixelHeight,
DisplayInformation.GetForCurrentView().LogicalDpi,
DisplayInformation.GetForCurrentView().LogicalDpi, pixelBuffer.ToArray());
await encoder.FlushAsync();
//CreatingFolder
// var folder = Windows.Storage.ApplicationData.Current.LocalFolder;
RandomAccessStreamReference rasr = RandomAccessStreamReference.CreateFromStream(stream);
var streamWithContent = await rasr.OpenReadAsync();
byte[] buffer = new byte[streamWithContent.Size];
await streamWithContent.ReadAsync(buffer.AsBuffer(), (uint)streamWithContent.Size, InputStreamOptions.None);
using (IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter dataWriter = new DataWriter(outputStream))
{
dataWriter.WriteBytes(buffer);
await dataWriter.StoreAsync(); //
dataWriter.DetachStream();
}
// write data on the empty file:
await outputStream.FlushAsync();
}
await fileStream.FlushAsync();
}
// await file.CopyAsync(folder, "tempFile.jpg", NameCollisionOption.ReplaceExisting);
}
catch (Exception ex)
{
Reporting.DisplayMessageDebugExemption(ex.Message);
}
return file;
}
I am trying to download and save a file in the isolated storage.
This is my attempt of downloading the file
Task.Run(async () => { await DownloadFileFromWeb(new Uri(#"http://main.get4mobile.net/ringtone/ringtone/ibMjbqEYMHUnso8MErZ_UQ/1452584693/fa1b23bb5e35c8aed96b1a5aba43df3d/stefano_gambarelli_feat_pochill-land_on_mars_v2.mp3"), "mymp3.mp3"); }).Wait();
public static Task<Stream> DownloadFile(Uri url)
{
var tcs = new TaskCompletionSource<Stream>();
var wc = new WebClient();
wc.OpenReadCompleted += (s, e) =>
{
if (e.Error != null) tcs.TrySetException(e.Error);
else if (e.Cancelled) tcs.TrySetCanceled();
else tcs.TrySetResult(e.Result);
};
wc.OpenReadAsync(url);
return tcs.Task;
}
public static async Task<Problem> DownloadFileFromWeb(Uri uriToDownload, string fileName)
{
using (Stream mystr = await DownloadFile(uriToDownload))
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream file = new IsolatedStorageFileStream(fileName, FileMode.OpenOrCreate, isf))
{
using (var fs = new StreamWriter(file))
{
byte[] bytesInStream = new byte[mystr.Length];
mystr.Read(bytesInStream, 0, (int)bytesInStream.Length);
file.Write(bytesInStream, 0, bytesInStream.Length);
file.Flush();
}
}
}
return Problem.Ok;
}
Obviously I am doing something wrong here since the file is never and the app is stack forever after the call.
However I believe I am not far from getting there.
Any help is greatly appreciated.
Add this methid and call it from there, it should work.
Downlaod_Click()
public static async void Downlaod_Click()
{
var cts = new CancellationTokenSource();
Problem fileDownloaded = await MainHelper.DownloadFileFromWeb(new Uri(#"url", UriKind.Absolute), "myfile.mp3", cts.Token);
switch (fileDownloaded)
{
case Problem.Ok:
MessageBox.Show("File downloaded");
break;
case Problem.Cancelled:
MessageBox.Show("Download cancelled");
break;
case Problem.Other:
default:
MessageBox.Show("Other problem with download");
break;
}
}
IsolatedStorage is not available in windows 8.1. So you might use following code for Windows 8.1 app, which works fine:
Task.Run(async () => { await DownloadFileFromWeb(new Uri(#"http://main.get4mobile.net/ringtone/ringtone/ibMjbqEYMHUnso8MErZ_UQ/1452584693/fa1b23bb5e35c8aed96b1a5aba43df3d/stefano_gambarelli_feat_pochill-land_on_mars_v2.mp3"), "mymp3.mp3"); }).Wait();
public static async Task<Stream> DownloadFile(Uri url)
{
var tcs = new TaskCompletionSource<Stream>();
HttpClient http = new System.Net.Http.HttpClient();
HttpResponseMessage response = await http.GetAsync(url);
MemoryStream stream = new MemoryStream();
ulong length = 0;
response.Content.TryComputeLength(out length);
if (length > 0)
await response.Content.WriteToStreamAsync(stream.AsOutputStream());
stream.Position = 0;
return stream;
}
public static async Task<string> DownloadFileFromWeb(Uri uriToDownload, string fileName)
{
using (Stream stream = await DownloadFile(uriToDownload))
{
StorageFolder local = Windows.Storage.ApplicationData.Current.LocalFolder;
var file = await local.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
stream.Position = 0;
using (Stream fileStream = await file.OpenStreamForWriteAsync())
{
stream.CopyTo(fileStream);
}
return file.Path;
}
}
I'm trying to save a zip file stream that I've downloaded from a server.
Now I've the Stream But I'm not able to save to a file. here is my attempt =>
private async Task DownloadCompleted(Stream inputStream, CancellationToken ct)
{
var file = await _downloadFolder.CreateFileAsync(_productDescription.ProductFileName, CreationCollisionOption.ReplaceExisting, ct);
using (Stream str = await file.OpenAsync(FileAccess.ReadAndWrite, ct))
{
await inputStream.CopyToAsync(str);
}
}
I'm trying to do it Xamarin.Android Project, I'm not good at streams, Also some good pointer are highly appreciated.
Edit- here I got the stream
private async Task DownloadFileFromUrl(string url, CancellationToken ct)
{
try
{
var receivedBytes = 0;
using (var client = new WebClient())
using (var stream = await client.OpenReadTaskAsync(url))
{
var buffer = new byte[4096];
var totalBytes = int.Parse(client.ResponseHeaders[HttpResponseHeader.ContentLength]);
for (;;)
{
var bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, ct);
if (bytesRead == 0)
{
await Task.Yield();
break;
}
receivedBytes += bytesRead;
if (_downloadProgressHandler != null)
{
_downloadProgressHandler((int)(((double)receivedBytes / totalBytes) * 100), false);
}
}
await DownloadCompleted(stream, ct);
}
}
catch (System.OperationCanceledException)
{
throw;
}
catch (Exception ex)
{
Analytics.AddHandledExceptionEvent(ex, "Ex-ProductDownloader-DownloadFileFromUrl");
throw new NetworkNotAvailableException("");
}
}