Я искал аналогичную проблему и понял, что мне нужно добавить «Content-Disposition». заголовок с «вложением» и моим именем файла. Несмотря на то, что я добавил это в свой заголовок, он все равно загружается, а затем показывает завершенное диалоговое окно.
Ниже приведен мой код:
Код для моего сервиса:
Код: Выделить всё
public async Task GetVideoStreamAsync(string videoCode, CancellationToken cancellationToken = default)
{
var localVideoPath = Path.Combine(BaseVideoPath, videoCode + ".mp4");
if (File.Exists(localVideoPath))
{
await using var fs = new FileStream(localVideoPath, FileMode.Open, FileAccess.Read, FileShare.Read);
var sr = new MemoryStream();
await fs.CopyToAsync(sr, cancellationToken);
sr.Position = 0; // Reset the position of the MemoryStream to the start after copying
return sr;
}
return null;
}
Код: Выделить всё
[HttpGet("GetStream")]
public async Task StreamVideo([FromQuery] string videoCode, CancellationToken cancellationToken = default)
{
try
{
var filePath = Path.Combine(BaseVideoPath, videoCode + ".mp4");
if (!System.IO.File.Exists(filePath))
{
return NotFound("Video not found.");
}
var fileInfo = new FileInfo(filePath);
var fileLength = fileInfo.Length;
var videoStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
var fileName = $"{videoCode}.mp4";
Response.ContentType = "video/mp4";
Response.Headers.Add("Content-Disposition", $"attachment; filename=\"{fileName}\"");
Response.Headers.Add("Accept-Ranges", "bytes");
if (Request.Headers.ContainsKey("Range"))
{
return await ProcessRangeRequest(videoStream, fileLength, cancellationToken);
}
// Set the Content-Length for full downloads
Response.ContentLength = fileLength;
return File(videoStream, "video/mp4", enableRangeProcessing: true);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to stream video");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
private async Task ProcessRangeRequest(Stream videoStream, long actualFileSize, CancellationToken cancellationToken)
{
var rangeHeader = RangeHeaderValue.Parse(Request.Headers["Range"].ToString());
var range = rangeHeader.Ranges.First();
var start = range.From ?? 0;
var end = range.To ?? actualFileSize - 1;
if (start >= actualFileSize || end >= actualFileSize)
{
Response.Headers.Add("Content-Range", $"bytes */{actualFileSize}");
return StatusCode(StatusCodes.Status416RequestedRangeNotSatisfiable);
}
var contentLength = end - start + 1;
Response.StatusCode = StatusCodes.Status206PartialContent;
Response.Headers.Add("Content-Range", $"bytes {start}-{end}/{actualFileSize}");
Response.ContentLength = contentLength;
// Position the stream and copy the range to the response body
videoStream.Position = start;
await videoStream.CopyToAsync(Response.Body, Convert.ToInt32(end - start + 1), cancellationToken);
return new EmptyResult();
}
Я попробовал почти каждый заголовок, меняя «Content-Disposition», но проблема все та же.
Подробнее здесь: https://stackoverflow.com/questions/783 ... n-browsers
Мобильная версия