Reduce Video Size Xamarin Forms - c#

I use Media Plugin to Pick video from ios and Android devices, but size of stream is very large,
my question is how reduce this stream to send to server.
var file = await CrossMedia.Current.PickVideoAsync();
if (file != null)
{
stream = file.GetStream();
byte[] result;
using (var streamReader = new MemoryStream())
{
stream.CopyTo(streamReader);
result = streamReader.ToArray();
}
}

You could set the CompressionQuality, which is a value from 0 the most compressed all the way to 100 .
var file = await CrossMedia.Current.TakeVideoAsync(new StoreVideoOptions
{
CompressionQuality = 85,
Quality = VideoQuality.Medium
});
Update
using System.IO;
using System.IO.Compression;
public static byte[] Compress(byte[] data)
{
var output = new MemoryStream();
using (var dstream = new DeflateStream(output, CompressionLevel.Optimal))
{
dstream.Write(data, 0, data.Length);
}
return output.ToArray();
}

Related

How can I compress an NBT with gzip?

I want to get a NBT file, decompress it, modify it, and then re-compress it. The only problem is re-compressing. Unlike just using GZipStream and calling it a day, Minecraft (and standalone NBT editors) can't read it.
public static void PatchNBT()
{
var data = File.ReadAllBytes(#"level.temp"); // Reads all bytes of the uncompressed NBT
var GetDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "level.dat");
Console.WriteLine(GetDirectory);
Console.ReadKey();
if (File.Exists("level.dat"))
{
File.Move("level.dat", "level.bak");
}
Task.WaitAll();
File.WriteAllBytes(GetDirectory, CompressGZip(data));
}
static byte[] CompressGZip(byte[] raw)
{
using (MemoryStream memory = new MemoryStream())
{
using (GZipStream gzip = new GZipStream(memory, CompressionLevel.Optimal))
{
gzip.Write(raw, 0, raw.Length);
}
return memory.ToArray();
}
}

Problem in cross platform (Convert 2 channel wav to mono wav in C#)

below code is only work in Window server.but i want its should also work in Linux server.Convert 2 channel wav to mono wav.please help
public static byte[] ConvertWavTo8000Hz16BitMonoWav(byte[] inArray)
{
using (var mem = new MemoryStream(inArray))
{
using (var reader = new WaveFileReader(mem))
{
using (var converter =
WaveFormatConversionStream.CreatePcmStream(reader))
{
using (var upsampler = new WaveFormatConversionStream(new
WaveFormat(8000, 16, 1), converter))
{
byte[] data;
using (var m = new MemoryStream())
{
upsampler.CopyTo(m);
data = m.ToArray();
}
using (var m = new MemoryStream())
{
// to create a propper WAV header (44 bytes),
//which begins with RIFF
var w = new WaveFileWriter(m, upsampler.WaveFormat);
// append WAV data body
w.Write(data,0,data.Length);
return m.ToArray();
}
}
}
}
}
}

'System.IO.InvalidDataException' In Stream.Read operation

I am compressing a json using deflate compression technique and saving to sql server database. The json contains values from any culture ie. th-TH, zh-TW. The compressed string is getting saved successfully in database.
Json includes data like {"#id":"2113","description":"อาหารเช้าคอนติเนนทัล"}
Now when i read the same data from db, i convert it to bytes as
Encoding encoding = Encoding.UTF8;
encoding.GetBytes(data ?? string.Empty)
The compression like this
public static string Compress(this string data, CompressionTypeOptions compressionType)
{
var bytes = Compress(Encoding.UTF-8.GetBytes(data ?? string.Empty), compressionType);
return Encoding.UTF-8.GetString(bytes);
}
}
private static byte[] Compress(byte[] data, CompressionTypeOptions compressionType)
{
using (var memoryStream1 = new MemoryStream(data))
{
using (var memoryStream2 = new MemoryStream())
{
using (var compressionStream = CreateCompressionStream(compressionType, (Stream)memoryStream2,
CompressionMode.Compress))
{
CopyTo((Stream)memoryStream1, compressionStream);
compressionStream.Close();
return memoryStream2.ToArray();
}
}
}
}
Then decompressing like this
using (var memoryStream = new MemoryStream(data))
{
using (var compressionStream = CreateCompressionStream(compressionType, (Stream)memoryStream,
CompressionMode.Decompress))
return ReadAllBytesFromStream(compressionStream);
}
Here is ReadAllBytesFromStream definition
private static byte[] ReadAllBytesFromStream(Stream stream)
{
using (var memoryStream = new MemoryStream())
{
var buffer1 = new byte[1];
while (true)
{
int count = stream.Read(buffer1, 0, 1);
if (count != 0)
memoryStream.Write(buffer1, 0, count);
else
break;
}
var length = memoryStream.Length;
var buffer2 = new byte[length];
memoryStream.Position = 0L;
memoryStream.Read(buffer2, 0, (int)length);
return buffer2;
}
}
Getting error at int count = stream.Read(buffer1, 0, 1); as
'System.IO.InvalidDataException'
'Unknown block type. Stream might be corrupted.'
Any help is appreaciated

Convert wav streamed over HTTP to mp3, in real-time

Background: I am consuming a service which returns data with a MIME type of audio/wav. I need to provide a playback mechanism for this audio (currently built as an MVC application). As an example, my endpoint looks something like https://audio.fooservice.com/GetAudio?audioId=123
The audio is 8kHz, 1-channel u-law.
Due to varying format support across browsers when using the HTML5 <audio> tag, I am unable to use the original u-law wav because Internet Explorer will not play it.
My proposed solution is to do a real-time conversion from the source format to mp3.
I've cobbled together a partially working solution from various other questions here and in the NAudio forums, but it throws an exception as noted in the comments below:
private void NAudioTest(string url)
{
Stream outStream = new MemoryStream();
var format = WaveFormat.CreateMuLawFormat(8000, 1);
using (Stream ms = new MemoryStream())
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
using (Stream stream = request.GetResponse().GetResponseStream())
{
using (var reader = new RawSourceWaveStream(stream, format))
{
// reader is not seekable; we need to convert to a byte array to seek
var bytes = reader.ToByteArray();
// create a new stream from the byte aray
var seekableStream = new MemoryStream(bytes);
// instantiating a WaveFileReader as follows will throw an exception:
// "System.FormatException: Not a WAVE file - no RIFF header"
using (var waveReader = new WaveFileReader(seekableStream))
{
using (var pcmStream = WaveFormatConversionStream.CreatePcmStream(waveReader))
{
var pcmBytes = pcmStream.ToByteArray();
var mp3 = pcmBytes.ToMp3();
}
}
}
}
}
}
public static class StreamExtensions
{
public static byte[] ToByteArray(this Stream stream)
{
var ms = new MemoryStream();
var buffer = new byte[1024];
int bytes = 0;
while ((bytes = stream.Read(buffer, 0, buffer.Length)) > 0)
ms.Write(buffer, 0, bytes);
return ms.ToArray();
}
}
public static class ByteExtensions
{
public static byte[] ToMp3(this byte[] bytes)
{
using (var outStream = new MemoryStream())
{
using (var ms = new MemoryStream(bytes))
{
using (var reader = new WaveFileReader(ms))
{
using (var writer = new LameMP3FileWriter(outStream, reader.WaveFormat, 64))
{
reader.CopyTo(writer);
return outStream.ToArray();
}
}
}
}
}
}
I've been poking around at this for most of the day and I feel like I'm introducing unnecessary complexity into something that seems like it should be fairly straightforward.
Any help would be much appreciated.
Note: I cannot change the source format and supporting IE is a requirement.
EDIT: I resolved the RIFF exception and am able to produce a stream of the MP3, but it's nothing but white noise. Hopefully I can resolve that as well. My new code is as follows:
[HttpGet]
public ActionResult GetMp3(string url)
{
if (String.IsNullOrWhiteSpace(url))
return null;
var muLawFormat = WaveFormat.CreateMuLawFormat(8000, 1);
var compressedStream = new MemoryStream();
using (var ms = new MemoryStream())
{
var request = (HttpWebRequest)WebRequest.Create(url);
request.KeepAlive = false;
request.ProtocolVersion = HttpVersion.Version10;
using (Stream webStream = request.GetResponse().GetResponseStream())
{
var buffer = new byte[4096];
int read;
while (webStream != null && (read = webStream.Read(buffer, 0, buffer.Length)) > 0)
ms.Write(buffer, 0, read);
}
ms.Position = 0;
using (WaveStream wav = WaveFormatConversionStream.CreatePcmStream(new RawSourceWaveStream(ms, muLawFormat)))
using (var mp3 = new LameMP3FileWriter(compressedStream, new WaveFormat(), LAMEPreset.MEDIUM_FAST))
wav.CopyTo(mp3);
}
compressedStream.Seek(0, 0);
return new FileStreamResult(compressedStream, "audio/mpeg");
}
This works for me (and I needed to do exactly what you wanted to do). Hope this helps someone else as well. I used NAudio with LAME.
You have to make sure that you copy the libmp3lamexx.dll files to your webserver's BIN location or to some folder in the %PATH% variable, else it won't work.
string sq = /* URL of WAV file (http://foo.com/blah.wav) */
Response.ContentType = "audio/mpeg";
using (WebClient wc = new WebClient())
{
if (!sq.ToLower().EndsWith(".wav"))
{
byte[] rawFile = wc.DownloadData(sq.Trim());
Response.OutputStream.Write(rawFile, 0, rawFile.Length);
}
else
{
using (var wavReader = new WaveFileReader(new MemoryStream(wc.DownloadData(sq.Trim()))))
{
try
{
using (var wavWriter = new LameMP3FileWriter(Response.OutputStream, wavReader.WaveFormat, LAMEPreset.ABR_128))
{
wavReader.CopyTo(wavWriter);
}
}
catch (ArgumentException)
{
var newFormat = new WaveFormat(wavReader.WaveFormat.SampleRate, 16, 2);
using (var pcmStream = new WaveFormatConversionStream(newFormat, wavReader))
{
using (var wavWriter = new LameMP3FileWriter(Response.OutputStream, pcmStream.WaveFormat, LAMEPreset.ABR_128))
{
pcmStream.CopyTo(wavWriter);
}
}
}
}
}
Response.Flush();
Response.End();
}

