I was wondering how I can download an MP4 video file from a URI and save it to the media library on Windows Phone 8.1.
It would be great if it worked in a Universal App - but it doesn't have to.
I found this code to save an image to the camera roll - do I go the same way about this with an *.mp4 to save it to the video library? And can I just hand off a download stream (not sure if that makes sense) to that function?
StorageFolder testFolder = await StorageFolder.GetFolderFromPathAsync(#"C:\test");
StorageFile sourceFile = await testFolder.GetFileAsync("TestImage.jpg");
StorageFile destinationFile = await KnownFolders.CameraRoll.CreateFileAsync("MyTestImage.jpg");
using (var sourceStream = await sourceFile.OpenReadAsync())
{
using (var sourceInputStream = sourceStream.GetInputStreamAt(0))
{
using (var destinationStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite))
{
using (var destinationOutputStream = destinationStream.GetOutputStreamAt(0))
{
await RandomAccessStream.CopyAndCloseAsync(sourceInputStream, destinationStream);
}
}
}
}
So I finally figured it out, this is what my code looks like:
var httpClient = new HttpClient();
var response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var file = await response.Content.ReadAsByteArrayAsync();
StorageFile destinationFile
= await KnownFolders.SavedPictures.CreateFileAsync("file.mp4",
CreationCollisionOption.ReplaceExisting);
Windows.Storage.Streams.IRandomAccessStream stream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite);
IOutputStream output = stream.GetOutputStreamAt(0);
DataWriter writer = new DataWriter(output);
writer.WriteBytes(file);
await writer.StoreAsync();
await output.FlushAsync();
}
Related
I recorded sound with the device's microphone but I don't know how to save it. Is it with the help of MediaCapture element, and if yes, then how to do it?
Here is a basic idea how to convert to mp3 and save in a file with Datawriter.
I wrote this code on the fly so its not tested.
MediaEncodingProfile _Profile = Windows.Media.MediaProperties.MediaEncodingProfile.CreateMp3(AudioEncodingQuality.High);
MediaTranscoder _Transcoder = new Windows.Media.Transcoding.MediaTranscoder();
CancellationTokenSource _cts = new CancellationTokenSource();
private void ConvertSteamToMp3()
{
IRandomAccessStream audio = buffer.CloneStream(); //your recoreded InMemoryRandomAccessStream
var folder = KnownFolders.MusicLibrary.CreateFolderAsync("MyCapturedAudio", CreationCollisionOption.OpenIfExists);
outputFile = await folder.CreateFileAsync("record.mp3", CreationCollisionOption.GenerateUniqueName);
using (IRandomAccessStream fileStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
{
var preparedTranscodeResult = await _Transcoder.PrepareStreamTranscodeAsync(audio, fileStream, _Profile);
if (preparedTranscodeResult.CanTranscode)
{
var progress = new Progress<double>(TranscodeProgress);
await preparedTranscodeResult.TranscodeAsync().AsTask(_cts.Token, progress);
}
using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
{
using (DataWriter dataWriter = new DataWriter(outputStream))
{
//TODO: Replace "Bytes" with the type you want to write.
dataWriter.WriteBytes(bytes);
await dataWriter.StoreAsync();
dataWriter.DetachStream();
}
await outputStream.FlushAsync();
}
}
}
Or just save the stream in a file
public async SaveToFile()
{
IRandomAccessStream audio = buffer.CloneStream(); //your recoreded InMemoryRandomAccessStream
var folder = KnownFolders.MusicLibrary.CreateFolderAsync("MyCapturedAudio", CreationCollisionOption.OpenIfExists);
outputFile = await folder.CreateFileAsync("record.mp3", CreationCollisionOption.GenerateUniqueName);
using (IRandomAccessStream fileStream = await outputFile.OpenAsync(FileAccessMode.ReadWrite))
{
await RandomAccessStream.CopyAndCloseAsync(audio.GetInputStreamAt(0), fileStream.GetOutputStreamAt(0));
await audio.FlushAsync();
audio.Dispose();
}
});
}
I'm trying to implement a StreamSocket communication and the server is now sending me a ".zip" file in byte[] chuncks. It looks like my byte[] in memory is fine (amount of bytes are the same as original .zip file in the server) but when I save those bytes in a file the unzip program says it's 'corrupted'.
I've tried several options but none of them worked for me:
1
var file = await StorageFile.CreateFileAsync();
using(var stream = await file.OpenStreamForWriteAsync())
{
stream.Write(myBytes, ...);
}
2
var file = await StorageFile.CreateFileAsync();
await FileIO.WriteBytesAsync(file, myBytes);
3
var file = await StorageFile.CreateFileAsync();
using (var fileStream = await file.OpenStreamForWriteAsync())
{
var sessionData = new MemoryStream(myBytes);
sessionData.Seek(0, SeekOrigin.Begin);
await sessionData.CopyToAsync(fileStream);
}
4
var file = await StorageFile.CreateFileAsync();
using (var writer = new BinaryWriter(await file.OpenStreamForWriteAsync())
{
writer.WriteBytes(myBytes);
}
If anyone has some new ideas please share.
Regards.
How do I download and store a jpeg image from the internet in a Windows Store App with Windows.Web.Http?
The problem that I am facing is that I don't know what Get…Async and Write…Async method I must use for an image? It is very different with files, than with strings.
Only Windows.Web.Http!
No third-party solutions!
If you suggest something else, please use the comment section, not the answer. Thank you!
…
using Windows.Storage;
using Windows.Web.Http;
Uri uri = new Uri("http://image.tmdb.org/t/p/w300/" + posterPath);
HttpClient httpClient = new HttpClient();
// I guess I need to use one of the Get...Async methods?
var image = await httpClient.Get…Async(uri);
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFolder cachedPostersFolder = await localFolder.CreateFolderAsync("cached posters", CreationCollisionOption.OpenIfExists);
StorageFile posterFile = await cachedPostersFolder.CreateFileAsync(posterPath, CreationCollisionOption.ReplaceExisting);
// I guess I need to use one of the Write...Async methods?
await FileIO.Write…Async(posterFile, image);
You can get a buffer using the GetBufferAsync method and then call the FileIO.WriteBufferAsync to write the buffer to a file:
Uri uri = new Uri("http://i.stack.imgur.com/ZfLdV.png?s=128&g=1");
string fileName = "daniel2.png";
StorageFile destinationFile = await KnownFolders.PicturesLibrary.CreateFileAsync(
fileName, CreationCollisionOption.GenerateUniqueName);
HttpClient client = new HttpClient();
var buffer = await client.GetBufferAsync(uri);
await Windows.Storage.FileIO.WriteBufferAsync(destinationFile, buffer);
image1.Source = new BitmapImage(new Uri("http://www.image.com/image.jpg", UriKind.RelativeOrAbsolute));
using (var mediaLibrary = new MediaLibrary())
{
using (var stream = new MemoryStream())
{
var fileName = string.Format("Gs{0}.jpg", Guid.NewGuid());
bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 100);
stream.Seek(0, SeekOrigin.Begin);
var picture = mediaLibrary.SavePicture(fileName, stream);
if (picture.Name.Contains(fileName)) return true;
}
}
This is a similar answer to John's, however in WP8.1 you can't use GetBufferAsync. Instead you can use GetStreamAsync in the way that I have:
Uri uri = new Uri(UriString);
string fileName = p4.IconLocation;
HttpClient client = new HttpClient();
var streamImage = await client.GetStreamAsync(uri);
await SaveToLocalFolderAsync(streamImage, fileName);
using the function:
public async Task SaveToLocalFolderAsync(Stream file, string fileName)
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
StorageFile storageFile = await localFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
using (Stream outputStream = await storageFile.OpenStreamForWriteAsync())
{
await file.CopyToAsync(outputStream);
}
}
I am trying to save an image from the web to local storage to be manipulated later, but it appears to be corrupt and attempting to open it with an external application fails. Opening the image in the webbrowser works completely normally. Thanks for any help.
var client = new HttpClient();
var clientResponse = await client.GetByteArrayAsync(imageUri);
var temp = ApplicationData.Current.TemporaryFolder;
StorageFile file;
if ((await temp.GetFilesAsync()).Any(f => f.Name == "temp_image.png")) {
file = await temp.GetFileAsync("tempcolorizer.png");
} else {
file = await temp.CreateFileAsync("temp_image.png");
}
using (var fs = await file.OpenReadAsync())
using (var writer = new DataWriter(fs)) {
writer.WriteBytes(clientResponse);
}
You have to call StoreAsync:
using (var fs = await file.OpenReadAsync())
using (var writer = new DataWriter(fs)) {
writer.WriteBytes(clientResponse);
await writer.StoreAsync();
}
In WinRT / C#, How do I download an image to a local folder to support caching of an online catalogue for offline use? is there a way to directly download the images and link the control to get them from the cache as a fallback?
var downloadedimage = await HttpWebRequest.Create(url).GetResponseAsync();
StorageFile imgfile = await ApplicationData.Current.LocalFolder.CreateFileAsync(
"localfile.png", CreationCollisionOption.FailIfExists);
What do I do next to store downloadedimage as localfile.jpg?
Looks like the code below from the HttpClient sample for Windows 8 solves the issue
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Get, resourceAddress);
HttpResponseMessage response = await rootPage.httpClient.SendAsync(request,
HttpCompletionOption.ResponseHeadersRead);
httpClient is a HttpClient, and its BaseAddress needs to be set a the server folder of your resource. we can then do this to convert that to an image source (if that's what we're downloading)
InMemoryRandomAccessStream randomAccessStream =
new InMemoryRandomAccessStream();
DataWriter writer = new DataWriter(randomAccessStream.GetOutputStreamAt(0));
writer.WriteBytes(await response.Content.ReadAsByteArrayAsync());
await writer.StoreAsync();
BitmapImage image = new BitmapImage();
imagecontrol.SetSource(randomAccessStream);
or this to write it to file
var imageFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(
filename, CreationCollisionOption.ReplaceExisting);
var fs = await imageFile.OpenAsync(FileAccessMode.ReadWrite);
DataWriter writer = new DataWriter(fs.GetOutputStreamAt(0));
writer.WriteBytes(await response.Content.ReadAsByteArrayAsync());
await writer.StoreAsync();
writer.DetachStream();
await fs.FlushAsync();
Try this:
var response = await HttpWebRequest.Create(url).GetResponseAsync();
List<Byte> allBytes = new List<byte>();
using (Stream imageStream = response.GetResponseStream())
{
byte[] buffer = new byte[4000];
int bytesRead = 0;
while ((bytesRead = await imageStream.ReadAsync(buffer, 0, 4000)) > 0)
{
allBytes.AddRange(buffer.Take(bytesRead));
}
}
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync(
"localfile.png", CreationCollisionOption.FailIfExists);
await FileIO.WriteBytesAsync(file, allBytes.ToArray());
If you want to download a file represented by a URL, the easiest way is to use the BackgroundDownloader class. See this page for more information on how to use the background downloader.
GetResponseAsync will give you a WebResponse file not the image:
Stream imageStream = downloadedimage.GetResponseStream();
Then you can write to the image file:
byte[] imageData = new byte[imageStream.Length];
using(StreamReader reader = new Streamreader(imageStream))
{
reader.ReadBytes(imageData, 0, imageData.Length);
}
await FileIO.WriteBytesAsync(imgfile, imageData);
By default Bitmap Images are cached by WinRT with no intervention required by the developer.