I have a method generating waveform data (using NAudio SampleProviders) from the audio files which was working properly till now. But today we noticed this method is generating wrong results for some specific audios. After examining I realized that the encoding of the problematic audio files was MuLaw which I didn't handle. Which sample provider should I use to properly obtain the sample values? (Btw: My project is .NET Core, so I can only use NAudio.Core)
Here is the complete method:
public async Task<string> GenerateWaveformAsync(AudioFormats format, byte[] content, int duration)
{
int samplesPerPixel = GetSamplesPerPixelFromConfig(duration);
var resultJson = string.Empty;
var waveformResult = new WaveformResult();
var waveformPointCount = 0L;
var waveformPointsAsShort = new List<short>();
var waveformPointsAsFloat = new List<float>();
try
{
_logger.LogInformation($"Waveform generation has been started.");
using (var memoryStream = new MemoryStream(content))
using (WaveStream waveReader = GetReaderStream(memoryStream, format))
{
ISampleProvider provider;
switch (waveReader.WaveFormat.Encoding)
{
case WaveFormatEncoding.Pcm:
provider = new Pcm16BitToSampleProvider(waveReader);
break;
case WaveFormatEncoding.IeeeFloat:
provider = new WaveToSampleProvider(waveReader);
break;
case WaveFormatEncoding.MuLaw:
provider = ???;
break;
default:
provider = new Pcm16BitToSampleProvider(waveReader);
break;
}
waveformResult.Bits = waveReader.WaveFormat.BitsPerSample;
waveformResult.Channels = waveReader.WaveFormat.Channels;
waveformResult.SampleRate = waveReader.WaveFormat.SampleRate;
waveformResult.SamplesPerPixel = samplesPerPixel;
var leftChannelSamples = new List<float>();
var rightChannelSamples = new List<float>();
var buffer = new float[waveReader.WaveFormat.SampleRate];
int byteCountRead;
do
{
byteCountRead = provider.Read(buffer, 0, buffer.Length);
for (var n = 0; n < byteCountRead; n++)
{
if (n % 2 == 0)
{
leftChannelSamples.Add(buffer[n]);
}
else
{
rightChannelSamples.Add(buffer[n]);
}
}
}
while (byteCountRead > 0);
var waveformPointCountDouble = (double)leftChannelSamples.Count / (double)samplesPerPixel;
waveformPointCount = (long)Math.Ceiling(waveformPointCountDouble);
var leftChannelPeaks = new List<PeakInfo>();
var rightChannelPeaks = new List<PeakInfo>();
for (var i = 0; i < waveformPointCount; i++)
{
var currentFrameLeftChannel = leftChannelSamples
.Skip(i * samplesPerPixel)
.Take(samplesPerPixel)
.ToList();
var currentFrameRightChannel = rightChannelSamples
.Skip(i * samplesPerPixel)
.Take(samplesPerPixel)
.ToList();
leftChannelPeaks.Add(new PeakInfo(currentFrameLeftChannel.Min(), currentFrameLeftChannel.Max()));
rightChannelPeaks.Add(new PeakInfo(currentFrameRightChannel.Min(), currentFrameRightChannel.Max()));
}
for (var i = 0; i < leftChannelPeaks.Count; i++)
{
waveformPointsAsFloat.Add(leftChannelPeaks[i].Min);
waveformPointsAsFloat.Add(leftChannelPeaks[i].Max);
waveformPointsAsFloat.Add(rightChannelPeaks[i].Min);
waveformPointsAsFloat.Add(rightChannelPeaks[i].Max);
}
waveformPointsAsFloat
.ForEach(f => waveformPointsAsShort.Add((short)Math.Round(f * short.MaxValue, 0)));
}
waveformResult.Length = waveformPointCount;
waveformResult.Data = waveformPointsAsShort;
var contractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy(),
};
resultJson = JsonConvert.SerializeObject(waveformResult, Formatting.Indented,
new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
ContractResolver = contractResolver,
});
_logger.LogInformation($"Waveform has been generated successfully.");
}
catch (Exception ex)
{
_logger.LogError($"An error has occurred while generating waveform. ({ex.Message})");
}
return resultJson;
}
private static WaveStream GetReaderStream(MemoryStream memoryStream, AudioFormats audioFormat)
{
switch (audioFormat)
{
case AudioFormats.Wav:
return new WaveFileReader(memoryStream);
case AudioFormats.Mp3:
return new Mp3FileReader(memoryStream);
default:
throw new UnsupportedAudioFormatForWaveformGenerationException();
}
}
Related
I have below json data I need to apply CAdES-BES Signature with Automatic JSON Canonicalization. Please find my json data below. Helpful link from https://www.example-code.com/Csharp/itida_egypt_cades_bes_json_canonicalization.asp. I follow the steps but still digital signature is not applying. Its returns normal json data.
[HttpGet]
[Route("api/invoiceLines/")]
public IHttpActionResult getEInvoiceLines()
{
Chilkat.Crypt2 crypt = new Chilkat.Crypt2();
crypt.VerboseLogging = true;
Chilkat.Cert cert = new Chilkat.Cert();
cert.VerboseLogging = true;
// Set the smart card PIN, which will be needed for signing.
cert.SmartCardPin = "1245345";
// There are many ways to load the certificate.
// This example was created for a customer using an ePass2003 USB token.
// Assuming the USB token is the only source of a hardware-based private key..
bool success = cert.LoadFromSmartcard(#"E"); //Is this Right way To load certificate ?
Chilkat.JsonObject cmsOptions = new Chilkat.JsonObject();
// Setting "DigestData" causes OID 1.2.840.113549.1.7.5 (digestData) to be used.
cmsOptions.UpdateBool("DigestData", true);
cmsOptions.UpdateBool("OmitAlgorithmIdNull", true);
// Indicate that we are passing normal JSON and we want Chilkat do automatically
// do the ITIDA JSON canonicalization:
cmsOptions.UpdateBool("CanonicalizeITIDA", true);
crypt.CmsOptions = cmsOptions.Emit();
// The CadesEnabled property applies to all methods that create CMS/PKCS7 signatures.
// To create a CAdES-BES signature, set this property equal to true.
crypt.CadesEnabled = true;
crypt.HashAlgorithm = "sha256";
Chilkat.JsonObject jsonSigningAttrs = new Chilkat.JsonObject();
jsonSigningAttrs.UpdateInt("contentType", 1);
jsonSigningAttrs.UpdateInt("signingTime", 1);
jsonSigningAttrs.UpdateInt("messageDigest", 1);
jsonSigningAttrs.UpdateInt("signingCertificateV2", 1);
crypt.SigningAttributes = jsonSigningAttrs.Emit();
// By default, all the certs in the chain of authentication are included in the signature.
// If desired, we can choose to only include the signing certificate:
crypt.IncludeCertChain = false;
EInvoiceModel.Example ds = new EInvoiceModel.Example();
//Start issuer details
ds.issuer = new EInvoiceModel.Issuer();
ds.issuer.type = "B";
ds.issuer.id = "113317713";
ds.issuer.name = "Issuer Company";
//Start issuer address details
ds.issuer.address = new EInvoiceModel.Address();
ds.issuer.address.branchID = "1";
ds.issuer.address.country = "EG";
ds.issuer.address.governate = "Cairo";
ds.issuer.address.regionCity = "Nasr City";
ds.issuer.address.street = "stree1";
ds.issuer.address.buildingNumber = "Bldg. 0";
ds.issuer.address.postalCode = "68030";
ds.issuer.address.floor = "1";
ds.issuer.address.room = "123";
ds.issuer.address.landmark = "7660 Melody Trail";
ds.issuer.address.additionalInformation = "beside Town Hall";
//Start Receiver details
ds.receiver = new EInvoiceModel.Receiver();
ds.receiver.type = "B";
ds.receiver.id = "3125617";
ds.receiver.name = "Receiver company";
//Start Receiver address datails
ds.receiver.address = new EInvoiceModel.AddressReceiver();
ds.receiver.address.country = "EG";
ds.receiver.address.governate = "Cairo";
ds.receiver.address.regionCity = "Nasr City";
ds.receiver.address.street = "stree1";
ds.receiver.address.buildingNumber = "Bldg. 0";
ds.receiver.address.postalCode = "68030";
ds.receiver.address.floor = "1";
ds.receiver.address.room = "123";
ds.receiver.address.landmark = "7660 Melody Trail";
ds.receiver.address.additionalInformation = "beside Town Hall";
//Document type & version
ds.documentType = "i";
ds.documentTypeVersion = "1.0";
DateTime d = new DateTime();
ds.dateTimeIssued = d; //Invoice date
ds.taxpayerActivityCode = "9478"; //needed info
ds.internalID = "WADIn1234"; //Internal Invoice number
ds.salesOrderReference = "So1234"; //So number //optional
ds.salesOrderDescription = "SO1234"; //So additional Info //optional
ds.proformaInvoiceNumber = "SoPro123"; //optional
//Invoiceline Start
ds.invoiceLines = new List<EInvoiceModel.InvoiceLine>
{
new EInvoiceModel.InvoiceLine
{
description = "Computer1",
itemType = "GPC",
itemCode = "10001774",
unitType = "EA",
quantity = 2,
internalCode = "IC0",
salesTotal = 23.99,
total = 2969.89,
valueDifference = 7.00,
totalTaxableFees = 817.42,
netTotal = 880.71,
itemsDiscount = 5.00,
unitValue = new EInvoiceModel.UnitValue
{
currencySold = "EUR",
amountEGP = 189.40,
amountSold = 10.00,
currencyExchangeRate = 18.94,
},
discount = new EInvoiceModel.Discount
{
rate = 7,
amount = 66.29
},
taxableItems = new List<EInvoiceModel.TaxableItem>
{
new EInvoiceModel.TaxableItem
{
taxType = "T1",
amount = 272.07,
subType = "T1",
rate = 12
}
}
}
}; //Invoice Lines End
//Items total Discount and Sales/NetAmount
ds.totalDiscountAmount = 76.29;
ds.totalSalesAmount = 1609.90;
ds.netAmount = 1533.61;
//Tax Total Start
ds.taxTotals = new List<EInvoiceModel.TaxTotal>
{
new EInvoiceModel.TaxTotal
{
taxType = "T1",
amount = 477.54,
}
};//Tax Total End
//Total Sales Amount & discounts
ds.totalAmount = 5191.50;
ds.extraDiscountAmount = 5.00;
ds.totalItemsDiscountAmount = 14.00;
string strResultJson = JsonConvert.SerializeObject(ds);
//System.IO.File.WriteAllText(#"C:\inetpub\wwwroot\path.json", strResultJson);
// File.WriteAllText(#"ds.json", strResultJson);
// string jsonToSign = "{ ... }";
string jsonToSign = strResultJson;
// Create the CAdES-BES signature.
crypt.EncodingMode = "base64";
// Make sure we sign the utf-8 byte representation of the JSON string
crypt.Charset = "utf-8";
string sigBase64 = crypt.SignStringENC(jsonToSign);
// return Ok(ds);
return Ok(sigBase64);
}
public static string SerializeObject2(object obj, int indent = 0)
{
var sb = new StringBuilder();
if (obj != null)
{
string indentString = new string(' ', indent);
if (obj is string || obj.IsNumber())
{
sb.Append($"\"{obj}\"");
}
else if (obj.GetType().BaseType == typeof(Enum))
{
sb.Append($"\"{obj.ToString()}\"");
}
else if (obj is Array)
{
var elems = obj as IList;
sb.Append($"{indentString}- [{elems.Count}] :\n");
for (int i = 0; i < elems.Count; i++)
{
sb.Append(SerializeObject2(elems[i], indent + 4));
}
}
else
{
Type objType = (obj).GetType();
PropertyInfo[] props = objType.GetProperties();
foreach (PropertyInfo prop in props)
{
if (prop.GetIndexParameters().Length == 0)
{
object propValue = prop.GetValue(obj);
var elems = propValue as IList;
if (elems != null)
{
sb.Append($"\"{prop.Name.ToUpper()}\"");
foreach (var item in elems)
{
sb.Append($"\"{prop.Name.ToUpper()}\"");
sb.Append(SerializeObject2(item, indent + 4));
}
}
else
{
if (Assembly.GetExecutingAssembly().DefinedTypes.Select(p => p.Assembly).ToList().Contains(prop.PropertyType.Assembly))
{
sb.Append($"\"{prop.Name.ToUpper()}\"");
sb.Append(SerializeObject2(propValue, indent + 4));
}
else
{
sb.Append($"\"{prop.Name.ToUpper()}\"\"{propValue}\"");
}
}
}
else if (objType.GetProperty("Item") != null)
{
int count = -1;
if (objType.GetProperty("Count") != null &&
objType.GetProperty("Count").PropertyType == typeof(int))
{
count = (int)objType.GetProperty("Count").GetValue(obj, null);
}
for (int i = 0; i < count; i++)
{
object val = prop.GetValue(obj, new object[] { i });
sb.Append(SerializeObject2(val, indent + 4));
}
}
}
}
}
return sb.ToString();
}
I am trying to convert ActionScript3 code to C# that's like the main thing. However, with trying to convert one of the functions I got the error which is in the title when I was trying to convert a hexadecimal string to an int.
Basically, this code is supposed to take information for example user data and then do somethings and in the end return Base64 encoded text. The main error that I am aware of is at the part where "loc9 = Convert.ToInt32(loc8, 16);" is as that is where I am getting the error said in the title. I have tried researching similar issues others have had with something like this, but it just didn't seem the same and didn't really help me out.
(Btw I am sorry if this doesn't sound so clear, correct me or ask more questions if not understood)
Screenshot of error when called
My C# Code:
private static string hasher(string input)
{
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("x2"));
}
return sb.ToString();
}
public static string p(string param1)
{
var loc6 = "";
var loc7 = "";
var loc8 = "";
var loc9 = 0;
var loc2 = hasher(param1);
var loc4 = 0;
MemoryStream loc0 = new MemoryStream();
var loc3 = new byte[] { };
while(loc4 < loc2.Length * 2)
{
loc6 = loc2.Substring(loc4, loc4 + 1);
loc7 = loc2.Substring(loc4 + 1, loc4 + 2);
loc8 = "0x" + loc6 + loc7;
loc9 = Convert.ToInt32(loc8, 16);
new BinaryWriter(loc0).Write(loc9);
loc4 = loc4 + 2;
}
loc0.Position = 0;
loc3 = loc0.ToArray();
return Convert.ToBase64String(loc3, 0, 16);
}
public string calculateFromNewActorCreationData(string username, string password, byte[] small, byte[] full)
{
return calculateFromStrings(username, password, small, full);
}
public string calculateFromStrings(string param1, string param2, object param3, object param4)
{
var loc5 = param1 + param2 + fromByteArray(param3 as byte[]) + fromByteArray(param4 as byte[]) + p();
return p(loc5);
}
private string fromByteArray(byte[] param1)
{
var ms = new MemoryStream(param1);
List<byte> list2 = new List<byte>();
if (param1.Length <= 20)
return HexStringFromBytes(param1);
var loc3 = new byte[] { };
var loc4 = param1.Length / 20;
var loc5 = 0;
while (loc5 < 20)
{
ms.Position = loc4 * loc5;
list2.Add(new BinaryReader(ms).ReadByte());
loc5++;
}
loc3 = list2.ToArray();
return HexStringFromBytes(loc3);
}
private static string HexStringFromBytes(byte[] bytes)
{
var sb = new StringBuilder();
foreach (byte b in bytes)
{
var hex = b.ToString("x2");
sb.Append(hex);
}
return sb.ToString();
}
private string p()
{
MemoryStream stream = new MemoryStream();
new BinaryWriter(stream).Write(120);
new BinaryWriter(stream).Write(-38);
new BinaryWriter(stream).Write(99);
new BinaryWriter(stream).Write(16);
new BinaryWriter(stream).Write(32);
new BinaryWriter(stream).Write(51);
new BinaryWriter(stream).Write(41);
new BinaryWriter(stream).Write(-110);
new BinaryWriter(stream).Write(12);
new BinaryWriter(stream).Write(50);
new BinaryWriter(stream).Write(81);
new BinaryWriter(stream).Write(73);
new BinaryWriter(stream).Write(49);
new BinaryWriter(stream).Write(-56);
new BinaryWriter(stream).Write(13);
new BinaryWriter(stream).Write(48);
new BinaryWriter(stream).Write(54);
new BinaryWriter(stream).Write(54);
new BinaryWriter(stream).Write(14);
new BinaryWriter(stream).Write(48);
new BinaryWriter(stream).Write(46);
new BinaryWriter(stream).Write(2);
new BinaryWriter(stream).Write(0);
new BinaryWriter(stream).Write(45);
new BinaryWriter(stream).Write(-30);
new BinaryWriter(stream).Write(4);
new BinaryWriter(stream).Write(-16);
stream.Position = 0;
return Encoding.UTF8.GetString(stream.ToArray());
}
ActionScript3 Code:
private static function p(param1:String) : String
{
var _loc6_:String = null;
var _loc7_:String = null;
var _loc8_:String = null;
var _loc9_:int = 0;
var _loc2_:String = MD5.hash(param1);
var _loc3_:ByteArray = new ByteArray();
var _loc4_:int = 0;
while(_loc4_ < _loc2_.length * 2)
{
_loc6_ = _loc2_.slice(_loc4_,_loc4_ + 1);
_loc7_ = _loc2_.slice(_loc4_ + 1,_loc4_ + 2);
_loc8_ = "0x" + _loc6_ + _loc7_;
_loc9_ = int(_loc8_);
_loc3_.writeByte(_loc9_);
_loc4_ = _loc4_ + 2;
}
_loc3_.position = 0;
var _loc5_:Base64Encoder = new Base64Encoder();
_loc5_.encodeBytes(_loc3_,0,16);
return _loc5_.toString();
}
public function calculateFromNewActorCreationData(param1:NewActorCreationData, param2:ByteArray, param3:ByteArray) : String
{
return this.calculateFromStrings(param1.ChosenActorName,param1.ChosenPassword,param2,param3);
}
public function calculateFromStrings(param1:String, param2:String, param3:Object, param4:Object) : String
{
var _loc5_:String = param1 + param2 + this.fromByteArray(param3) + this.fromByteArray(param4) + this.p();
return p(_loc5_);
}
private function fromByteArray(param1:Object) : String
{
if(param1 == null)
{
return "";
}
var _loc2_:int = 20;
if(param1.length <= _loc2_)
{
return Hex.fromArray(param1 as ByteArray);
}
var _loc3_:ByteArray = new ByteArray();
var _loc4_:int = param1.length / _loc2_;
var _loc5_:int = 0;
while(_loc5_ < _loc2_)
{
param1.position = _loc4_ * _loc5_;
_loc3_.writeByte(param1.readByte());
_loc5_++;
}
return Hex.fromArray(_loc3_);
}
private function p() : String
{
var _loc1_:ByteArray = new ByteArray();
_loc1_.writeByte(120);
_loc1_.writeByte(-38);
_loc1_.writeByte(99);
_loc1_.writeByte(16);
_loc1_.writeByte(12);
_loc1_.writeByte(51);
_loc1_.writeByte(41);
_loc1_.writeByte(-118);
_loc1_.writeByte(12);
_loc1_.writeByte(50);
_loc1_.writeByte(81);
_loc1_.writeByte(73);
_loc1_.writeByte(49);
_loc1_.writeByte(-56);
_loc1_.writeByte(13);
_loc1_.writeByte(48);
_loc1_.writeByte(54);
_loc1_.writeByte(54);
_loc1_.writeByte(14);
_loc1_.writeByte(48);
_loc1_.writeByte(46);
_loc1_.writeByte(2);
_loc1_.writeByte(0);
_loc1_.writeByte(45);
_loc1_.writeByte(-30);
_loc1_.writeByte(4);
_loc1_.writeByte(-16);
_loc1_.uncompress();
_loc1_.position = 0;
return _loc1_.readUTF();
}
What I am expecting in the end is to be able to call the function having the returned Base64 encoded data show in a MessageBox (using messagebox as a test) instead of any errors popping up.
P.S - Besides the main problem I am having with this code, I also feel like the other functions I had converted aren't perfect or just might not be the same. So, if my main problem can be solved, if someone can also double check the other functions of my code make sure they are accurate that would be amazing and thanks in advance.
Looking at this overall, it appears the AS3 code is attempting to convert the MD5.hash result into a Base64 encoded string in the worst way possible (I believe it can be done in one line.)
So, instead of copying all the code to translate the hash to a hex string only to poorly translate it back to a binary array, just use the C# result which is already a binary array directly:
public static string p(string param1) {
byte[] loc3 = System.Security.Cryptography.MD5.Create().ComputeHash(System.Text.Encoding.ASCII.GetBytes(param1));
return Convert.ToBase64String(loc3, 0, 16);
}
Trying to stitch multiple videos using AVAssetTrack and AVMutableCompositionTrack. Uploaded videos could have different audio settings (e.g. sample rate) - what's the best way to pass in desired audio settings when adding AVAssetTracks to AVMutableVideoComposition? Currently using the following code, certain videos with 48KHz stitched with 44.1KHz produce no sound when played on IE/Edge, but works on other browsers:
Composition = new AVMutableComposition();
AVMutableCompositionTrack VideoCompositionTrack = Composition.AddMutableTrack(AVMediaType.Video, 0);
AVMutableCompositionTrack AudioCompositionTrack = Composition.AddMutableTrack(AVMediaType.Audio, 1);
AVMutableVideoCompositionLayerInstruction LayerInstruction = AVMutableVideoCompositionLayerInstruction.FromAssetTrack(VideoCompositionTrack);
CMTime StartTime = CMTime.Zero;
AVUrlAssetOptions Options = new AVUrlAssetOptions
{
PreferPreciseDurationAndTiming = true
};
CMTimeRange TimeRange;
NSError InsertError = null;
int Counter = 0;
CGSize FinalRenderSize = new CGSize();
foreach (NSUrl VideoLocation in SelectedVideoLocations)
{
using (AVAsset Asset = new AVUrlAsset(VideoLocation, Options))
{
TimeRange = new CMTimeRange()
{
Start = CMTime.Zero,
Duration = Asset.Duration
};
if (Asset.TracksWithMediaType(AVMediaType.Video).Length > 0)
{
using (AVAssetTrack VideoAssetTrack = Asset.TracksWithMediaType(AVMediaType.Video)[0])
{
if (Counter == 0)
{
FinalRenderSize = VideoAssetTrack.NaturalSize;
}
LayerInstruction.SetTransform(VideoAssetTrack.PreferredTransform, StartTime);
VideoCompositionTrack.InsertTimeRange(TimeRange, VideoAssetTrack, StartTime, out InsertError);
}
}
if (Asset.TracksWithMediaType(AVMediaType.Audio).Length > 0)
{
using (AVAssetTrack AudioAssetTrack = Asset.TracksWithMediaType(AVMediaType.Audio)[0])
{
LayerInstruction.SetTransform(AudioAssetTrack.PreferredTransform, StartTime);
AudioCompositionTrack.InsertTimeRange(TimeRange, AudioAssetTrack, StartTime, out InsertError);
}
}
StartTime = CMTime.Add(StartTime, Asset.Duration);
Counter++;
}
}
AVMutableVideoCompositionInstruction MainInstruction = new AVMutableVideoCompositionInstruction
{
TimeRange = VideoCompositionTrack.TimeRange,
LayerInstructions = new AVVideoCompositionLayerInstruction[1] { LayerInstruction }
};
AVMutableVideoComposition CompositionInstruction = AVMutableVideoComposition.Create(Composition);
CompositionInstruction.Instructions = new AVMutableVideoCompositionInstruction[1] { MainInstruction };
CompositionInstruction.FrameDuration = new CMTime(1, 30);
CompositionInstruction.RenderScale = 1.0f;
CompositionInstruction.RenderSize = FinalRenderSize;
string FilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), FolderName, FileName);
await LocalStorage.DeleteFileAsync(FilePath);
NSUrl FilePathURL = NSUrl.CreateFileUrl(new string[] { FilePath });
MediaURL = FilePath;
AVAssetExportSession ExportSession = new AVAssetExportSession(Composition, AVAssetExportSessionPreset.Preset960x540);
if (CompositionInstruction != null)
{
ExportSession.VideoComposition = CompositionInstruction;
}
ExportSession.ShouldOptimizeForNetworkUse = true;
ExportSession.OutputUrl = FilePathURL;
ExportSession.OutputFileType = AVFileType.Mpeg4;
await ExportSession.ExportTaskAsync();
if (ExportSession.Status != AVAssetExportSessionStatus.Completed)
{
throw new Exception(ExportSession.Error.DebugDescription);
}
Hi I am trying to parse the response from a OSM webservice into feature collection using GeoJson.Net
I am new to GeoJSON and not able to identify how to do so:
The Json response can be find here. The code I have written is:
System.IO.StreamReader file = new System.IO.StreamReader(filepath);
string content = file.ReadToEnd();
file.Close();
dynamic deserialized = JsonConvert.DeserializeObject(content);
List<Feature> lstGeoLocation = new List<Feature>();
foreach (JObject item in deserialized.features)
{
//var feature = new Feature();
var geom = item.Property("geometry").Value;
}
But this will be plain JSON parsing and there might be a better way to parse the same.
I also tried NetTopologySuite JSON extension but when i use following code it gives me exception
"Expected token 'type' not found."
System.IO.StreamReader file = new System.IO.StreamReader(filepath);
string content = file.ReadToEnd();
file.Close();
var reader = new NetTopologySuite.IO.GeoJsonReader();
var featureCollection = reader.Read <NetTopologySuite.Features.FeatureCollection>(content);
I hate to answer my I question but after two days of hit & trial I get it working with both NetTopology and GeoJson
// get the JSON file content
var josnData = File.ReadAllText(destinationFileName);
// create NetTopology JSON reader
var reader = new NetTopologySuite.IO.GeoJsonReader();
// pass geoJson's FeatureCollection to read all the features
var featureCollection = reader.Read<GeoJSON.Net.Feature.FeatureCollection>(josnData);
// if feature collection is null then return
if (featureCollection == null)
{
return;
}
// loop through all the parsed featurd
for (int featureIndex = 0;
featureIndex < featureCollection.Features.Count;
featureIndex++)
{
// get json feature
var jsonFeature = featureCollection.Features[featureIndex];
Geometry geom = null;
// get geometry type to create appropriate geometry
switch (jsonFeature.Geometry.Type)
{
case GeoJSONObjectType.Point:
break;
case GeoJSONObjectType.MultiPoint:
break;
case GeoJSONObjectType.LineString:
break;
case GeoJSONObjectType.MultiLineString:
break;
case GeoJSONObjectType.Polygon:
{
var polygon = jsonFeature.Geometry as GeoJSON.Net.Geometry.Polygon;
var coordinates = new List <Point3D>();
foreach (var ring in polygon.Coordinates)
{
if (ring.IsLinearRing())
{
foreach (var coordinate in ring.Coordinates)
{
var location = coordinate as GeographicPosition;
if (location == null)
{
continue;
}
coordinates.Add(new Point3D(location.Longitude,
location.Latitude,
location.Altitude.HasValue ? location.Altitude.Value : 0 ));
}
}
}
geom = new Polygon(new LinearRing(new CoordinateSequence(coordinates.ToArray())),
null);
}
break;
case GeoJSONObjectType.MultiPolygon:
break;
case GeoJSONObjectType.GeometryCollection:
break;
case GeoJSONObjectType.Feature:
break;
case GeoJSONObjectType.FeatureCollection:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
//Steps to Converting GeoJSON response to FeatureCollection
//1. Add NetTopologySuite.IO.GeoJson package from Nuget Package Manager.
//2. Write Following Code Snap:
string Filepath = "Your filepath here";
var josnData = File.ReadAllText(Filepath);
var reader = new NetTopologySuite.IO.GeoJsonReader();
var featureCollection =
reader.Read<GeoJSON.Net.Feature.FeatureCollection>(josnData);
//in my case i did it like this
for (int fIndex = 0; fIndex < featureCollection.Features.Count; fIndex++)
{
var AreaDetails =
featureCollection.Features[fIndex].Properties;
for (int AIndex = 0; AIndex < AreaDetails.Count;
AIndex++)
{
var element = AreaDetails.ElementAt(AIndex);
var Key = element.Key;
var Value = element.Value;
if (Key == "GML_ID")
{
areaDetails.StateCode = Value.ToString();
}
else if (Key == "STNAME")
{
areaDetails.State = Value.ToString();
}
else if (Key == "DISTFULL")
{
areaDetails.DistrictCode = Value.ToString();
}
else if (Key == "DTNAME")
{
areaDetails.District = Value.ToString();
}
else if (Key == "IPCODE")
{
areaDetails.TalukaCode = Value.ToString();
}
else if (Key == "IPNAME")
{
areaDetails.Taluka = Value.ToString();
}
else if (Key == "VLGCD2001")
{
areaDetails.AreaCode = Value.ToString();
}
else if (Key == "VILLNAME")
{
areaDetails.AreaName = Value.ToString();
}
}
var AreaCoords = featureCollection.Features[fIndex].Geometry;
var Type = AreaCoords.Type;
LocationDetails locationDetails = new LocationDetails();
if (Type == GeoJSONObjectType.Polygon)
{
var polygon = AreaCoords as GeoJSON.Net.Geometry.Polygon;
var polygonCoords = polygon.Coordinates[0].Coordinates;
for (int AIndex = 0; AIndex < polygonCoords.Count; AIndex++)
{
locationDetails.lat = Convert.ToDecimal(polygonCoords[AIndex].Latitude);
locationDetails.lng = Convert.ToDecimal(polygonCoords[AIndex].Longitude);
locationDetailsList.Add(locationDetails);
}
}
I'm building an android app with Xamarin which communicates with an ASP.net server's API. I'm trying to upload a file to the server using the following lines of code:
public async Task<HttpResponseMessage> UploadFile(byte[] file)
{
var progress = new System.Net.Http.Handlers.ProgressMessageHandler();
//progress.HttpSendProgress += progress_HttpSendProgress;
using (var client = HttpClientFactory.Create(progress))
{
client.BaseAddress = new Uri(GlobalVariables.host);
// Set the Accept header for BSON.
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/bson"));
var request = new uploadFileModel { data = file, dateCreated = DateTime.Now, fileName = "myvideooo.mp4", username = "psyoptica" };
// POST using the BSON formatter.
MediaTypeFormatter bsonFormatter = new BsonMediaTypeFormatter();
var m = client.MaxResponseContentBufferSize;
var result = await client.PostAsync("api/media/upload", request, bsonFormatter);
return result.EnsureSuccessStatusCode();
}
}
The app crashes before the server receives the request. The file I'm trying to upload could be a video or an audio file. The server receives the request after the app has crashed. This works fine on the local server but the crash happens with the live server. My server side code looks like this:
[HttpPost]
[Route("upload")]
public async Task<HttpResponseMessage> Upload(uploadFileModel model)
{
var result = new HttpResponseMessage(HttpStatusCode.OK);
if (ModelState.IsValid)
{
string thumbname = "";
string resizedthumbname = Guid.NewGuid() + "_yt.jpg";
string FfmpegPath = Encoding_Settings.FFMPEGPATH;
string tempFilePath = Path.Combine(HttpContext.Current.Server.MapPath("~/tempuploads"), model.fileName);
string pathToFiles = HttpContext.Current.Server.MapPath("~/tempuploads");
string pathToThumbs = HttpContext.Current.Server.MapPath("~/contents/member/" + model.username + "/thumbs");
string finalPath = HttpContext.Current.Server.MapPath("~/contents/member/" + model.username + "/flv");
string resizedthumb = Path.Combine(pathToThumbs, resizedthumbname);
var outputPathVid = new MediaFile { Filename = Path.Combine(finalPath, model.fileName) };
var inputPathVid = new MediaFile { Filename = Path.Combine(pathToFiles, model.fileName) };
int maxWidth = 380;
int maxHeight = 360;
var namewithoutext = Path.GetFileNameWithoutExtension(Path.Combine(pathToFiles, model.fileName));
thumbname = model.VideoThumbName;
string oldthumbpath = Path.Combine(pathToThumbs, thumbname);
var fileName = model.fileName;
File.WriteAllBytes(tempFilePath, model.data);
if (model.fileName.Contains("audio"))
{
File.WriteAllBytes(Path.Combine(finalPath, model.fileName), model.data);
string audio_thumb = "mic_thumb.jpg";
string destination = Path.Combine(pathToThumbs, audio_thumb);
string source = Path.Combine(pathToFiles, audio_thumb);
if (!System.IO.File.Exists(destination))
{
System.IO.File.Copy(source, destination, true);
}
Video_Struct vd = new Video_Struct();
vd.CategoryID = 0; // store categoryname or term instead of category id
vd.Categories = "";
vd.UserName = model.username;
vd.Title = "";
vd.Description = "";
vd.Tags = "";
vd.OriginalVideoFileName = model.fileName;
vd.VideoFileName = model.fileName;
vd.ThumbFileName = "mic_thumb.jpg";
vd.isPrivate = 0;
vd.AuthKey = "";
vd.isEnabled = 1;
vd.Response_VideoID = 0; // video responses
vd.isResponse = 0;
vd.isPublished = 1;
vd.isReviewed = 1;
vd.Thumb_Url = "none";
//vd.FLV_Url = flv_url;
vd.Embed_Script = "";
vd.isExternal = 0; // website own video, 1: embed video
vd.Type = 0;
vd.YoutubeID = "";
vd.isTagsreViewed = 1;
vd.Mode = 0; // filter videos based on website sections
long videoid = VideoBLL.Process_Info(vd, false);
}
else
{
using (var engine = new Engine())
{
engine.GetMetadata(inputPathVid);
// Saves the frame located on the 15th second of the video.
var outputPathThumb = new MediaFile { Filename = Path.Combine(pathToThumbs, thumbname+".jpg") };
var options = new ConversionOptions { Seek = TimeSpan.FromSeconds(0), CustomHeight = 360, CustomWidth = 380 };
engine.GetThumbnail(inputPathVid, outputPathThumb, options);
}
Image image = Image.FromFile(Path.Combine(pathToThumbs, thumbname+".jpg"));
//var ratioX = (double)maxWidth / image.Width;
//var ratioY = (double)maxHeight / image.Height;
//var ratio = Math.Min(ratioX, ratioY);
var newWidth = (int)(maxWidth);
var newHeight = (int)(maxHeight);
var newImage = new Bitmap(newWidth, newHeight);
Graphics.FromImage(newImage).DrawImage(image, 0, 0, newWidth, newHeight);
Bitmap bmp = new Bitmap(newImage);
bmp.Save(Path.Combine(pathToThumbs, thumbname+"_resized.jpg"));
//File.Delete(Path.Combine(pathToThumbs, thumbname));
using (var engine = new Engine())
{
var conversionOptions = new ConversionOptions
{
VideoSize = VideoSize.Hd720,
AudioSampleRate = AudioSampleRate.Hz44100,
VideoAspectRatio = VideoAspectRatio.Default
};
engine.GetMetadata(inputPathVid);
engine.Convert(inputPathVid, outputPathVid, conversionOptions);
}
File.Delete(tempFilePath);
Video_Struct vd = new Video_Struct();
vd.CategoryID = 0; // store categoryname or term instead of category id
vd.Categories = "";
vd.UserName = model.username;
vd.Title = "";
vd.Description = "";
vd.Tags = "";
vd.Duration = inputPathVid.Metadata.Duration.ToString();
vd.Duration_Sec = Convert.ToInt32(inputPathVid.Metadata.Duration.Seconds.ToString());
vd.OriginalVideoFileName = model.fileName;
vd.VideoFileName = model.fileName;
vd.ThumbFileName = thumbname+"_resized.jpg";
vd.isPrivate = 0;
vd.AuthKey = "";
vd.isEnabled = 1;
vd.Response_VideoID = 0; // video responses
vd.isResponse = 0;
vd.isPublished = 1;
vd.isReviewed = 1;
vd.Thumb_Url = "none";
//vd.FLV_Url = flv_url;
vd.Embed_Script = "";
vd.isExternal = 0; // website own video, 1: embed video
vd.Type = 0;
vd.YoutubeID = "";
vd.isTagsreViewed = 1;
vd.Mode = 0; // filter videos based on website sections
//vd.ContentLength = f_contentlength;
vd.GalleryID = 0;
long videoid = VideoBLL.Process_Info(vd, false);
}
return result;
}
else
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotAcceptable, "This request is not properly formatted"));
}
}`
What am I doing wrong here that's making the app crash. Is there a better way to do this?
Any help is appreciated.