I created a bot with bot framework and now i'm trying to use the CustomSpeech service instead of the bing SpeechToText Service that works fine. I have tried various way to resolve the problem but i get the error 400 and i don't know how to solve this.
The method where i would like to get the text from a Stream of a wav pcm audio:
public static async Task<string> CustomSpeechToTextStream(Stream audioStream)
{
audioStream.Seek(0, SeekOrigin.Begin);
var customSpeechUrl = "https://westus.stt.speech.microsoft.com/speech/recognition/interactive/cognitiveservices/v1?cid=<MyEndPointId>";
string token;
token = GetToken();
HttpWebRequest request = null;
request = (HttpWebRequest)HttpWebRequest.Create(customSpeechUrl);
request.SendChunked = true;
//request.Accept = #"application/json;text/xml";
request.Method = "POST";
request.ProtocolVersion = HttpVersion.Version11;
request.ContentType = "audio/wav; codec=\"audio/pcm\"; samplerate=16000";
request.Headers["Authorization"] = "Bearer " + token;
byte[] buffer = null;
int bytesRead = 0;
using (Stream requestStream = request.GetRequestStream())
{
// Read 1024 raw bytes from the input audio file.
buffer = new Byte[checked((uint)Math.Min(1024, (int)audioStream.Length))];
while ((bytesRead = audioStream.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
requestStream.Flush();
}
string responseString = string.Empty;
// Get the response from the service.
using (WebResponse response = request.GetResponse()) // Here i get the error
{
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
responseString = sr.ReadToEnd();
}
}
dynamic deserializedResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(responseString);
if (deserializedResponse.RecognitionStatus == "Success")
{
return deserializedResponse.DisplayText;
}
else
{
return null;
}
}
At using (WebResponse response = request.GetResponse()){} i get an exception (Error 400).
Am I doing the HttpWebRequest in the right way?
I read in internet that maybe the problem is the file audio... but then why with the same Stream bing speech service doesn't return this error?
In my case the problem was that i had a wav stream audio that doesn't had the file header that Cris (Custom Speech Service) needs. The sulution is creating a temporary file wav, read the file wav and copy it in a Stream to send it as array to Cris
byte[] buffer = null;
int bytesRead = 0;
using (Stream requestStream = request.GetRequestStream())
{
buffer = new Byte[checked((uint)Math.Min(1024, (int)audioStream.Length))];
while ((bytesRead = audioStream.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
}
requestStream.Flush();
}
or copy it in a MemoryStream and send it as array
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(audioStream.ToArray(), 0, audioStream.ToArray().Length);
requestStream.Flush();
}
Related
I need to upload text file from local machine to ftp server using c#.
I've tried folowing code but it did't work.
private bool UploadFile(FileInfo fileInfo)
{
FtpWebRequest request = null;
try
{
string ftpPath = "ftp://www.tt.com/" + fileInfo.Name
request = (FtpWebRequest)WebRequest.Create(ftpPath);
request.Credentials = new NetworkCredential("ftptest", "ftptest");
request.Method = WebRequestMethods.Ftp.UploadFile;
request.KeepAlive = false;
request.Timeout = 60000; // 1 minute time out
request.ServicePoint.ConnectionLimit = 15;
byte[] buffer = new byte[1024];
using (FileStream fs = new FileStream(fileInfo.FullPath, FileMode.Open))
{
int dataLength = (int)fs.Length;
int bytesRead = 0;
int bytesDownloaded = 0;
using (Stream requestStream = request.GetRequestStream())
{
while (bytesRead < dataLength)
{
bytesDownloaded = fs.Read(buffer, 0, buffer.Length);
bytesRead = bytesRead + bytesDownloaded;
requestStream.Write(buffer, 0, bytesDownloaded);
}
requestStream.Close();
}
}
return true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
request = null;
}
return false;
}// UploadFile
any suggestions ???
You need to actually send the request by calling GetResponse().
You can also make your code much simpler by calling fs.CopyTo(requestStream).
I tinkered around with a bit ftp code and got the following, which seems to work pretty well for me.
ftpUploadloc is a ftp://ftp.yourftpsite.com/uploaddir/yourfilename.txt
ftpUsername and ftpPassword should be self explanatory.
Finally currentLog is the location of the file you're uploading.
Let me know how this worked out for you, if anyone else has any other suggestions I welcome those.
private void ftplogdump()
{
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(ftpUploadloc);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential(ftpUsername, ftpPassword);
StreamReader sourceStream = new StreamReader(currentLog);
byte[] fileContents = Encoding.UTF8.GetBytes(sourceStream.ReadToEnd());
sourceStream.Close();
request.ContentLength = fileContents.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(fileContents, 0, fileContents.Length);
requestStream.Close();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
// Remove before publishing
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
}
I'm passing the stream this way:
StreamReader sr = new StreamReader(openFileDialog1.FileName);
byte[] fileStream = Utility.ReadFully(sr.BaseStream);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress));
request.Method = "POST";
request.ContentType = "application/octet-stream";
Stream serverStream = request.GetRequestStream();
serverStream.Write(fileStream, 0, fileStream.Length);
serverStream.Close();
HttpWebResponse response2 = (HttpWebResponse)request.GetResponse();
if (response2.StatusCode == HttpStatusCode.OK)
{
MessageBox.Show(Utility.ReadResponse(response2));
}
-------------------------------------------------------------------------
public static byte[] ReadFully(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
if (input != null)
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
}
return ms.ToArray();
}
}
Then handling it on the server:
public bool UploadPhotoStream(string someStringParam, Stream fileData)
{
string filePath = string.Format("{0}/{1}", 'sdfgsdf87s7df8sd', '24asd54s4454d5f4g');
ProductPhoto newphoto = new ProductPhoto();
newphoto.FileSizeBytes = fileData.Length / 1024 / 1024;
newphoto.FileLocation = filePath;
...
}
Now I'm getting NotSupportedException when calling fileData.Length. I know it happens because the stream is closed. But how can I re-open it? Or what should I do so that when I pass the stream to the service I can still get its length?
Why don't you pass content-length header? Your server can check the header and know exactly how many bytes is the content being sent. How you read the header depends on which http framework you are using, ASP.NET Web Api, classic WCF Web Api, HttpListener, etc.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new Uri(baseAddress));
request.Method = "POST";
request.ContentType = "application/octet-stream";
request.ContentLength = new FileInfo(openFileDialog1.FileName).Length
Without a Content-Length header, an http server can never know how many bytes are left to read. All it knows is there is a Stream and will read it till there is no more data. This is also how your browser can display a progress bar when downloading something. It takes bytesDownloaded / Content-Length.
According to this post: https://stackoverflow.com/a/8239268/1160036
You can access the header like this from your web method.
long dataLength = long.Parse(HttpContext.Current.Request.Headers["Content-Length"]);
I have a c# script that does 2 things
This script connects a my web server to get a pin number generated,
It then makes a connection where its post a form with that pin number it gets from my web server,
The problem is when the form is posted it responds with an application now i need to run this application i don't care if i have to save the exe then run it or if i can run it from memory
Here is my script sofar
string[] responseSplit;
bool connected = false;
try
{
request = (HttpWebRequest)WebRequest.Create(API_url + "prams[]=");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
connected = true;
}
catch(Exception e)
{
MessageBox.Show(API_url + "prams[]=");
}
if (!connected)
{
MessageBox.Show("Support Requires and Internet Connection.");
}
else
{
request = (HttpWebRequest)WebRequest.Create(API_url + "prams[]=");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream resStream = response.GetResponseStream();
StreamReader reader = new StreamReader(resStream);
string responceString = reader.ReadToEnd();
responseSplit = responceString.Split('\n');
WebRequest req = WebRequest.Create("https://secure.logmeinrescue.com/Customer/Code.aspx");
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes("Code=" + responseSplit[1]);
req.ContentLength = bytes.Length;
Stream os = req.GetRequestStream();
os.Write(bytes, 0, bytes.Length);
os.Close();
WebResponse responce = req.GetResponse();
hasDownloaded = true;
}
Well you could save the response into a file and then run it (assuming it's an executable of course):
using (var response = req.GetResponse())
using (var responseStream = response.GetResponseStream())
using (var output = new FileStream("test.exe", FileMode.Create, FileAccess.Write))
{
var buffer = new byte[2048]; // read in chunks of 2KB
int bytesRead;
while ((bytesRead = responseStream.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
Process.Start("test.exe");
I need to download a text file from the internet using C#. The file size can be quite large and the information I need is always within the first 1000 bytes. Is this possible?
Stolen from here.
string GetWebPageContent(string url)
{
string result = string.Empty;
HttpWebRequest request;
const int bytesToGet = 1000;
request = WebRequest.Create(url) as HttpWebRequest;
//get first 1000 bytes
request.AddRange(0, bytesToGet - 1);
// the following code is alternative, you may implement the function after your needs
using (WebResponse response = request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
byte[] buffer = new byte[1024];
int read = stream.Read(buffer, 0, 1000);
Array.Resize(ref buffer, read);
return Encoding.ASCII.GetString(buffer);
}
}
}
(Edited as requested in the comments... ;) )
I did this as an answer to your newer question. You could put the range header in too if you want, but I excluded it.
string GetWebPageContent(string url)
{
//string result = string.Empty;
HttpWebRequest request;
const int bytesToGet = 1000;
request = WebRequest.Create(url) as HttpWebRequest;
var buffer = new char[bytesToGet];
using (WebResponse response = request.GetResponse())
{
using (StreamReader sr = new StreamReader(response.GetResponseStream()))
{
sr.Read(buffer, 0, bytesToGet);
}
}
return new string(buffer);
}
In C# rather than having to dowloading a file from the web using httpwebrequest, save this to file somewhere, and then upload to a webservice using a POST with the file as one of the parameters...
Can I instead somehow open a reader stream from httpwebresponse and then stream this into the http POST? Any code someone could post to show how?
In other words I'm trying to avoid haing to save to disk first.
Thanks
Something like that should do the trick :
HttpWebRequest downloadRequest = WebRequest.Create(downloadUri) as HttpWebRequest;
using(HttpWebResponse downloadResponse = downloadRequest.GetResponse() as HttpWebResponse)
{
HttpWebRequest uploadRequest = new HttpWebRequest(uploadUri);
uploadRequest.Method = "POST";
uploadRequest.ContentLength = downloadResponse.ContentLength;
using (Stream downloadStream = downloadResponse.GetResponseStream())
using (Stream uploadStream = uploadRequest.GetRequestStream())
{
byte[] buffer = new byte[4096];
int totalBytes = 0;
while(totalBytes < downloadResponse.ContentLength)
{
int nBytes = downloadStream.Read(buffer, 0, buffer.Length);
uploadStream.Write(buffer, 0, nBytes);
totalBytes += nRead;
}
}
HttpWebResponse uploadResponse = uploadRequest.GetResponse() as HttpWebResponse;
uploadResponse.Close();
}
(untested code)