ASP.NET Mvc+FFmpeg+Video实现视频转码

目录

首先,做了视频上传的页面:

FFmpeg:视频转码

FFmpegHelper工作类:

后台控制器代码:

前端视图代码:

参考文章:


首先,做了视频上传的页面:

借鉴了这篇文章

ASP.NET MVC+LayUI视频上传 - 追逐时光者 - 博客园 (cnblogs.com)

其中的(maxRequestLength和maxAllowedContentLength)设置我是这样设置的

cs 复制代码
<system.web>
  <compilation debug="true" targetFramework="4.6.2" />
  <httpRuntime targetFramework="4.6.2" maxRequestLength="2147483647" executionTimeout="600" />
</system.web>
	<system.webServer>
<security>
	<requestFiltering>
		<requestLimits maxAllowedContentLength="2147483647"/>
	</requestFiltering>
</security>
	</system.webServer>

layUI相关的报引用的是最新版的:发现最新版的只需要引用layui不需要layer

2.后续发现Video标签只支持以下几种格式就涉及到视频转码了:

格式 IE Firefox Opera Chrome Safari
Ogg No 3.5+ 10.5+ 5.0+ No
MPEG 4 9.0+ No No 5.0+ 3.0+
WebM No 4.0+ 10.6+ 6.0+ No

FFmpeg:视频转码

第一步首先在网上下载ffmpeg.exe程序,并保存到工程目录中

ffmpeg安装教程(windows版)_ffmpeg windows安装-CSDN博客

FFmpegHelper工作类:

cs 复制代码
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;

namespace Player.Helper
{
    public class FFmpegHelper
    {
        //安装的ffmpeg的路径 写在配置文件的 你也可以直接写你的路径 D:\ffmpeg\bin\ffmpeg.exe
        //static string FFmpegPath = System.Configuration.ConfigurationManager.AppSettings["ffmepg"];

        /// <summary>
        /// 视频转码为mp4文件
        /// </summary>
        /// <param name="videoUrl"></param>
        /// <param name="targetUrl"></param>
        public static void VideoToTs(string videoUrl, string targetUrl)
        {
            //视频转码指令
            string cmd = string.Format("ffmpeg  -i \"{0}\" -y -ab 32 -ar 22050 -b 800000 -s 480*360 \"{1}\"", videoUrl, targetUrl);
            RunMyProcess(cmd);
        }

        /// <summary>
        /// 执行cmd指令
        /// </summary>
        /// <param name="Parameters"></param>
        public static void RunMyProcess(string Parameters)
        {
            using (Process p = new Process())
            {
                try
                {
                    p.StartInfo.FileName = "cmd.exe";
                    p.StartInfo.UseShellExecute = false;//是否使用操作系统shell启动
                    p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
                    p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
                    p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
                    p.StartInfo.CreateNoWindow = false;//不创建进程窗口                                                
                    p.Start();//启动线程
                    p.StandardInput.WriteLine(Parameters + "&&exit"); //向cmd窗口发送输入信息
                    p.StandardInput.AutoFlush = true;
                    p.StandardInput.Close();
                    //获取cmd窗口的输出信息
                    string output = p.StandardError.ReadToEnd(); //可以输出output查看具体报错原因

                    p.WaitForExit();//等待完成
                    p.Close();//关闭进程
                    p.Dispose();//释放资源

                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
    }
}

后台控制器代码:

cs 复制代码
using Player.Helper;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using static System.Net.WebRequestMethods;

namespace Player.Controllers
{
    public class FileUploadController : Controller
    {
        // GET: FileUpload
        public ActionResult Index()
        {
            return View();
        }
        /// <summary>
        /// 对验证和处理 HTML 窗体中的输入数据所需的信息进行封装,如FromData拼接而成的文件[图片,视频,文档等文件上传]
        /// </summary>
        /// <param name="context">FemContext对验证和处理html窗体中输入的数据进行封装</param>
        /// <returns></returns>
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult FileLoad(FormContext context)//FemContext对验证和处理html窗体中输入的数据进行封装
        {

            HttpPostedFileBase httpPostedFileBase = Request.Files[0];//获取文件流
            if (httpPostedFileBase != null)
            {
                try
                {
                    ControllerContext.HttpContext.Request.ContentEncoding = Encoding.GetEncoding("UTF-8");
                    ControllerContext.HttpContext.Response.Charset = "UTF-8";

                    string fileName = Path.GetFileName(httpPostedFileBase.FileName);//原始文件名称
                    string fileExtension = Path.GetExtension(fileName);//文件扩展名

                    byte[] fileData = ReadFileBytes(httpPostedFileBase);//文件流转化为二进制字节

                    string result = SaveFile(fileExtension, fileData);//文件保存
                                                                      
                    

                    return string.IsNullOrEmpty(result) ? Json(new { code = 0, path = "", msg = "网络异常,文件上传失败.~" }) : Json(new { code = 1, path = result, msg = "文件上传成功" });
                }
                catch (Exception ex)
                {
                    return Json(new { code = 0, msg = ex.Message, path = "" });
                }
            }
            else
            {
                return Json(new { code = 0, path = "", msg = "网络异常,文件上传失败!~" });
            }
        }


        /// <summary>
        /// 将文件流转化为二进制字节
        /// </summary>
        /// <param name="fileData">图片文件流</param>
        /// <returns></returns>
        private byte[] ReadFileBytes(HttpPostedFileBase fileData)
        {
            byte[] data;
            using (var inputStream = fileData.InputStream)
            {
                if (!(inputStream is MemoryStream memoryStream))
                {
                    memoryStream = new MemoryStream();
                    inputStream.CopyTo(memoryStream);
                }
                data = memoryStream.ToArray();
            }
            return data;
        }

        /// <summary>
        /// 保存文件
        /// </summary>
        /// <param name="fileExtension">文件扩展名</param>
        /// <param name="fileData">图片二进制文件信息</param>
        /// <returns></returns>
        private string SaveFile(string fileExtension, byte[] fileData)
        {
            string result;
            string saveName = Guid.NewGuid().ToString() + fileExtension; //保存文件名称
            string basePath = "UploadFile";
            string saveDir = DateTime.Now.ToString("yyyy-MM-dd");

            // 文件上传后的保存路径
            string serverDir = Path.Combine(Server.MapPath("~/"), basePath, saveDir);

            string fileNme = Path.Combine(serverDir, saveName);//保存文件完整路径
            try
            {
                var savePath = Path.Combine(saveDir, saveName);

                //项目中是否存在文件夹,不存在创建
                if (!Directory.Exists(serverDir))
                {
                    Directory.CreateDirectory(serverDir);
                }

                System.IO.File.WriteAllBytes(fileNme, fileData);//WriteAllBytes创建一个新的文件,按照对应的文件流写入,假如已存在则覆盖

                //返回前端项目文件地址
                result = "/" + basePath + "/" + saveDir + "/" + saveName;
                //进行视频转换
                var mp4Name = Guid.NewGuid().ToString() + ".mp4";
                string tsUrl = Path.Combine(serverDir, mp4Name);
                FFmpegHelper.VideoToTs(fileNme, tsUrl);
                //检测是否已生成ts文件
                if (!System.IO.File.Exists(tsUrl))
                {
                    //删除源文件
                    System.IO.File.Delete(fileNme);

                    return null;
                }

                //删除MP4源文件
                System.IO.File.Delete(fileNme);

                result = "/" + basePath + "/" + saveDir + "/" + mp4Name;
            }
            catch (Exception ex)
            {
                result = "发生错误" + ex.Message;
            }
            return result;
        }

    }

}

前端视图代码:

cs 复制代码
<!DOCTYPE html>

<head>
    <meta charset="utf-8" />
    <!--最高级模式渲染文档-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title></title>
    <link href="~/Content/Layui/css/layui.css" rel="stylesheet" />
</head>
<body>

    <div class="jumbotron" style="margin-top: 200px;">
        <div class="row" style="margin-top: 20px;">
            <div class="form-group znStyle">
                <div class="col-sm-6">
                    <div id="upload_all_file">
                        <div class="layui-upload">
                            <button type="button" class="layui-btn" id="VideoBtn"><i class="layui-icon">&#xe67c;</i>上传视频</button>
                            <input type="hidden" name="Video" id="Video" />
                            <div class="layui-upload-list" id="videoPlay">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="~/Content/Layui/layui.js"></script>
    <!--layer.js视频上传-->
    <script type="text/javascript">
    var upload;
    //上传图片
    layui.use('upload', function () {
        upload = layui.upload;

        upload.render({
            before: function () {
                layer.msg('视频努力上传中,请耐心等待...', { icon: 16, shade: 0.8, time: false });
            },
            elem: '#VideoBtn'
            , url: '@Url.Action("FileLoad","FileUpload")'
            , accept: 'video' //视频
            , exts: 'mp4|mov|wmv|flv|avi|avchd|webm|mkv|m4v'//只允许上传的后缀(mp4文件)
            , done: function (res) {
                console.log(res);
                layer.closeAll();
                layer.msg(res.msg);
                if (res.code == 1) {
                    $("#Video").val(res.path);
                    $("#videoPlay").html('<video controls="controls" id="currentVideo" style="width:400px;"><source src="' + res.path + '" type="video/mp4" /><source src="' + res.path + '" type="video/webm" /><source src="' + res.path + '" type="audio/ogg" /></video>');
                    $("#videoPlay").show();
                    // 自动播放
                    $("#currentVideo")[0].play();
                }
            }
        });


        $(".layui-upload-list").on("click", "i", function () {
            $(this).parent().remove();
        });
    });
    </script>
</body>

参考文章:

Request Limits <requestLimits> | Microsoft Learn

httpRuntime代码放在web.config哪里?深度了解httpRuntime - ASP.NET编程_卡卡网

相关推荐
向前看-7 小时前
验证码机制
前端·后端
超爱吃士力架8 小时前
邀请逻辑
java·linux·后端
李小白669 小时前
Spring MVC(上)
java·spring·mvc
AskHarries10 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
isolusion11 小时前
Springboot的创建方式
java·spring boot·后端
zjw_rp12 小时前
Spring-AOP
java·后端·spring·spring-aop
TodoCoder12 小时前
【编程思想】CopyOnWrite是如何解决高并发场景中的读写瓶颈?
java·后端·面试
凌虚13 小时前
Kubernetes APF(API 优先级和公平调度)简介
后端·程序员·kubernetes
机器之心14 小时前
图学习新突破:一个统一框架连接空域和频域
人工智能·后端
.生产的驴14 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven