How to first read and the write to a file - windows-runtime

I am trying to read tags, change tags,, and then and write back data to the same file. Reading tags is no problem but write are not working. Data seems not to be saved to disk.
My test case.
var file = await KnownFolders.MusicLibrary.GetFileAsync("sampleUnderTest.wav");
var content = await ReadFileAsynch(file);
content.Add("newTag","newValue")
await SubmittFileAsynch(file, content)
var newContent = await ReadFileAsynch(file);
Assert.NotEqual(content,newContent)
The Assert throws a Exception because content and newContent are identical.
This is part my code:
public async Task SubmittFileAsynch(StorageFile file, Content content)
{
var accessStream = await file.OpenAsync(FileAccessMode.ReadWrite);
using (accessStream)
await CommitAsynch(accessStream, content);
}
internal async Task CommitAsynch(IRandomAccessStream accessStream, Content content)
{
List<byte[]> tbw = new List<byte[]>();
using (var InStream = accessStream.AsStreamForRead())
{
using (var br = new BinaryReader(InStream))
{
//Reads file until it reaches the part of the containing tags and
//that are going to be modified by content.
//tbw is created from data in content and from the read process.
await BuildAsync(br, content, tbw);
using (var outstream = (accessStream.GetOutputStreamAt(0)))
using (var bw = new DataWriter(outstream))
{
await CommitAsync(tbw, bw);
await bw.FlushAsync();
}
}
}
}
private async Task CommitAsync(List<byte[]> tbw, DataWriter bw)
{
await Task.Run(() =>
{
foreach (byte[] buf in tbw)
bw.WriteBytes(buf);
});
}
I can't see what I am doing wrong ,, and are hoping for some help.
//lg

I am back smile
Finally I solved my problem. There where some threading issues in my code. I changed the write part to:
using (var bw = new DataWriter(outstream))
{
//await CommitAsync(tbw, bw);
foreach (byte[] buf in tbw)
bw.WriteBytes(buf);
await bw.StoreAsync();
bw.DetachStream();
}
await outstream.FlushAsync();
Now it works nicely. I am not sure if there are som part of the code that are redundant,, with respect to the "using" clause.
If anyone can tip me about some good reading regarding fileIO, streams etc,,, I would be greatful. All that I found on internet,, was very basic,,
Hope this will help someone else.

Related

Puppeteer: how to access/intercept a FileSystemDirectoryHandle?

I'm wondering if it's possible within puppeteer to access a FileSystemDirectoryHandle (from the File System Access API). I would like to pass in a directory path via puppeteer as though the user had selected a directory via window.showDirectoryPicker(). On my client page I use the File System Access API to write a series of png files taken from a canvas element, like:
const directoryHandle = await window.showDirectoryPicker();
for (let frame = 0; frame < totalFrames; frame++){
const fileHandle = await directoryHandle.getFileHandle(`${frame}.png`, { create: true });
const writable = await fileHandle.createWritable();
updateCanvas(); // <--- update the contents of my canvas element
const blob = await new Promise((resolve) => canvas.toBlob(resolve, 'image/png'));
await writable.write(blob);
await writable.close();
}
On the puppeteer side, I want to mimic that behavior with something like:
const page = await browser.newPage();
await page.goto("localhost:3333/canvasRenderer.html");
// --- this part doesn't seem to exist ---
const [dirChooser] = await Promise.all([
page.waitForDirectoryChooser(),
page.click('#choose-directory'),
]);
await dirChooser.accept(['save/frames/here']);
//--------------------------------------
but waitForDirectoryChooser() doesn't exist.
I'd really appreciate any ideas or insights on how I might accomplish this!

getUserMedia and mediarecorder in html

I record audio via getUserMedia and mediarecorder:
...
navigator.mediaDevices.getUserMedia(constraints).then(mediaStream => {
try {
const mediaRecorder = new MediaRecorder(mediaStream);
mediaRecorder.ondataavailable = vm.mediaDataAvailable;
mediaRecorder.start(1000);
...
When I receive the chucks in the callback, I send them to a web api via websockets, which simply writes the parts one after another to a file:
mediaDataAvailable(e) {
if (!event.data || event.data.size === 0)
{
return;
}
vm.websocket.SendBlob(e.data);
...
The file, which is created on the webserver side in the webapi (lets call it "server.webm"), does not work correct. More exactly: It plays the first n seconds (n is the time I chose for the start command), the it stops. This means, the first chunk is transferred correctly, but it seams that adding the 2nd, 3rd, ... chuck together to a file does not work. If I push the chuncks in the web page on an array and the to a file, the resulting file (lets call it "client.webm") is working the whole recording duration.
Creating file on web client side:
mediaDataAvailable(e) {
if (!event.data || event.data.size === 0)
{
return;
}
vm.chuncks.push(e.data);
...
stopCapturing() {
var blob = new Blob(this.chuncks, {type: 'audio/webm'});
var url = window.URL.createObjectURL(blob);
var a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'client.webm';
document.body.appendChild(a);
a.click();
I compared the files client.webm and server.webm. They are quite similar, but there are certain parts in the server.webm which are not in the client.webm.
Anybody any ideas? Server code looks like the following:
private async Task Echo( HttpContext con, WebSocket webSocket)
{
System.IO.BinaryWriter Writer = new System.IO.BinaryWriter(System.IO.File.OpenWrite(#"server.webm"));
var buffer = new byte[1024 * 4];
WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
while (!result.CloseStatus.HasValue)
{
Writer.Write(buffer);
Writer.Flush();
await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None);
result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
}
await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
Writer.Close();
}
resolved, I write all bytes of the reserved byte array to file in server code, not the count of received bytes.

Confused on how notes = JSON.parse(noteString);

var addnote = function (title, body) {
var notes = [];
var note = {
title: title,
body: body
}
need explanation on the two lines under try
try {
var noteString = fs.readFileSync("data.json");
notes = JSON.parse(noteString);
} catch (e) {
}
And explanation on how duplicateNotes works ..
var duplicateNotes = notes.filter(function(note){
return note.title === title
})
if (duplicateNotes.length === 0) {
notes.push(note);
fs.writeFileSync("data.json", JSON.stringify(notes));
}
}
JSON.parse converts a JSON object to String.
{
field1:field1Value,
field2:fieldValue
}
If this is in Json format you can access it's elements using JSONObjectName.fieldName
But,if it's converted to String it looses it's JSON properties. You can't access fields in same way. Output will act like String.
need explanation on the two lines under try
var noteString = fs.readFileSync("data.json");
There are two kinds of response back asynchronous and synchronous. Synchronous call is like you will not start playing until you get a pass and score a goal. But, Asynchronous call is like you start playing with your friend but, you run near him and, there is a promise you won't shoot until you get the ball.
readFileSync will read the file and the next line will wait until it gets the pass.JSON.parse() will convert file content to JSON object.
And explanation on how duplicateNotes works ..
var duplicateNotes = notes.filter(function(note){
return note.title === title
})
Whenever a match is found , that element in notes will be pushed to duplicate note. That's all.

Play an audio from an arraybuffer of bytes?

I Have a bufferarray comes from a rest endpoint I have created with Java that returns a byte[] array ; so I managed to get the array with HTTP (I am using Angular) now I want to play the audio in the browser. I have done some research and I found the web audio API but the error is that I can not decode the array.
context = new AudioContext();
audioArray : ArrayBuffer;
buf ;
let arrayBuffer = new ArrayBuffer(this.audioArray.byteLength);
let bufferView = new Uint8Array(arrayBuffer);
for (let i = 0; i < this.audioArray.byteLength; i++) {
bufferView[i] = this.audioArray[i];
}
console.log(arrayBuffer);
// this function should decode the array but the error occurs
// DOMException: Unable to decode audio data
this.context.decodeAudioData(this.audioArray).then((buffer)=>{
this.buf = buffer;
this.play();
}).catch((error)=>{
console.log(error);
});
console.log(this.audioArray);
play() {
let source = this.context.createBufferSource();
source.buffer = this.buf;
source.connect(this.context.destination);
source.start(0);
}
And I am getting the array in ngOnInit function by calling the rest API:)
this.radioService.generateVoiceMethode().subscribe(res => {
console.log(res);
this.audioArray = new ArrayBuffer(res.byteLength);
this.audioArray = res;
console.log(this.audioArray);
});
Though this is an old question, I am sharing an answer that worked for me. May be useful for some one in the future.
async play(data: ArrayBuffer) {
const context = new AudioContext();
const buffer = await context.decodeAudioData(data);
const source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start();
}
The code above works in Angular 8.

Get a uri from a LocalStorage in Windows Phone

I write the following code to save some images from internet:
public static async Task SaveImage(string name, string uri)
{
var localfolder = ApplicationData.Current.LocalFolder;
var client = new HttpClient();
var imageStream = await client.GetStreamAsync(uri); //Secuencia de bytes
var storageFile = await localfolder.CreateFileAsync(name, CreationCollisionOption.ReplaceExisting);
using (Stream outputStream = await storageFile.OpenStreamForWriteAsync())
{
await imageStream.CopyToAsync(outputStream);
}
}
My problem is when I try to set these images store in the Local Storage to a CycleTile because this class needs the Uri's, and I don't know how to provide the uri here. This is what I have:
CycleTileData cycleicon = new CycleTileData();
cycleicon.Title = "Fotopantalla";
cycleicon.Count = 0;
cycleicon.SmallBackgroundImage = new Uri("/Assets/Tiles/FlipCycleTileSmall.png", UriKind.RelativeOrAbsolute);
List<Uri> images = new List<Uri>();
for (int i = 0; i < 9; i++)
{
/// tries...
string path1 = "ms-appdata:///local/image" + i + ".jpg";
string path2 = "isostore:/Shared/ShellContent/image" + i + ".jpg";
string path3 = "ms-appdata:///Local/Shared/ShellContent/image" + i + ".jpg";
///
Uri uri = new Uri(path2, UriKind.RelativeOrAbsolute);
images.Add(uri);
}
cycleicon.CycleImages = images;
What am I wrong or what am I missing?
For any ShellTileData related data structures you have to use path2:
"isostore:/Shared/ShellContent/*" if the images are not in the (read only) InstalledLocation folder.
For more details see: http://blogs.msdn.com/b/andy_wigley/archive/2013/04/10/live-apps-creating-custom-tile-and-lock-screen-images.aspx
I have something similar in my code:
var store = IsolatedStorageFile.GetUserStoreForApplication();
if (!store.DirectoryExists("Shared/ShellContent"))
{
store.CreateDirectory("Shared/ShellContent");
}
StorageFolder shellContent = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFolderAsync("Shared", CreationCollisionOption.OpenIfExists);
shellContent = await shellContent.CreateFolderAsync("ShellContent", CreationCollisionOption.OpenIfExists);
Stream imgin = picture.GetImage();
//Picture read stream from Media Library or other input stream
StorageFile new_img = await shellContent.CreateFileAsync(newPictureName);
Stream imgout = await new_img.OpenStreamForWriteAsync();
imgin.CopyTo(imgout);
imgout.Close(); // <- necessary in your code or not?
imgin.Close(); // <-
I'm not sure, whether you really need the Isostore thing at the beginning, but it works, if I haven't done some stupid mistake while shortening the code. ;-)
Also have a look at "StandardTileData.BackgroundImage Property", "Data for Windows Phone" and "How to use the Isolated Storage Explorer tool for Windows Phone" from Microsoft's Dev Center. (The last one is about how to have a look at the saved image file on your device.)