C# Winforms application - Upload Stream progress bar - c#

I'm looking to add a progress bar to a file upload to a WebService.
I just started working on a winforms application that I believe uses WCF to allow the client to upload a document to our corporate repository.
I'm using a UploadService where I pass it a Multi-part Stream consisting of metadata and a file. I've already taken care of building this part.
I'm not quite sure how to go about how to hook "something" to the stream so I can track it being uploaded
I've seen some people using a background worker to track the progress of a task asynchronously, but can't seem to find an example of someone doing this to track a file being uploaded to a WebService. I only seem to find an example of someone tracking the stream being built into memory.
Any advice/help is appreciated.
Thank you!
(I'm an intern, so if I mis-explained things, I apologize. I'd be happy to provide clearer details if necessary)
edit: From what I can tell the method to upload the stream only takes a stream in, there's no option to hand it the size of the stream, or how many bytes to read at a time.

Assuming you know the size of the file (if it's local you most likely do).
You're probably accessing it off-disk as a stream, and then copying it over to the upload stream.
If you're doing it in chunks (e.g a buffer), then you can calculate the progress:
var totalNumberOfChunks = (fileSize / chunkSize);
for(var chunk = 0; chunk < totalNumberOfChunks; chunk++)
{
// assuming you have the chunk byte array
// and have already sent it up to the server
var progress = ((double)chunk / totalNumberOfChunks) * 100;
// do something to surface this progress
}
Essentially you just want to work out how many separate chunks of data you're sending, and then as you send them calculate how far along you are and surface the progress somehow.
Of course, there are sometimes ways to have this done for you: Getting the upload progress during file upload using Webclient.Uploadfile

Related

Limit upload speed on c#

Im building an app to upload clips auto to a Minio S3 server.
When im playing and save a clip, the app uses 100% of bandwidth and this is so annoying.
I need to limit the upload speed to complete this, Thanks!
My upload string:
await s3.PutObjectAsync(bucketName, objectName, filePath, contentType);
You can't really do that with any built in functions, but one thing you could try is handling the transfer yourself at your own rate by writing a custom ThrottledStream.
That exercise will teach you how difficult what you want is to get right (for example, you can't just send X amount of data every second), so that's also a plus!

Send a slice of a Video File through HttpHandler

i am a .Net developer who has written a CMS-System for the Intranet of a specific company.
Our client has the ability to upload videos and other media there and let his employees and customers view them alongside other information.
We use a Standard Httphandler to fetch the uploaded video from HDD of the server and context.response.TransmitFile() it to the Browser.
So we can use this Handler as target for a html5 src-Attribute.
Now i've gotten a request to sort of "emulate" a videostream. The idea is that the client uplaods the video as a file, sets a specific start date from which the video should be viewable and every Request to the video should then return only the slice from the video from startdate to now.
Sort of pretending this video would be a live stream which goes forward on its own.
I tried adapting the HttpHandler to calculate the number of seconds between the startdate and the current request time, multiply it by the bitrate of the video and then simply cut off x bytes from the Stream (for example using Stream.seek) but the resulting data does not get recognized by Brwosers as a valid video stream. I guess this is because of missing (cut away) header-informations and key-frames etc.
Does anybody know a library who allows me to do this (cutting the video in slices without writing them to harddisk, i dont want to have a videofile laying around for every request thats landed on my httphandler)
The video is in mp4 format and i would liek to avoid the additional overhead of having to transcode it (like VLC requires when you use it for streaming)
Any ideas on this topic, im kinda lost...!?
Thanks in advance.
Chris
Clarification:
I do not know how much to cut off the video beforehand, that depends on the moment the stream is requested.
The Formula is easy: Date of the Request (Datetime.Now) - Configured Start time of the video. This Timespan has to be "skipped" from the start of the video.
Ideally i woudl like some library which allows me to load the file as a fileStream, skip x Seconds and write the remaining bytes/frames to the output of the httphandler. But i have no idea how to do this as VLC and FFMPEG seem so only support slicing by writing files, not giving me the sliced data as a stream...

get image from video stream in C#

I am trying to get image from a stream (MemoryStream to be more precise). I can not find anything from Microsoft that can solve my problem.
I am getting my streams from SQL so if there is some way to get an image from there, it will be OK.
I have checked ffmpeg and the problem is that I need to save the video files. The files can reach up to 2GB and if there is a way not writing to the disk it will be helpful. If there is a way to read only the first 10MB or other limited size and read the image from it, that can also be a solution.
Video feed might be as simple as raw uncompressed video frames side by side to more complex multiplexed file format compatible chunk of data, e.g. .MP4 file. While the former case might be pretty simple, the latter requires you to demultiplex the file, seek within the stream, start decoding, possibly skip a few frames, then grab the frame of interest. The point is that it might be not as simple as it seems.
Video processing APIs in Windows are DirectShow, Media Foundation. With DirectShow it is possible to create a custom data source on top of SQL backed data stream and stream from there fetching DB data on demand, using API interfaces components (stock and third party) to do the rest of the task.
It is possible to capture frames with free VideoConverter for .NET that actually is a wrapper to FFMpeg tool. The idea is using live streaming capabilities (to C# Stream) of VideoConverter for special FFMpeg format "rawvideo" that actually is bitmap stream that can be processed by C# program, something like that:
var videoConv = new FFMpegConverter();
var ffMpegTask = videoConv.ConvertLiveMedia(
"input.mp4",
null, // autodetect live stream format
rawBmpOutputStream, // this is your special stream that will capture bitmaps
"rawvideo",
new ConvertSettings() {
VideoFrameSize = "320x200", // lets resize to exact frame size
CustomOutputArgs = " -pix_fmt bgr24 ", // windows bitmap pixel format
VideoFrameRate = 5, // lets consume 5 frames per second
MaxDuration = 5 // lets consume live stream for first 5 seconds
});
VideoConverter can read live streams from another .NET Stream (if input format can be used with live stream conversion).

Reading Data from a File as it grows

I have a binary data file that is written to from a live data stream, so it keeps on growing as stream comes. In the meanwhile, I need to open it at the same time in read-only mode to display data on my application (time series chart). Opening the whole file takes a few minutes as it is pretty large (a few 100' MBytes).
What I would like to do is, rather than re-opening/reading the whole file every x seconds, read only the last data that was added to the file and append it to the data that was already read.
I would suggest using FileSystemWatcher to be notified of changes to the file. From there, cache information such as the size of the file between events and add some logic to only respond to full lines, etc. You can use the Seek() method of the FileStream class to jump to a particular point in the file and read only from there. I hope it helps.
If you control the writing of this file, I would split it in several files of a predefined size.
When the writer determines that the current file is larger than, say, 50MB, close it and immediately create a new file to write data to. The process writing this data should always know the current file to write received data to.
The reader thread/process would read all these files in order, jumping to the next file when the current file was read completely.
You can probably use a FileSystemWatcher to monitor for changes in the file, like the example given here: Reading changes in a file in real-time using .NET.
But I'd suggest that you evaluate another solution, including a queue, like RabbitMQ, or Redis - any queue that has Subscriber-Publisher model. Then you'll just push the live data into the queue, and will have 2 different listeners(subscribers) - one to save in the file, and the other to process the last-appended data. This way you can achieve more flexibility with distributing load of the application.

Creating an MJPEG video stream in c#

I have images being sent to my database from a remote video source at about 5 frames per second as JPEG images. I am trying to figure out how to get those images into a video format so I can stream a live video feed to Silverlight.
It seems to make sense to create a MJPEG stream but I'm having a few problems. Firstly I was trying to stream via an HTTP request so I didn't have a deal with sockets but maybe this is breaking my code.
If I try surf to my stream from QT I get a video error, Media player shows the first frame image and Silverlight crashes :)
Here is the code that streams - since I content type used this way can only be sent once I know that it isn't ideal and might be the root cause. All images are coming in via a LINQ2SQL object.
I did already try simply updating the image source of an image control in Silverlight but the flicker isn't acceptable. If Silverlight doesn't support MJPEG then no point even continuing but it looks like it does. I do have access to the h.264 frames coming in but that seemed more complicated via MP4.
Response.Clear();
Response.ContentType = "multipart/x-mixed-replace; boundary=--myboundary";
ASCIIEncoding ae = new ASCIIEncoding();
HCData data = new HCData();
var videos = (from v in data.Videos
select v).Take(50); // sample the first 50 frames
foreach (Video frame in videos)
{
byte[] boundary = ae.GetBytes("\r\n--myboundary\r\nContent-Type: image/jpeg\r\nContent-Length:" + frame.VideoData.ToArray().Length + "\r\n\r\n");
var mem = new MemoryStream(boundary);
mem.WriteTo(Response.OutputStream);
mem = new MemoryStream(frame.VideoData.ToArray());
mem.WriteTo(Response.OutputStream);
Response.Flush();
Thread.Sleep(200);
}
Thanks!
EDIT: I have the stream working in firefox so if I surf to the page I see video! but nothing else accepts the format. Not IE, SL, Media player - nothing.
I did MJPEG a long time ago (3-4 years ago) and I'm scratching my head trying to remember the details and I simply can't. But, if its possible, I would suggest finding some kind of web site that streams MJPEG content and fire up wireshark/ethereal and see what you get over the wire. My guess is you are missing some required HTTP headers that firefox is little more forgiving about.
If you can't find a sample MJPEG stream over the internet, a lot of web cams have software that give you an MJPEG stream. The app I worked on it with was a console for multiple security cameras, so I know that is a common implementation for cams of all types (if they support a web interface).
I'm far from being an expert in MJPEG streaming, but looking at the source of mjpg-streamer on sourcefourge I think you should send each frame separately, writing the boundary before and after each of them. You should of course not write the content-type in the closing boundary.
First, write your mjpeg frames out to separate files. You should then be able to open these in Phototshop (this will independently verify that you are parsing the stream correctly). If this fails, by bet is that you have HTTP headers embedded in your image data.
Have you looked at various web cam setups that exist on the net? A lot of them do some sort of low res update without flicker. You should be able to reverse engineer these types of sites for additional clues to your problem.
Some sites create a GIF animation, maybe that is an option so that the user can see the past minute or so.
About your edit: MJPEG is supported by Firefox and Safari. However other applications do not, like Explorer or Silverlight depending on what you are doing with it.

Categories