本文介绍如何使用 WebRTC 从 ASP.NET Core 3.1 MVC 应用程序使用网络摄像头捕获视频。
WebRTC(Web 实时通信)是一个免费的开源项目,它使 Web 应用程序和站点能够捕获和可选地流式传输音频和/或视频媒体,以及在浏览器之间交换任意数据而无需中介。WebRTC 背后的技术作为开放网络标准实施,并在所有主要浏览器中作为常规 JavaScript API 提供。
让我们按照下面提到的步骤从一个简单的 ASP.NET Core 3.1 MVC 应用程序中捕获视频。
步骤1
创建 ASP.NET Core 3.1 MVC Web 应用程序。
第2步
现在转到Solution Explorer添加一个新控制器,右键单击Controllers > Add > Controller,然后像这样给出一个合适的名称。
以下是VideoController.cs 的代码片段。
public class VideoController : Controller
{
[HttpGet]
public IActionResult Index()
{
return View();
}
[HttpPost]
public async Task<IActionResult> SaveRecoredFile()
{
if( Request.Form.Files.Any())
{
var file = Request.Form.Files["video-blob"];
string UploadFolder = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "UploadedFiles");
string UniqueFileName = Guid.NewGuid().ToString() + "_" + file.FileName+ ".webm";
string UploadPath = Path.Combine(UploadFolder, UniqueFileName);
await file.CopyToAsync(new FileStream(UploadPath, FileMode.Create));
}
return Json(HttpStatusCode.OK);
}
}
请注意, SaveRecoredFile () 操作方法将用于将录制的视频存储到文件夹中并处理发布请求。
现在打开VideoController.cs > 在Index Action Method内设置光标并在Index action 方法内右键单击> 单击Add View ,确保选中 Use a Layout page 选项。
添加视图后,让我们添加一些 HTML 代码和脚本。以下是Index.cshtml视图的代码片段。
@{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="container">
<h1>
<a href="//webrtc.github.io/samples/" title="WebRTC samples homepage">ASP.NET Core 3.1 samples</a>
<span>Audio/Video Recording</span>
</h1>
<p>
For more information see the MediaStream Recording API <a href="http://w3c.github.io/mediacapture-record/MediaRecorder.html"
title="W3C MediaStream Recording API Editor's Draft">Editor's Draft</a>.
</p>
<video id="gum" playsinline autoplay muted style="border: 1px solid rgb(15, 158, 238); height: 240px; width: 320px;"></video>
<video id="recorded" playsinline loop style="border: 1px solid rgb(15, 158, 238); height: 240px; width: 320px;"></video>
<div>
<button id="start" class="btn btn-success">Start camera</button>
<button id="record" disabled class="btn btn-info">Start Recording</button>
<button id="play" disabled class="btn btn-warning">Play</button>
<button id="download" disabled class="btn btn-dark">Download</button>
<button id="stop" class="btn btn-danger">Stop camera</button>
</div>
<div> Recording format: <select id="codecPreferences" disabled></select> </div>
<div>
<h4>Media Stream Constraints options</h4>
<p>Echo cancellation: <input type="checkbox" id="echoCancellation"></p>
</div>
<div><span id="errorMsg"></span></div>
</div>
步骤 3
现在创建一个将存储捕获的视频文件的文件夹,并将下面的 Video.css 和 Video.js 文件也添加到wwwroot 文件夹下的css和 j s文件夹中。
以下是Video.css的代码片段
p.borderBelow {
margin: 0 0 20px 0;
padding: 0 0 20px 0;
}
video {
vertical-align: top;
--width: 25vw;
width: var(--width);
height: calc(var(--width) * 0.5625);
}
video:last-of-type {
margin: 0 0 20px 0;
}
video#gumVideo {
margin: 0 20px 20px 0;
}
这是 Video.js 的代码片段。此脚本用于捕获视频并将其存储在文件夹中。
'use strict';
/* globals MediaRecorder */
let mediaRecorder;
let recordedBlobs;
const codecPreferences = document.querySelector('#codecPreferences');
const errorMsgElement = document.querySelector('span#errorMsg');
const recordedVideo = document.querySelector('video#recorded');
const recordButton = document.querySelector('button#record');
recordButton.addEventListener('click', () => {
if (recordButton.textContent === 'Start Recording') {
startRecording();
} else {
stopRecording();
recordButton.textContent = 'Start Recording';
playButton.disabled = false;
downloadButton.disabled = false;
codecPreferences.disabled = false;
}
});
const playButton = document.querySelector('button#play');
playButton.addEventListener('click', () => {
const mimeType = codecPreferences.options[codecPreferences.selectedIndex].value.split(';', 1)[0];
const superBuffer = new Blob(recordedBlobs, { type: mimeType });
recordedVideo.src = null;
recordedVideo.srcObject = null;
recordedVideo.src = window.URL.createObjectURL(superBuffer);
recordedVideo.controls = true;
recordedVideo.play();
});
const downloadButton = document.querySelector('button#download');
downloadButton.addEventListener('click', () => {
const blob = new Blob(recordedBlobs, { type: 'video/webm' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = 'test.webm';
document.body.appendChild(a);
a.click();
PostBlob(blob);
setTimeout(() => {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 100);
});
function handleDataAvailable(event) {
console.log('handleDataAvailable', event);
if (event.data && event.data.size > 0) {
recordedBlobs.push(event.data);
}
}
function getSupportedMimeTypes() {
const possibleTypes = [
'video/webm;codecs=vp9,opus',
'video/webm;codecs=vp8,opus',
'video/webm;codecs=h264,opus',
'video/mp4;codecs=h264,aac',
];
return possibleTypes.filter(mimeType => {
return MediaRecorder.isTypeSupported(mimeType);
});
}
function startRecording() {
recordedBlobs = [];
const mimeType = codecPreferences.options[codecPreferences.selectedIndex].value;
const options = { mimeType };
try {
mediaRecorder = new MediaRecorder(window.stream, options);
} catch (e) {
console.error('Exception while creating MediaRecorder:', e);
errorMsgElement.innerHTML = `Exception while creating MediaRecorder: ${JSON.stringify(e)}`;
return;
}
console.log('Created MediaRecorder', mediaRecorder, 'with options', options);
recordButton.textContent = 'Stop Recording';
playButton.disabled = true;
downloadButton.disabled = true;
codecPreferences.disabled = true;
mediaRecorder.onstop = (event) => {
console.log('Recorder stopped: ', event);
console.log('Recorded Blobs: ', recordedBlobs);
};
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();
console.log('MediaRecorder started', mediaRecorder);
}
function stopRecording() {
mediaRecorder.stop();
}
function handleSuccess(stream) {
recordButton.disabled = false;
console.log('getUserMedia() got stream:', stream);
window.stream = stream;
const gumVideo = document.querySelector('video#gum');
gumVideo.srcObject = stream;
getSupportedMimeTypes().forEach(mimeType => {
const option = document.createElement('option');
option.value = mimeType;
option.innerText = option.value;
codecPreferences.appendChild(option);
});
codecPreferences.disabled = false;
}
function PostBlob(blob) {
//FormData
var formData = new FormData();
formData.append('video-blob', blob);
// POST the Blob
$.ajax({
type: 'POST',
url: "Video/SaveRecoredFile",
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (result) {
if (result) {
console.log('Success');
}
},
error: function (result) {
console.log(result);
}
})
}
async function init(constraints) {
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
handleSuccess(stream);
} catch (e) {
console.error('navigator.getUserMedia error:', e);
errorMsgElement.innerHTML = `navigator.getUserMedia error:${e.toString()}`;
}
}
document.querySelector('button#start').addEventListener('click', async () => {
document.querySelector('button#start').disabled = true;
document.querySelector('button#stop').disabled = false;
const hasEchoCancellation = document.querySelector('#echoCancellation').checked;
const constraints = {
audio: {
echoCancellation: { exact: hasEchoCancellation }
},
video: {
width: 1280, height: 720
}
};
console.log('Using media constraints:', constraints);
await init(constraints);
});
document.querySelector('button#stop').addEventListener('click',async () => {
document.querySelector('button#stop').disabled = true;
document.querySelector('button#start').disabled = false;
const video = document.querySelector('video#gum');
const mediaStream = video.srcObject;
await mediaStream.getTracks().forEach(track => track.stop());
video.srcObject = null;
});
步骤4
现在在 _Layout.cshtml 中添加以下行。
<link rel="stylesheet" href="~/css/Video.css" />
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="~/js/Video.js" asp-append-version="true" async></script>
以下是_Layout.cshtml 的完整代码片段。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - Sample_Code</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/css/Video.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">Sample_Code</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2021 - Sample_Code - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
<script src="~/js/Video.js" asp-append-version="true" async></script>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true" ></script>
@RenderSection("Scripts", required: false)
</body>
</html>
现在让我们构建并运行应用程序以查看输出。单击 “开始摄像头” 按钮并使用网络摄像头录制视频。
现在单击 下载按钮将 捕获的视频保存到 我们之前创建的wwwroot文件夹下的 UploadedFiles文件夹中。
概括
在这里,我们了解了如何逐步从简单的 ASP.NET Core 3.1 MVC 应用程序捕获视频。希望您喜欢这篇文章并从中获取一些信息。
参考
- https://webrtc.github.io/samples/
- 完整代码:https://github.com/ArnabMSDN/ASP.NET-Core-Sample
版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。