I am sending a compressed byte array to a IIS server.
var byteXML = Encoding.UTF8.GetBytes(aufXML.ToString());
using (var result = new MemoryStream())
{
using (var compressionStream = new GZipStream(result, CompressionMode.Compress))
{
compressionStream.Write(byteXML, 0, byteXML.Length);
compressionStream.Flush();
}
byteXML = result.ToArray();
}
When I receive the data over the webserver I am decompressing the data:
using (var source = new MemoryStream(trafficAnhangXml))
{
byte[] lengthBytes = new byte[trafficAnhangXml.Length];
source.Read(lengthBytes, 0, trafficAnhangXml.Length);
var length = BitConverter.ToInt32(lengthBytes, 0);
using (var decompressionStream = new GZipStream(source, CompressionMode.Decompress))
{
var result = new byte[length];
decompressionStream.Read(result, 0, length);
trafficAnhangXml = result;
}
}
I try to get the InnerXML like this:
appPath = SaveFileAsync("D3.XML", trafficVorgangXml, systemUser).Result;
xDoc.Load(appPath);
receive.VorgangsXML = xDoc.InnerXml;
And then I get the following error:
Error: root element is missing
Related
I have a file .ogg and i need to convert it to .wav. I'm tryng to use Opus.Net (that use NAudio) but i get this exception in OpusDecoder.Decode():
"System.Exception: 'Decoding failed - InvalidPacket'"
This is the code:
byte[] audioBynary = File.ReadAllBytes($"{filePath}{fileOgg}");
_decoder = OpusDecoder.Create(48000, 1);
var pcmBinary = _decoder.Decode(audioBynary, audioBynary.Length, out int decodedLenght);
WaveFileWriter.CreateWaveFile($"{filePath}{fileWav}", new WaveFileReader(new MemoryStream(pcmBinary)));
This works for me, I read the ogg/opus file with Concentus, copy it's bytes to a memoryStream and then use it to create a RawSourceWaveStream.
I can get an ISampleProvider from the RawSourceWaveStream, which is what you need to feed
WaveFileWriter.CreateWaveFile16.
Voilá
var filePath = $#"C:\Users\blabla\foo\bar\";
var fileOgg = "testAudio.ogg";
var fileWav = "testAudio.wav";
using (FileStream fileIn = new FileStream($"{filePath}{fileOgg}", FileMode.Open))
using (MemoryStream pcmStream = new MemoryStream())
{
OpusDecoder decoder = OpusDecoder.Create(48000, 1);
OpusOggReadStream oggIn = new OpusOggReadStream(decoder, fileIn);
while (oggIn.HasNextPacket)
{
short[] packet = oggIn.DecodeNextPacket();
if (packet != null)
{
for (int i = 0; i < packet.Length; i++)
{
var bytes = BitConverter.GetBytes(packet[i]);
pcmStream.Write(bytes, 0, bytes.Length);
}
}
}
pcmStream.Position = 0;
var wavStream = new RawSourceWaveStream(pcmStream, new WaveFormat(48000, 1));
var sampleProvider = wavStream.ToSampleProvider();
WaveFileWriter.CreateWaveFile16($"{filePath}{fileWav}", sampleProvider);
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
I've got two methods in my Windows Forms application for parsing some gzip encoded strings.
Here are my two methods, which both return the same value.
public static async Task<string> DecodeGzipAsync(string str)
{
var values = new Dictionary<string, string>
{
{ "data", str }
};
var content = new FormUrlEncodedContent(values);
var client = new HttpClient();
var response = await client.PostAsync("http://www.txtwizard.net/compression/decompress/gz", content);
var json = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<GzipData>(json);
return result.DecompressedData;
}
public static string DecodeGzip(string str)
{
byte[] gzBuffer = Convert.FromBase64String(str);
using (MemoryStream ms = new MemoryStream())
{
int msgLength = BitConverter.ToInt32(gzBuffer, 0);
ms.Write(gzBuffer, 0, gzBuffer.Length);
byte[] buffer = new byte[msgLength];
ms.Position = 0;
using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
{
zip.Read(buffer, 0, buffer.Length);
}
return Encoding.UTF8.GetString(buffer);
}
And then I call these two methods from my main form.
var string1 = await Utilities.DecodeGzipAsync(xml.InnerText);
var string1Concat = string.Concat("<Connotes>", string1, "</Connotes>");
var string2 = Utilities.DecodeGzip(xml.InnerText);
var string2Concat = string.Concat("<Connotes>", string2, "</Connotes>");
Where xml.InnerText is
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
The results I get are really frustrating (and weird!)
string1 and string2 both return the same string, however string1Concat and string2Concat return different results.
string1Concat = "<Connotes>" + string1 + "</Connotes>"
string2Concat = "<Connotes>" + string2 // Notice how it is missing the concatenation on the end
What might be causing this behaviour? I have tried changing the encoding to ASCII and UTF8 but both give the same results.
Any help is much appreciated!
This was a little tricky, but I found the problem/solution:
You convert the array of the size of the compressed data to a string at Encoding.UTF8.GetString(buffer). This will create a string which a length of 559903 instead of the correct 9209. If you create a new byte-array with the actually read bytes it is working:
public static string DecodeGzip(string str)
{
byte[] gzBuffer = Convert.FromBase64String(str);
using (MemoryStream ms = new MemoryStream())
{
int msgLength = BitConverter.ToInt32(gzBuffer, 0);
ms.Write(gzBuffer, 0, gzBuffer.Length);
byte[] buffer = new byte[msgLength];
ms.Position = 0;
int length;
using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
{
length = zip.Read(buffer, 0, buffer.Length);
}
var data = new byte[length];
Array.Copy(buffer, data, length);
return Encoding.UTF8.GetString(data);
}
}
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();
}
I'm trying to compress and decompress a memory stream to send it over an tcp connection.
In the following code snap I do do the decompressing right after compressing to get it working first.
What ever I do I end up with a devompressed buffer wit all zero's and in the line
int read = Decompress.Read(buffie, 0, buffie.Length);
it seems that 0 bytes are read.
Does anyone has a clue what is wrong?
bytesRead = ms.Read(buf, 0, i);
MemoryStream partialMs = new MemoryStream();
GZipStream gZip = new GZipStream(partialMs, CompressionMode.Compress);
gZip.Write(buf, 0, buf.Length);
partialMs.Position = 0;
byte[] compressedBuf = new byte[partialMs.Length];
partialMs.Read(compressedBuf, 0, (int)partialMs.Length);
partialMs.Close();
byte[] gzBuffer = new byte[compressedBuf.Length + 4];
System.Buffer.BlockCopy(compressedBuf, 0, gzBuffer, 4, compressedBuf.Length);
System.Buffer.BlockCopy(BitConverter.GetBytes(buf.Length), 0, gzBuffer, 0, 4);
using (MemoryStream mems = new MemoryStream())
{
int msgLength = BitConverter.ToInt32(gzBuffer, 0);
byte[] buffie = new byte[msgLength];
mems.Write(gzBuffer, 4, gzBuffer.Length - 4);
mems.Flush();
mems.Position = 0;
using (GZipStream Decompress = new GZipStream(mems, CompressionMode.Decompress, true))
{
int read = Decompress.Read(buffie, 0, buffie.Length);
Decompress.Close();
}
}
Your implementation could use some work. there seems to be some confusion as to which streams should be used where. here is a working example to get you started..
see user content at the bottom of this MSDN page
var original = new byte[65535];
var compressed = GZipTest.Compress(original);
var decompressed = GZipTest.Decompress(compressed);
using System.IO;
using System.IO.Compression;
public class GZipTest
{
public static byte[] Compress(byte[] uncompressedBuffer)
{
using (var ms = new MemoryStream())
{
using (var gzip = new GZipStream(ms, CompressionMode.Compress, true))
{
gzip.Write(uncompressedBuffer, 0, uncompressedBuffer.Length);
}
byte[] compressedBuffer = ms.ToArray();
return compressedBuffer;
}
}
public static byte[] Decompress(byte[] compressedBuffer)
{
using (var gzip = new GZipStream(new MemoryStream(compressedBuffer), CompressionMode.Decompress))
{
byte[] uncompressedBuffer = ReadAllBytes(gzip);
return uncompressedBuffer;
}
}
private static byte[] ReadAllBytes(Stream stream)
{
var buffer = new byte[4096];
using (var ms = new MemoryStream())
{
int bytesRead = 0;
do
{
bytesRead = stream.Read(buffer, 0, buffer.Length);
if (bytesRead > 0)
{
ms.Write(buffer, 0, bytesRead);
}
} while (bytesRead > 0);
return ms.ToArray();
}
}
}
You're not closing the GzipStream you're writing to, so it's probably all buffered. I suggest you close it when you're done writing your data.
By the way, you can get the data out of a MemoryStream much more easily than your current code: use MemoryStream.ToArray.