英文:
Getting Video To play using c# ASP.NET MVC
问题
我正在尝试让用户将视频保存到数据库中,然后其他用户可以在线观看这些视频。
我将文件保存在wwwroot/videos/用户名目录下,同时将其他信息(视频名称、描述、URL)保存在数据库中。我已经成功保存了所有文件,但似乎无法播放视频。经过一些研究,我发现由于安全原因,Firefox 和 Chrome 无法从您的磁盘播放视频。是将 IFormFile videofile 正确保存到数据库并且就此结束,还是有办法让它正常工作?
上传和保存视频的代码:
[HttpPost]
public async Task<IActionResult> UploadVideo(VideoViewModel video, IFormFile file)
{
if (file.Length > 0)
{
try
{
string userName = (User.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Name).Value);
string pathString = Path.Combine(@"path", userName);
if (!Directory.Exists(pathString))
{
Directory.CreateDirectory(pathString);
}
int fCount = Directory.GetFiles(pathString, "*", SearchOption.TopDirectoryOnly).Length + 1;
var filePath = Path.Combine(pathString, file.FileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
_videoLogic.SaveVideo(new Video(video.VideoId, video.Description, file.FileName, DateTime.Now, filePath, video.CategoryId));
}
}
catch (Exception ex)
{
ViewBag.Message = "ERROR: " + ex.Message.ToString();
}
}
else
{
ViewBag.Message = "You have not specified a file.";
}
return RedirectToAction("UploadVideo");
}
尝试查看视频的代码:
<h2>Overzicht Videos gebruiker</h2>
<!DOCTYPE html>
<html>
<head>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="container">
@foreach(var item in Model)
{
<div class="col-sm-4 col-md-4 col-xs-12">
<div class="modal-title" style="width:250px;">@item.Name</div>
<hr/>
<div class="video-frame">
<video style="width:250px; height:150px;" controls>
<source src="@Url.Content(item.ContentUrl)" type="video/mp4" />
</video>
</div>
</div>
}
</div>
</body>
</html>
从控制器中获取视频的代码:
[HttpGet]
public ActionResult GetVideosUser(UserViewModel user)
{
List<VideoViewModel> videoViewModels = new List<VideoViewModel>();
string userName = user.FirstName + " " + user.LastName;
string pathString = Path.Combine(@"path", userName);
List<Video> videos = _videoLogic.GetVideos();
foreach (Video video in videos)
{
VideoViewModel videoViewModel = new VideoViewModel(video);
videoViewModels.Add(videoViewModel);
}
return View("ViewerVideoList", videoViewModels);
}
这段代码正确地将数据上传到数据库,并将正确的文件上传到视频文件夹中。它还正确获取了上述的 ContentUrl。如何使这个视频能够正常播放?非常感谢!
代码图片:
在 Chrome 中的 URL:/wwwroot/video/Jesse%20Oosterwijk/WhatsApp%20Video%202019-12-04%20at%2018.04.49.mp4
https://i.stack.imgur.com/OzF4P.jpg
英文:
I am trying to let people save video's on a database, then other users can watch these video's online.
I save my files in wwwroot/videos/Username, while saving other info (name of video, description, url) in a database. Got all of the files to save, but can't seem to be able to play the video's. Did some research and saw that because of security reasons, firefox and chrome, are not able to play video's from your disk. Is it better to save the IFormFile videofile to the database correctly and call it a day? Or is there a way to make this work?
Uploading and saving the video:
[HttpPost]
public async Task<IActionResult> UploadVideo(VideoViewModel video, IFormFile file)
{
if (file.Length > 0)
{
try
{
string userName = (User.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Name).Value);
string pathString = Path.Combine(@"path", userName);
if (!Directory.Exists(pathString))
{
Directory.CreateDirectory(pathString);
}
int fCount = Directory.GetFiles(pathString, "*", SearchOption.TopDirectoryOnly).Length + 1;
var filePath = Path.Combine(pathString, file.FileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
_videoLogic.SaveVideo(new Video(video.VideoId, video.Description, file.FileName, DateTime.Now, filePath, video.CategoryId));
}
}
catch (Exception ex)
{
ViewBag.Message = "ERROR: " + ex.Message.ToString();
}
}
else
{
ViewBag.Message = "You have not specified a file.";
}
return RedirectToAction("UploadVideo");
}
Trying to view the video:
<h2>Overzicht Videos gebruiker</h2>
<!DOCTYPE html>
<html>
<head>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
</head>
<body>
<div class="container">
@foreach(var item in Model)
{
<div class="col-sm-4 col-md-4 col-xs-12">
<div class="modal-title" style="width:250px;">@item.Name</div>
<hr/>
<div class="video-frame">
<video style="width:250px; height:150px;" controls>
<source src="@Url.Content(item.ContentUrl)" type="video/mp4" />
</video>
</div>
</div>
}
</div>
</body>
</html>
Code for getting video in Controller:
[HttpGet]
public ActionResult GetVideosUser(UserViewModel user)
{
List<VideoViewModel> videoViewModels = new List<VideoViewModel>();
string userName = user.FirstName + " " + user.LastName;
string pathString = Path.Combine(@"path", userName);
List<Video> videos = _videoLogic.GetVideos();
foreach (Video video in videos)
{
VideoViewModel videoViewModel = new VideoViewModel(video);
videoViewModels.Add(videoViewModel);
}
return View("ViewerVideoList", videoViewModels);
}
This code correctly uploads data to my database, and uploads the correct file to my videofolder.
It also correctly gets the ContentUrl stated above.
How can I get this video to play correctly?
Many thanks in advance!
Image of the code:
![Code]: https://i.stack.imgur.com/tNhv3.jpg
URL in Chrome: /wwwroot/video/Jesse%20Oosterwijk/WhatsApp%20Video%202019-12-04%20at%2018.04.49.mp4
![ChromeCode]: https://i.stack.imgur.com/yiNqk.jpg
![FileIsThere]: https://i.stack.imgur.com/eDjxJ.jpg
答案1
得分: 0
由于安全原因,Firefox和Chrome无法从您的磁盘播放视频。您可以尝试通过与Web根相关的路径访问这些视频文件,而不是物理路径。
Name = "user1",
ContentUrl = "~/videos/user1/movie.mp4";
测试结果
注意:当出现问题时,如果您检查浏览器中的控制台或HTML源代码,您可能会发现文件路径看起来像这样。
英文:
> Did some research and saw that because of security reasons, firefox and chrome, are not able to play video's from your disk.
You can try to access these video files via a path relative to the web root, rather than a physical path.
Name = "user1",
ContentUrl = "~/videos/user1/movie.mp4"
Test Result
Note: when the issue occurs, if you check Console or html source in your browser, you may find the file path looks like this.
答案2
得分: 0
通过依赖注入,我找到了解决这个问题的方法。我可以将一个IHostingEnvironment添加到我的videocontroller中。这样,我就可以更轻松地将视频保存到我的webroot中。
添加IHostingEnvironment:
public class VideoController : Controller
{
// ... 其他成员变量
private readonly IHostingEnvironment _environment;
public VideoController(VideoLogic videoLogic, CategoryLogic categoryLogic, ReportLogic reportLogic, CommentLogic commentLogic, UserLogic userLogic, IHostingEnvironment environment)
{
_videoLogic = videoLogic;
_categoryLogic = categoryLogic;
_reportLogic = reportLogic;
_commentLogic = commentLogic;
_userLogic = userLogic;
_environment = environment;
}
}
在保存视频的代码中:
[HttpPost]
public async Task<IActionResult> UploadVideo(VideoViewModel video, IFormFile file)
{
if (file.Length > 0)
{
try
{
int userId = int.Parse(User.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Sid)?.Value);
string userName = (User.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Name).Value);
string folder = Path.Combine(_environment.WebRootPath, "video");
string url = @"\video\" + userName + @"\" + file.FileName;
string pathString = Path.Combine(folder, userName);
if (!Directory.Exists(pathString))
{
Directory.CreateDirectory(pathString);
}
var filePath = Path.Combine(pathString, file.FileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
_videoLogic.SaveVideo(new Video(userId, video.VideoId, video.Description, file.FileName, DateTime.Now, url, video.CategoryId));
}
}
catch (Exception ex)
{
ViewBag.Message = "ERROR: " + ex.Message.ToString();
}
}
else
{
ViewBag.Message = "You have not specified a file.";
}
return RedirectToAction("UploadVideo");
}
之后,你可以从数据库中获取视频并从那里获取URL!感谢所有的帮助。
英文:
Found out how to solve the problem. Through dependency injection I can add an IHostingEnvironment to my videocontroller. This way i can save the video more easily to my webroot.
Adding the hostingenvironment:
public class VideoController : Controller
{
private readonly VideoLogic _videoLogic;
private readonly CategoryLogic _categoryLogic;
private readonly ReportLogic _reportLogic;
private readonly CommentLogic _commentLogic;
private readonly UserLogic _userLogic;
private readonly IHostingEnvironment _environment;
public VideoController(VideoLogic videoLogic, CategoryLogic categoryLogic, ReportLogic reportLogic, CommentLogic commentLogic, UserLogic userLogic, IHostingEnvironment environment)
{
_videoLogic = videoLogic;
_categoryLogic = categoryLogic;
_reportLogic = reportLogic;
_commentLogic = commentLogic;
_userLogic = userLogic;
_environment = environment;
}
In the code saving the video:
[HttpPost]
public async Task<IActionResult> UploadVideo(VideoViewModel video, IFormFile file)
{
if (file.Length > 0)
{
try
{
int userId = int.Parse(User.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Sid)?.Value);
string userName = (User.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.Name).Value);
string folder = Path.Combine(_environment.WebRootPath, "video");
string url = @"\video\" + userName + @"\" + file.FileName;
string pathString = Path.Combine(folder, userName);
if (!Directory.Exists(pathString))
{
Directory.CreateDirectory(pathString);
}
var filePath = Path.Combine(pathString, file.FileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
_videoLogic.SaveVideo(new Video(userId, video.VideoId, video.Description, file.FileName, DateTime.Now, url, video.CategoryId));
}
}
catch (Exception ex)
{
ViewBag.Message = "ERROR: " + ex.Message.ToString();
}
}
else
{
ViewBag.Message = "You have not specified a file.";
}
return RedirectToAction("UploadVideo");
}
After that you can just get the video from the database and get the url from there!
Thanks for all the help
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论