public HttpContent CreateHttpContent(byte[] ContentBytes, string MimeType, long?From, long?To) { long contentExtent = (long)ContentBytes.Length - 1; VideoStreamContentByteRange byteRange = VideoStreamFactoryHelper.ExtractByteRange(From, To, contentExtent); if (byteRange.From < 0 || byteRange.From > contentExtent || byteRange.To > contentExtent) { string errorMessage = "The requested range (bytes=" + ((From.HasValue) ? From.Value.ToString() : "") + "-" + ((To.HasValue) ? To.Value.ToString() : "") + ") does not overlap with the current extent of the selected resource."; throw new InvalidByteRangeException(new ContentRangeHeaderValue(0, ContentBytes.Length), errorMessage); } VideoStreamContentByteRange[] singleByteRange = new VideoStreamContentByteRange[1]; singleByteRange[0] = byteRange; var result = new VideoStreamContent(this, ContentBytes, MimeType, _bufferSize, _throttleRate, singleByteRange); result.Headers.ContentRange = new ContentRangeHeaderValue(byteRange.From, byteRange.To, ContentBytes.Length); result.Headers.ContentType = new MediaTypeHeaderValue(MimeType); return(result); }
public VideoStreamContent(VideoStreamFactory Factory, byte[] ContentBytes, string MimeType, int BufferSize, int ThrottleRate, VideoStreamContentByteRange[] ByteRanges) { _source = ContentBytes; _bufferSize = BufferSize; _throttleRate = ThrottleRate; _mimeType = MimeType; _byteRanges = new VideoStreamContentByteRange[ByteRanges.Length]; for (int i = 0; i < ByteRanges.Length; i++) { long from = ByteRanges[i].From; long to = ByteRanges[i].To + 1; _byteRanges[i] = new VideoStreamContentByteRange(from, to); } _factory = Factory; }
private async Task ThrottledWrite(byte[] SourceBytes, string MimeType, Stream OutStream, VideoStreamContentByteRange[] ByteRanges, int BufferSize, int ThrottleRate) { await Task.Factory.StartNew(() => { try { for (int i = 0; i < ByteRanges.Length; i++) { VideoStreamContentByteRange currentRange = ByteRanges[i]; int indexFrom = (int)currentRange.From; int countTo = (int)(currentRange.To - currentRange.From); if (ByteRanges.Length > 1) { using (StreamWriter streamWriter = new StreamWriter(OutStream, System.Text.Encoding.ASCII, 4096, leaveOpen: true)) { if (i > 0) { streamWriter.WriteLine(); } streamWriter.WriteLine("--" + _byteRangeBoundary.ToString()); streamWriter.WriteLine("Content-Type: " + MimeType); streamWriter.WriteLine("Content-Range: bytes " + currentRange.From.ToString() + "-" + (currentRange.To - 1).ToString() + "/" + SourceBytes.Length); streamWriter.WriteLine(); OutStream.Flush(); } } byte[] buffer = new byte[BufferSize]; int bytesRead = 1; using (MemoryStream streamBytes = new MemoryStream(buffer: SourceBytes, index: indexFrom, count: countTo, writable: false)) { while (bytesRead > 0) { bytesRead = streamBytes.Read(buffer, 0, BufferSize); OutStream.Write(buffer, 0, bytesRead); OutStream.Flush(); if (_abort) { break; } Thread.Sleep(ThrottleRate); } } } if (ByteRanges.Length > 1) { using (StreamWriter streamWriter = new StreamWriter(OutStream, System.Text.Encoding.ASCII, 4096, leaveOpen: true)) { streamWriter.WriteLine(); streamWriter.WriteLine("--" + _byteRangeBoundary.ToString() + "--"); OutStream.Flush(); } } } catch (HttpException ex) { var snoop = ex; } finally { OutStream.Dispose(); } }, TaskCreationOptions.LongRunning); }