public Stream InfoVideoFromFilename(string base64filename, int?userId, bool?autowatch, string fakename) { InfoResult r = ResolveFilename(base64filename, userId, autowatch); StreamWithResponse s = new StreamWithResponse(r.Status, r.StatusDescription); if (r.Status != HttpStatusCode.OK && r.Status != HttpStatusCode.PartialContent) { return(s); } s.Headers.Add("Server", ServerVersion); s.Headers.Add("Accept-Ranges", "bytes"); s.Headers.Add("Content-Range", "bytes 0-" + (r.File.Size - 1) + "/" + r.File.Size); s.ContentType = r.Mime; s.ContentLength = r.File.Size; return(s); }
private Stream StreamFromIFile(InfoResult r, bool?autowatch) { try { var request = HttpContext.Request; FileSystemResult <Stream> fr = r.File.OpenRead(); if (fr == null || fr.Status != Status.Ok) { return(new StreamWithResponse(HttpStatusCode.InternalServerError, "Unable to open file '" + r.File.FullName + "': " + fr?.Error)); } Stream org = fr.Result; long totalsize = org.Length; long start = 0; long end = totalsize - 1; string rangevalue = request.Headers["Range"].FirstOrDefault() ?? request.Headers["range"].FirstOrDefault(); rangevalue = rangevalue?.Replace("bytes=", string.Empty); bool range = !string.IsNullOrEmpty(rangevalue); if (range) { // range: bytes=split[0]-split[1] string[] split = rangevalue.Split('-'); if (split.Length == 2) { // bytes=-split[1] - tail of specified length if (string.IsNullOrEmpty(split[0]) && !string.IsNullOrEmpty(split[1])) { long e = long.Parse(split[1]); start = totalsize - e; end = totalsize - 1; } // bytes=split[0] - split[0] to end of file else if (!string.IsNullOrEmpty(split[0]) && string.IsNullOrEmpty(split[1])) { start = long.Parse(split[0]); end = totalsize - 1; } // bytes=split[0]-split[1] - specified beginning and end else if (!string.IsNullOrEmpty(split[0]) && !string.IsNullOrEmpty(split[1])) { start = long.Parse(split[0]); end = long.Parse(split[1]); if (start > totalsize - 1) { start = totalsize - 1; } if (end > totalsize - 1) { end = totalsize - 1; } } } } var outstream = new SubStream(org, start, end - start + 1); var resp = new StreamWithResponse { ContentType = r.Mime }; resp.Headers.Add("Server", ServerVersion); resp.Headers.Add("Connection", "keep-alive"); resp.Headers.Add("Accept-Ranges", "bytes"); resp.Headers.Add("Content-Range", "bytes " + start + "-" + end + "/" + totalsize); resp.ContentLength = end - start + 1; resp.ResponseStatus = range ? HttpStatusCode.PartialContent : HttpStatusCode.OK; if (r.User != null && autowatch.HasValue && autowatch.Value && r.VideoLocal != null) { outstream.CrossPosition = (long)(totalsize * WatchedThreshold); outstream.CrossPositionCrossed += (a) => { Task.Factory.StartNew(() => { r.VideoLocal.ToggleWatchedStatus(true, r.User.JMMUserID); }, new CancellationToken(), TaskCreationOptions.LongRunning, TaskScheduler.Default); }; } resp.Stream = outstream; return(resp); } catch (Exception e) { logger.Error("An error occurred while serving a file: " + e); var resp = new StreamWithResponse(); resp.ResponseStatus = HttpStatusCode.InternalServerError; resp.ResponseDescription = e.Message; return(resp); } }