html和winform webBrowser控件交互并播放视频(包含转码)

news2025/1/11 14:52:33

1、 为了使网页能够与winform交互 将com的可访问性设置为真
   

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    [System.Runtime.InteropServices.ComVisibleAttribute(true)]

2、在webBrowser控件中设置可被html页面调用的类即:webBrowser1.ObjectForScripting = this;前端即可通过window.external访问this对象

3、html页面调用后台方法:window.external.方法名(); 此处的window.external相当于webBrowser1.ObjectForScripting

设计:

 后台代码:

注意:视频地址需要修改

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using WebKit;
using System.IO;
using DXApplication1.Helper;

namespace DXApplication1
{
    //为了使网页能够与winform交互 将com的可访问性设置为真
    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    public partial class webBrowser : DevExpress.XtraEditors.XtraForm
    {
        public webBrowser()
        {
            InitializeComponent();
           
        }

        private void webBrowser_Load(object sender, EventArgs e)
        {
            webBrowser1.ScriptErrorsSuppressed = true;//消除脚本错误 
            webBrowser1.Navigate(@"C:\source\repos\DXApplication1\DXApplication1\Html\HTMLPage2.html");
            webBrowser1.ObjectForScripting = this;
            
        }
        
        public string FileLode(string url)
        {
            //返回路径
            string result = url;
            if (!string.IsNullOrEmpty(url))
            {
                //保存文件名称
                string saveName = Guid.NewGuid().ToString() + ".mp4"; 
                string basePath = "UploadFile";
                string saveDir = DateTime.Now.ToString("yyyy-MM-dd");
                //获取应用程序的当前工作目录
                string MapPath = Directory.GetCurrentDirectory();
                // 文件上传后的保存路径
                string serverDir = Path.Combine(MapPath, basePath, saveDir);
                //保存文件完整路径
                string fileNme = Path.Combine(serverDir, saveName);
                //项目中是否存在文件夹,不存在创建                                                                                        
                if (!Directory.Exists(serverDir)) 
                {
                    Directory.CreateDirectory(serverDir);
                }
                //进行视频转换
                FFmpegHelper.VideoToTs( url, fileNme);
                result = fileNme;
            }
            
            return result;
        }

        /// <summary>
        /// 前台调用后台返回数据
        /// 注意:前台调用的方法不能:static
        /// </summary>
        /// <param name="a"></param>
        /// <returns></returns>
        public string videoLine(int  a)
        {
            var result = string.Empty;
            switch (a)
            {
                case 1:
                    result = "http:/UploadFile/2024-03-12/17577f56-d999-4bbe-b67a-2156e241170d.mp4";
                    break;
                case 2:
                    result = "http:/UploadFile/2024-03-12/af67f8d3-ac79-4bd1-aa41-0743015ef9a4.m4v";
                    break;
                default:
                    result= "C:\\source\\repos\\DXApplication1\\DXApplication1\\video\\231127.m4v";
                    break;
            }
            return result;


        }

        private void simpleButton1_Click(object sender, EventArgs e)
        {
            var url=textBox1.Text;
            if (!string.IsNullOrEmpty(url))
            {
                webBrowser1.ScriptErrorsSuppressed = true;
                webBrowser1.Navigate(url);
                webBrowser1.ObjectForScripting = this;
            }
            

        }
        private void simpleButton2_Click(object sender, EventArgs e)
        {
            //调用前台js方法
            webBrowser1.Document.InvokeScript("handinitLine", new object[] { "后台调用js方法1" });
        }
    }
}

Html代码:

<!DOCTYPE html>

<head>
    <meta charset="utf-8" />
    <!--最高级模式渲染文档-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title></title>
    <link href="layui-v2.9.7/css/layui.css" rel="stylesheet" />
</head>
<body>
    <!--<div id="player">-->
    <!--播放本地视频-->
    <!--<video controls width="500" height="300" src="../video/1699408632422.m4v"></video>-->
    <!--播放网络视频-->
    <!--<video controls width="500" height="300" src="http:/UploadFile/2024-03-12/b7962018-26b3-43c1-83ad-aa2c14149f58.m4v"></video>-->
    <!--</div>-->

    <div>
        <input type="file" class="layui-btn layui-btn-primary" id="videoUpload" accept="video/*">
    </div>

    <div class="layui-form-item">
        <div class="layui-input-group">
            <div class="layui-input-split layui-input-prefix">
                
            </div>
            <input type="text" placeholder="" class="layui-input" id="textvideo">
            <div class="layui-input-suffix">
                <button class="layui-btn layui-btn-primary" id="videoLine" value="前台调用后台方法" onclick="vide()">前台调用后台方法</button>
            </div>
        </div>
    </div>



    <script src="layui-v2.9.7/layui.js"></script>
    <script>
        document.getElementById('videoUpload').addEventListener('change', handleVideoUpload, false);

        function handleVideoUpload(event) {
           
            var url = document.getElementById('videoUpload').value;//获取file选择文件物理路径方法
            url = window.external.FileLode(url)
            //var file = event.target.files[0]; // 获取用户选择的文件
            //var videoURL = URL.createObjectURL(file); // 创建一个指向视频文件的 URL
            document.getElementById('videoUpload').value = url;
            //判断是否存在video标签
            if (document.getElementById('videofile')) {
                var element = document.getElementById("videofile");
                element.parentNode.removeChild(element);
            }
            // 创建一个 video 元素,用于播放视频
            var video = document.createElement('video');
            video.src = url;//videoURL; // 设置 video 元素的 src 属性为视频文件的 URL
            video.controls = true; // 显示视频控制器,如播放/暂停按钮等
            video.width = "500";
            video.height = "300";
            video.id = "videofile";
            video.play(); // 自动播放视频
            // 将 video 元素添加到页面中
            document.body.appendChild(video);
           
        }
        function handinitLine(text) {
            alert(text);
        }
        function vide() {
            var a = document.getElementById('textvideo').value;
            var url = window.external.videoLine(a);
            //判断是否存在video标签
            if (document.getElementById('videofile')) {
                var element = document.getElementById("videofile");
                element.parentNode.removeChild(element);
            }
            // 创建一个 video 元素,用于播放视频
            var video = document.createElement('video');
            video.src = url; // 设置 video 元素的 src 属性为视频文件的 URL
            video.controls = true; // 显示视频控制器,如播放/暂停按钮等
            video.width = "500";
            video.height = "300";
            video.id = "videofile";
            video.play(); // 自动播放视频
            // 将 video 元素添加到页面中
            document.body.appendChild(video);

        }
        function strbol(str) {
            if (str.indexOf('http') == 0) {
                //开头包含http
                return false;
            }
            return true;
        }
    </script>
</body>

FFmpegHelper类:视频转码类

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DXApplication1.Helper
{
    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>
        /// 将ts文件转换为mu3u8文件
        /// </summary>
        /// <param name="tsUrl"></param>
        /// <param name="m3u8Url">这个路径不要带扩展名</param>
        /// <param name="videoLength">视频切片时长,默认5秒</param>
        public static void TsToM3u8(string tsUrl, string m3u8Url, int videoLength = 5)
        {
            //这里是关键点,一般平时切视频都是用FFmpeg -i  地址 -c这样,但是在服务器时,这样调用可能找不到ffmpeg的路径 所以这里直接用ffmpeg.exe来执行命令
            //string cmd = $@"{FFmpegPath} -i {tsUrl} -c copy -map 0 -f segment -segment_list {m3u8Url}.m3u8 -segment_time 5 {m3u8Url}%03d.ts";
            string cmd = string.Format("ffmpeg -i \"{0}\" -c copy -map 0 -f segment -segment_list \"{1}.mp4\" -segment_time {2} \"{1}%03d.ts\"", tsUrl, m3u8Url, videoLength);
            RunMyProcess(cmd);
        }

        /// <summary>
        /// 生成MP4频的缩略图
        /// </summary>
        /// <param name="videoUrl">视频文件地址</param>
        /// <param name="imgUrl">视频缩略图地址</param>
        /// <param name="imgSize">宽和高参数,如:240*180</param>
        /// <param name="Second">ss后跟的时间单位为秒</param>
        /// <returns></returns>
        public static string CatchImg(string videoUrl, string imgUrl, int Second = 8, string imgSize = "1280x720")
        {
            try
            {
                //转换文件格式的同时抓缩微图: 
                //ffmpeg - i "test.avi" - y - f image2 - ss 8 - t 0.001 - s 350x240 'test.jpg'
                //- ss后跟的时间单位为秒

                string cmd = string.Format("ffmpeg -i \"{0}\" -y -f image2 -ss {1} -t 0.001 -s {2} \"{3}\"", videoUrl, Second, imgSize, imgUrl);
                RunMyProcess(cmd);

                //注意:图片截取成功后,数据由内存缓存写到磁盘需要时间较长,大概在3,4秒甚至更长;
                //System.Threading.Thread.Sleep(500);
                if (System.IO.File.Exists(imgUrl))
                {
                    return imgUrl;
                }
                return "";
            }
            catch
            {
                return "";
            }
        }

        /// <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;
                }
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1520140.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MS08-067 漏洞利用与安全加固

文章目录 环境说明1 MS08_067 简介2 MS08_067 复现过程3 MS08_067 安全加固 环境说明 渗透机操作系统&#xff1a;2024.1漏洞复现操作系统: Windows XP Professional with Service Pack 2- VL (English)安全加固复现操作系统&#xff1a;Windows XP Professional with Service …

一文让您读懂实时数仓(Apache Doris)

引言&#xff1a; 随着大数据时代的来临&#xff0c;实时数据处理与分析成为企业核心竞争力的关键因素之一。在这场数据革命中&#xff0c;SelectDB成为引领者。从百度自研的实时数仓平台 Palo&#xff0c;到开源项目 Apache Doris&#xff0c;再到飞轮科技研发的 SelectDB&am…

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:ListItem)

用来展示列表具体item&#xff0c;必须配合List来使用。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。该组件的父组件只能是List或者ListItemGroup。 子组件 可以包含单个子组件。 接口 从API…

19113133262(微信同号)【征稿进行时|见刊、检索快速稳定】2024年区块链、物联网与复合材料与国际学术会议 (ICBITC 2024)

【征稿进行时|见刊、检索快速稳定】2024年区块链、物联网与复合材料与国际学术会议 (ICBITC 2024) 大会主题: (主题包括但不限于, 更多主题请咨询会务组苏老师) 区块链&#xff1a; 区块链技术和系统 分布式一致性算法和协议 块链性能 信息储存系统 区块链可扩展性 区块…

[云原生] Prometheus之部署 Alertmanager 发送告警

一、Alertmanager 发送告警的介绍 Prometheus 对指标的收集、存储与告警能力分属于 Prometheus Server 和 AlertManager 两个独立的组件&#xff0c;前者仅负责定义告警规则生成告警通知&#xff0c; 具体的告警操作则由后者完成。 Alertmanager 负责处理由 Prometheus Serve…

SQLiteC/C++接口详细介绍之sqlite3类(九)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;八&#xff09; 下一篇&#xff1a;​​SQLiteC/C接口详细介绍之sqlite3类&#xff08;十&#xff09;&#xff08;未发表&#xff09;​​​​ 27…

机器学习概念(一)

机器学习 是一门使计算机在没有明确编程的情况下具备学习能力的研究领域。 监督学习&#xff08;Supervised learning&#xff09; 监督学习算法 通过学习输入&#xff08;x&#xff09;到输出&#xff08;y&#xff09;的映射关系。在监督学习中&#xff0c;你需要为算法提…

AI日报:欧盟人工智能法案通过后行业面临合规障碍

文章目录 人工智能新规对web爬网的影响对英国的影响。 人工智能新规 立法者已经通过了欧盟人工智能法案。企业现在必须确保其人工智能应用程序符合规则。 全面的新规定对可能影响公民权利的人工智能系统实施制裁&#xff0c;并有可能彻底禁止某些系统。 违反规定的公司可能面…

stable diffusion上安装数字人sadtalker插件

数字人无论是在营销还是品牌推广的作用都非常重要&#xff0c;很多企业和个人都正在使用数字为自己创作财富&#xff0c;市面上的数字人生成网站包括某讯智影、D-ID或者是Heygen收费都比较昂贵。 那么如何才能拥有一个免费的数字人生成工具呢&#xff1f;其实很简单你只需要在…

基于LBP和KNN的人面表情识别,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

Unity类银河恶魔城学习记录10-10 p98 UI health bar源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili HealthBar_UI.cs using System.Collections; using System.Collections.G…

AJAX学习(四)

版权声明 本文章来源于B站上的某马课程&#xff0c;由本人整理&#xff0c;仅供学习交流使用。如涉及侵权问题&#xff0c;请立即与本人联系&#xff0c;本人将积极配合删除相关内容。感谢理解和支持&#xff0c;本人致力于维护原创作品的权益&#xff0c;共同营造一个尊重知识…

NodeJs利用腾讯云实现手机发送验证码

本文介绍如何在nodejs实现短信发送&#xff0c;以腾讯云的短信验证为例。 腾讯云中准备工作 首先需要腾讯云的个人或者企业认证的账号&#xff0c;个人会赠送一百条&#xff0c;企业赠送一千条&#xff0c;可以用于测试&#xff0c;地址&#xff1a;腾讯云短信服务。然后需要…

k8s helm 删除 tiller

kuberneter 上面装了 helm 想卸载还并不是那么简单, 参考 stackoverflow 回复 kubectl get -n kube-system secrets,sa,clusterrolebinding -o name|grep tiller|xargs kubectl -n kube-system delete kubectl get all -n kube-system -l apphelm -o name|xargs kubectl dele…

前端实例:页面布局1(后端数据实现)

效果图 注&#xff1a;这里用到后端语言php&#xff08;页面是.php文件&#xff09;,提取纯html也可以用 inemployee_index.php <?php include(includes/session.inc); $Title _(内部员工首页); $ViewTopic 内部员工首页; $BookMark 内部员工首页; include(includes/…

FFmepg--音频编码流程--pcm编码为aac

文章目录 基本概念流程apicode(核心部分) 基本概念 从本地⽂件读取PCM数据进⾏AAC格式编码&#xff0c;然后将编码后的AAC数据存储到本地⽂件。 PCM样本格式&#xff1a;未经压缩的⾳频采样数据裸流 参数&#xff1a; Sample Rate : 采样频率Sample Size : 量化位数Number o…

14 stack和queue的使用

stack的介绍 stack文档 1.stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入和提取操作 2.stack是作为容器适配器被实现的&#xff0c;容器适配器是对特定类封装作为其底层的容器&#xff0c;并提供…

C/C++ Socket 获取或设置 TCP MSS 大小

通过 Socket 系统接口&#xff0c;链接到一个TCP服务器&#xff0c;那么在链接成功之后会被配置一个从本地端到目的端最佳的TCP_MSS大小。 我们通过这个特点&#xff0c;即可轻松的实现&#xff0c;链路MTU大小发现功能&#xff0c;在不依赖ROOT管理员权限的情况下&#xff0c;…

Unity AI Navigation插件快速使用方法

AI Navigation插件使您能够创建能够在游戏世界中智能移动的角色。这些角色利用的是根据场景几何结构自动生成的导航网格。障碍物可以让您在运行时改变角色的导航路径。 演示使用的Unity版本为Tuanjie 1.0.0,团结引擎是Unity中国的引擎研发团队基于Unity 2022 LTS版本为中国开发…

第五十九回 公孙胜芒砀山降魔 晁天王曾头市中箭-飞桨自然语言处理套件PaddleNLP初探

公孙胜献出八卦阵&#xff0c;宋江用八员大将守阵。项充李衮进入阵里&#xff0c;被抓住了。宋江说久闻大名&#xff0c;来梁山吧。两人说誓当效力到死&#xff0c;希望能先放我们两个回去把樊瑞带来一起。见到樊瑞后把宋江讲义气一说&#xff0c;樊瑞说不可逆天&#xff0c;于…