Skip to content

Instantly share code, notes, and snippets.

@chikien276
Created July 28, 2017 08:03
Show Gist options
  • Save chikien276/6e570b9a2b0d96eb89d69b22f7d4f199 to your computer and use it in GitHub Desktop.
Save chikien276/6e570b9a2b0d96eb89d69b22f7d4f199 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.IO;
using Microsoft.AspNetCore.Hosting;
namespace VideoServing.Controllers
{
[Route("api/[controller]")]
public class VideoController : Controller
{
private IHostingEnvironment _evn;
public VideoController(IHostingEnvironment env)
{
_evn = env;
}
// GET api/values
[HttpGet]
public async Task Get()
{
const int PART_SIZE = 0x100000;
var fileLocation = "/home/vzota/lotr.mp4";
if (_evn.IsDevelopment())
{
fileLocation = "C:/users/admin/1.mp4";
}
Response.ContentType = "video/mp4";
Response.Headers["Accept-Ranges"] = "bytes";
Stream file = new FileStream(fileLocation, FileMode.Open, FileAccess.Read, FileShare.Read, PART_SIZE);
string rangeRequest = Request.Headers["Range"];
long start = 0L;
long end = Math.Min(PART_SIZE, file.Length);
if (!string.IsNullOrEmpty(rangeRequest))
{
var byteIndex = rangeRequest.ToLower().IndexOf("bytes=");
if (byteIndex != -1)
{
var pr = rangeRequest.Substring("bytes=".Length);
var split = pr.Split('-');
start = int.Parse(split[0]);
if (split.Length > 1 && !string.IsNullOrEmpty(split[1]))
end = int.Parse(split[1]);
else
end = Math.Min(start + PART_SIZE, file.Length);
}
if (start > file.Length || end > file.Length)
{
Response.StatusCode = 416;
return;
}
}else
{
Response.StatusCode = 200;
return;
}
file.Seek(start, SeekOrigin.Begin);
var contentLength = end - start;
if (contentLength < PART_SIZE)
{
Response.Cookies.Append("hehe", "huhu");
}
Response.ContentLength = contentLength;
Response.StatusCode = 206;
Response.Headers["Content-Range"] = $"bytes {start}-{end}/{file.Length}";
byte[] buffer = new byte[0x1000];
var wrote = 0;
if (end == file.Length)
{
await file.CopyToAsync(Response.Body);
}
else
while (wrote < Response.ContentLength)
{
var read = await file.ReadAsync(buffer, 0, 4096);
await Response.Body.WriteAsync(buffer, 0, read);
wrote += read;
}
Response.Body.Flush();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment