You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET中录制摄像头视频?求助无法保存录制内容问题

ASP.NET摄像头视频录制与保存解决方案

我来帮你搞定这个摄像头录制后无法保存的问题!其实核心卡点通常在前端视频数据的捕获传输逻辑,或者后端ASP.NET的接收存储代码上,我给你一套完整的可落地方案,分前后端两部分详细说明:


一、前端:捕获摄像头并录制视频(原生JS实现)

这里用浏览器原生的MediaRecorder API实现,不需要第三方插件,兼容性覆盖主流浏览器:

<!DOCTYPE html>
<html>
<head>
    <title>摄像头视频录制</title>
</head>
<body>
    <video id="video" autoplay playsinline width="640" height="480"></video>
    <div style="margin-top:10px;">
        <button id="startBtn">开始录制</button>
        <button id="stopBtn" disabled>停止录制</button>
    </div>

    <script>
        let mediaRecorder;
        let recordedChunks = [];
        const video = document.getElementById('video');
        const startBtn = document.getElementById('startBtn');
        const stopBtn = document.getElementById('stopBtn');

        // 获取摄像头权限并初始化视频流
        async function initCameraStream() {
            try {
                // 请求摄像头+麦克风权限,不需要音频可以去掉audio:true
                const stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
                video.srcObject = stream;
                return stream;
            } catch (err) {
                console.error('摄像头权限获取失败:', err);
                alert('无法访问摄像头,请检查浏览器权限设置');
            }
        }

        // 开始录制逻辑
        startBtn.addEventListener('click', async () => {
            const stream = await initCameraStream();
            if (!stream) return;

            // 配置录制格式,优先用webm(兼容性好),可根据浏览器调整
            const mimeType = MediaRecorder.isTypeSupported('video/webm') ? 'video/webm' : 'video/mp4';
            mediaRecorder = new MediaRecorder(stream, { mimeType });
            
            // 收集录制的视频片段
            mediaRecorder.ondataavailable = (e) => {
                if (e.data.size > 0) recordedChunks.push(e.data);
            };

            // 录制停止后,将片段合并为Blob并发送到后端
            mediaRecorder.onstop = async () => {
                const videoBlob = new Blob(recordedChunks, { type: mimeType });
                await sendVideoToServer(videoBlob);
                // 重置录制状态并关闭摄像头流
                recordedChunks = [];
                stream.getTracks().forEach(track => track.stop());
            };

            mediaRecorder.start();
            startBtn.disabled = true;
            stopBtn.disabled = false;
        });

        // 停止录制逻辑
        stopBtn.addEventListener('click', () => {
            mediaRecorder.stop();
            startBtn.disabled = false;
            stopBtn.disabled = true;
        });

        // 发送视频到ASP.NET后端接口
        async function sendVideoToServer(blob) {
            const formData = new FormData();
            // 生成带时间戳的文件名,避免重复
            const fileName = `recording_${new Date().getTime()}.${blob.type.split('/')[1]}`;
            formData.append('videoFile', blob, fileName);

            try {
                const response = await fetch('/Video/SaveRecording', {
                    method: 'POST',
                    body: formData
                });

                response.ok ? alert('视频保存成功!') : alert('视频保存失败,请检查后端接口');
            } catch (err) {
                console.error('视频上传失败:', err);
                alert('网络错误,无法上传视频');
            }
        }
    </script>
</body>
</html>

二、后端:ASP.NET接收并保存视频

方案1:ASP.NET Core(.NET 6+)

创建一个VideoController,实现接收FormData并保存视频的接口:

using Microsoft.AspNetCore.Mvc;
using System.IO;

namespace YourProjectNamespace.Controllers
{
    public class VideoController : Controller
    {
        // 视频保存目录,建议从appsettings.json读取,这里用示例路径
        private readonly string _saveDir = Path.Combine(Directory.GetCurrentDirectory(), "RecordedVideos");

        public VideoController()
        {
            // 自动创建保存目录(如果不存在)
            if (!Directory.Exists(_saveDir)) Directory.CreateDirectory(_saveDir);
        }

        [HttpPost]
        public async Task<IActionResult> SaveRecording(IFormFile videoFile)
        {
            // 校验上传文件
            if (videoFile == null || videoFile.Length == 0)
                return BadRequest("未接收到有效视频文件");

            try
            {
                // 生成唯一文件名(避免覆盖)
                var uniqueFileName = $"{Guid.NewGuid()}_{Path.GetFileName(videoFile.FileName)}";
                var savePath = Path.Combine(_saveDir, uniqueFileName);

                // 写入文件到服务器
                using var fileStream = new FileStream(savePath, FileMode.Create);
                await videoFile.CopyToAsync(fileStream);

                return Ok(new { Message = "视频保存成功", SavePath = savePath });
            }
            catch (Exception ex)
            {
                return StatusCode(500, $"保存视频出错:{ex.Message}");
            }
        }
    }
}

方案2:传统ASP.NET MVC(.NET Framework)

如果是基于.NET Framework的项目,控制器代码调整如下:

using System.IO;
using System.Web;
using System.Web.Mvc;

namespace YourProjectNamespace.Controllers
{
    public class VideoController : Controller
    {
        private readonly string _saveDir = Path.Combine(HttpContext.Current.Server.MapPath("~/RecordedVideos"));

        public VideoController()
        {
            if (!Directory.Exists(_saveDir)) Directory.CreateDirectory(_saveDir);
        }

        [HttpPost]
        public ActionResult SaveRecording()
        {
            if (Request.Files.Count == 0)
                return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest, "未接收到视频文件");

            var videoFile = Request.Files[0];
            if (videoFile.ContentLength == 0)
                return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest, "视频文件为空");

            try
            {
                var uniqueFileName = $"{Guid.NewGuid()}_{Path.GetFileName(videoFile.FileName)}";
                var savePath = Path.Combine(_saveDir, uniqueFileName);
                videoFile.SaveAs(savePath);

                return Json(new { Message = "视频保存成功", SavePath = savePath });
            }
            catch (Exception ex)
            {
                return new HttpStatusCodeResult(System.Net.HttpStatusCode.InternalServerError, $"保存视频出错:{ex.Message}");
            }
        }
    }
}

三、常见问题排查

  • 前端录制无数据:用MediaRecorder.isTypeSupported('video/webm')检查格式兼容性,不支持的话换成video/mp4尝试。
  • 后端接收不到文件:确保前端FormData的键名(示例中是videoFile)和后端参数名完全一致;如果视频过大,需要调整ASP.NET的请求大小限制:
    • ASP.NET Core:在Program.cs中添加请求大小配置:
      builder.Services.Configure<FormOptions>(options =>
      {
          options.MultipartBodyLengthLimit = 1073741824; // 1GB,按需调整
      });
      
    • 传统ASP.NET MVC:在web.config中添加:
      <system.web>
          <httpRuntime maxRequestLength="1048576" /> <!-- 1GB -->
      </system.web>
      <system.webServer>
          <security>
              <requestFiltering>
                  <requestLimits maxAllowedContentLength="1073741824" /> <!-- 1GB -->
              </requestFiltering>
          </security>
      </system.webServer>
      
  • 视频文件损坏:必须在MediaRecorder的onstop事件触发后再生成Blob,确保录制数据完全收集。

内容的提问来源于stack exchange,提问作者Washim Akram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:11:20