How to use httpwebrequest to pull image from website to local file

I'm trying to use a local c# app to pull some images off a website to files on my local machine. I'm using the code listed below. I've tried both ASCII encoding and UTF8 encoding but the final file is not an correct. Does anyone see what I'm doing wrong? The url is active and correct and show the image just fine when I put the address in my browser.
private void button1_Click(object sender, EventArgs e)
{
HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");
// returned values are returned as a stream, then read into a string
String lsResponse = string.Empty;
HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse();
using (StreamReader lxResponseStream = new StreamReader(lxResponse.GetResponseStream()))
{
lsResponse = lxResponseStream.ReadToEnd();
lxResponseStream.Close();
}
byte[] lnByte = System.Text.UTF8Encoding.UTF8.GetBytes(lsResponse);
System.IO.FileStream lxFS = new FileStream("34891.jpg", FileMode.Create);
lxFS.Write(lnByte, 0, lnByte.Length);
lxFS.Close();
MessageBox.Show("done");
}
nice image :D
try using the following code:
you needed to use a BinaryReader, 'cause an image file is binary data and thus not encoded in UTF or ASCII
edit: using'ified
HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create(
"http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");
// returned values are returned as a stream, then read into a string
String lsResponse = string.Empty;
using (HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse()){
using (BinaryReader reader = new BinaryReader(lxResponse.GetResponseStream())) {
Byte[] lnByte = reader.ReadBytes(1 * 1024 * 1024 * 10);
using (FileStream lxFS = new FileStream("34891.jpg", FileMode.Create)) {
lxFS.Write(lnByte, 0, lnByte.Length);
}
}
}
MessageBox.Show("done");
Okay, here's the final answer. It uses a memorystream as a way to buffer the data from the reaponsestream.
private void button1_Click(object sender, EventArgs e)
{
byte[] lnBuffer;
byte[] lnFile;
HttpWebRequest lxRequest = (HttpWebRequest)WebRequest.Create("http://www.productimageswebsite.com/images/stock_jpgs/34891.jpg");
using (HttpWebResponse lxResponse = (HttpWebResponse)lxRequest.GetResponse())
{
using (BinaryReader lxBR = new BinaryReader(lxResponse.GetResponseStream()))
{
using (MemoryStream lxMS = new MemoryStream())
{
lnBuffer = lxBR.ReadBytes(1024);
while (lnBuffer.Length > 0)
{
lxMS.Write(lnBuffer, 0, lnBuffer.Length);
lnBuffer = lxBR.ReadBytes(1024);
}
lnFile = new byte[(int)lxMS.Length];
lxMS.Position = 0;
lxMS.Read(lnFile, 0, lnFile.Length);
}
}
}
using (System.IO.FileStream lxFS = new FileStream("34891.jpg", FileMode.Create))
{
lxFS.Write(lnFile, 0, lnFile.Length);
}
MessageBox.Show("done");
}
A variation of the answer, using async await for async file I/O. See Async File I/O on why this is important.
Download png and write to disk using BinaryReader/Writer
string outFile = System.IO.Path.Combine(outDir, fileName);
// Download file
var request = (HttpWebRequest) WebRequest.Create(imageUrl);
using (var response = await request.GetResponseAsync()){
using (var reader = new BinaryReader(response.GetResponseStream())) {
// Read file
Byte[] bytes = async reader.ReadAllBytes();
// Write to local folder
using (var fs = new FileStream(outFile, FileMode.Create)) {
await fs.WriteAsync(bytes, 0, bytes.Length);
}
}
}
Read all bytes extension method
public static class Extensions {
public static async Task<byte[]> ReadAllBytes(this BinaryReader reader)
{
const int bufferSize = 4096;
using (var ms = new MemoryStream())
{
byte[] buffer = new byte[bufferSize];
int count;
while ((count = reader.Read(buffer, 0, buffer.Length)) != 0) {
await ms.WriteAsync(buffer, 0, count);
}
return ms.ToArray();
}
}
}
You can use the following method to download an image from a web site and save it, using the Image class:
WebRequest req = WebRequest.Create(imageUrl);
WebResponse resp = req.GetResponse();
Image img = Image.FromStream(resp.GetResponseStream());
img.Save(filePath + fileName + ".jpg");

Categories