簡體   English   中英

我想在 ASP.NET Core MVC 上顯示視頻 SQL 數據庫視圖

[英]I want to Show Video on ASP.NET Core MVC View from SQL Database

所以基本上我已經使用以下邏輯將我的視頻文件存儲到我的 SQL 服務器數據庫表中:

using (var dataStream = new MemoryStream())
            {
                await file.CopyToAsync(dataStream);
                VideoSegment video = new VideoSegment
                {
                    VideoData = dataStream.ToArray(),
                    ProfileidForVideoSegment = userprofileid.Id
                };
                Context.VideoSegments.Add(video);
                Context.SaveChanges();
            }

因此,使用上面的代碼,我的數據以 varbinary(MAX) 形式完美存儲到表中,但現在我想檢索此視頻數據以顯示在我的 asp.net 核心網站上播放的視頻。 我為此搜索了很多,但每次我找到與 aspx 相關的解決方案,簡單的 asp.net MVC。 但仍在搜索 ASP.NET Core MVC 網站,因為我想在我的 asp.net core MVC 中顯示視頻,而不是簡單的 asp.net MVC 網站。 所以請告訴我如何完成這項工作的解決方案。 任何形式的幫助將不勝感激。 謝謝。

這是您可以遵循的工作演示:

Model:

public class VideoSegment
{
    public int Id { get; set; }
    public byte[] VideoData { get; set; }
}

創建.cshtml:

@model VideoSegment

<h1>Create</h1>
<div class="row">
    <div class="col-md-4">
        <form asp-action="Create" enctype="multipart/form-data">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="VideoData" class="control-label"></label>
                <input name="file" type="file" class="form-control" />
                <span asp-validation-for="VideoData" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

VideoSegments控制器:

public IActionResult Create()
{
    return View();
}

[HttpPost]
public async Task<IActionResult> Create([FromForm]IFormFile file)
{
    using (var dataStream = new MemoryStream())
    {
        await file.CopyToAsync(dataStream);
        VideoSegment video = new VideoSegment
        {
            VideoData = dataStream.ToArray(),
        };
        _context.VideoSegment.Add(video);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
}

成功添加視頻片段后,您將重定向到索引操作並顯示視頻:

索引.cshtml:

@model IEnumerable<VideoSegment>

<h1>Index</h1>

<p>
    <a asp-action="Create">Create New</a>
</p>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.VideoData)
            </th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                <video autoplay controls src="/Home/SampleVideoStream?id=@item.Id"></video>
            </td>           
        </tr>
}
    </tbody>
</table>

VideoSegments控制器:

public class VideoSegmentsController : Controller
{
    private readonly YourDbContext _context;

    public VideoSegmentsController(YourDbContext context)
    {
        _context = context;
    }

    // GET: VideoSegments
    public async Task<IActionResult> Index()
    {
        return View(await _context.VideoSegment.ToListAsync());
    }
}

家庭控制器:

public class HomeController : Controller
{
    private readonly YourDbContext _context;
    public HomeController(YourDbContext context)
    {
        _context = context;
    }
    public IActionResult SampleVideoStream(int id)
    {
        var data = _context.VideoSegment.Find(id);
        return File(data.VideoData, "video/mp4");
    }
}

stream 可以直接從 SQL 服務器表中取出一個 varbinary。 但是你需要克服一個障礙。

首先,您需要一種訪問DbDataReader的方法。 通過這種方式,您可以重用與 EF Core 相同的基礎架構,因此您無需自己管理連接。 由於不支持此位,因此將來可能會中斷。

// Based on https://github.com/dotnet/efcore/blob/16188163c24b1c803c4d694e9222a2f717fcb376/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs#L211
public static Task<RelationalDataReader> ExecuteReaderRawAsync(this DatabaseFacade db, string sql, IEnumerable<object> parameters, CancellationToken cancellationToken = default)
{
    var dependencies = ((IDatabaseFacadeDependenciesAccessor)db).Dependencies as IRelationalDatabaseFacadeDependencies;
    var cmd = dependencies.RawSqlCommandBuilder
        .Build(sql, parameters);

    return cmd.RelationalCommand
        .ExecuteReaderAsync(new RelationalCommandParameterObject(
            dependencies.RelationalConnection,
            cmd.ParameterValues,
            null,
            ((IDatabaseFacadeDependenciesAccessor)db).Context,
            dependencies.CommandLogger
        ), cancellationToken);
}

現在您可以將 select varbinary 列作為 stream;

using var reader = await context.Database.ExecuteReaderRawAsync(
    "select VideoData from VideoSegment where Id = {0}", 
    new object[] { Id });

if (await reader.ReadAsync()){
    using var stream = reader.DbDataReader.GetStream(0);
    // TODO copy stream to the response.
}    

將 stream 復制到數據庫列中稍微容易一些。 盡管如果您使用 EF Core 插入行,則必須先執行此操作。

var streamParm = new SqlParameter()
{
    SqlDbType = SqlDbType.VarBinary,
    Value = stream
};
await context.Database.ExecuteSqlInterpolatedAsync(
    $"update VideoSegment set VideoData = {streamParm} where id = {Id}");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM