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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自动驾驶泊车(APA_HAVP)算法学习整理

自动驾驶泊车(APA/HAVP)算法学习整理 附赠宝贵的全套自动驾驶学习资料&#xff1a;链接

基于GA优化的CNN-GRU-Attention的时间序列回归预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1卷积神经网络&#xff08;CNN&#xff09;在时间序列中的应用 4.2 长短时记忆网络&#xff08;LSTM&#xff09;处理序列依赖关系 4.3 注意力机制&#xff08;Attention&#xff09; 4…

腾讯春招后端一面(算法篇)

前言&#xff1a; 哈喽大家好&#xff0c;前段时间在小红书和牛客上发了面试的经验贴&#xff0c;很多同学留言问算法的具体解法&#xff0c;今天就详细写个帖子回复大家。 因为csdn是写的比较详细&#xff0c;所以更新比较慢&#xff0c;大家见谅~~ 就题目而言&#xff0c;…

中科数安 | 企业办公透明加密系统,终端文件数据 \ 资料防泄密管理软件

#公司办公文件数据 \ 资料防泄密软件系统# "中科数安"是一家专注于数据安全领域的公司&#xff0c;其提供的企业办公加密系统是一种针对企事业单位内部数据安全需求而设计的解决方案。该系统通过先进的加密技术&#xff0c;对企业在日常办公过程中产生的各类敏感信息…

【自动驾驶可视化工具】

自动驾驶可视化工具 自动驾驶可视化工具1.百度Apollo的Dreamview:2.Cruise的Worldview:3.Uber的AVS:4.Fglovex Studio: 自动驾驶可视化工具 介绍一下当前主流的自动驾驶可视化工具。 1.百度Apollo的Dreamview: Dreamview是百度Apollo平台开发的一种可视化工具&#xff0c;用…

计算机网络(6)-----传输层

目录 一.传输层 二.UDP协议 1.UDP的特点&#xff1a; 2.UDP的首部格式&#xff1a; 3.UDP校验的过程&#xff1a; 三.TCP协议 1.TCP协议的特点 2.TCP报文段首部格式 3.TCP的连接管理 &#xff08;1&#xff09;连接建立&#xff08;三次握手&#xff09; &#xff0…

uniapp无感登录封装

全局请求封装 https://blog.csdn.net/qq_42618566/article/details/109308690 无感登录封装 import {http} from "./index.js" let requestsQueue []; // 请求队列// 记录请求队列 export function recordRequests(path, params, loading, method) {requestsQueu…

开箱即用之 windows部署jdk、设置nginx、jar自启

jdk安装 官网下载对应的安装包&#xff0c;解压之后放在本地指定的文件夹下 传送门https://www.oracle.com/java/technologies/downloads/#jdk21-windows 我比较喜欢下载zip方式的&#xff0c;解压之后直接能用&#xff0c;不需要安装了 配置环境 JAVA_HOME 添加path路径 …

Python常见设计模式库之python-patterns使用详解

概要 设计模式是解决软件设计问题的经验总结和最佳实践。Python 作为一种灵活且强大的编程语言,也可以使用设计模式来提高代码的可读性、可维护性和可扩展性。Python Patterns 库提供了一系列经典和常用的设计模式实现,本文将深入探讨 Python Patterns 库的功能、使用方法以…

Ubuntu Desktop 设置 gedit

Ubuntu Desktop 设置 gedit 1. View2. Editor3. Font & Colors4. keyboard shortcut5. Find and ReplaceReferences gedit (/ˈdʒɛdɪt/ or /ˈɡɛdɪt/) is the default text editor of the GNOME desktop environment and part of the GNOME Core Applications. Desig…

【机器学习-01】机器学习基本概念与建模流程

机器学习的过程本质上是一个不断通过数据训练来提升模型在对应评估指标上表现的过程。在此过程中&#xff0c;为模型提供有效的反馈并基于这些反馈进行持续的调整是至关重要的。只有当这个过程顺利进行时&#xff0c;模型才能得到有效的训练&#xff0c;机器才能真正实现学习。…

Android SystemServer进程解析

SystemServer进程在android系统中占了举足轻重的地位&#xff0c;系统的所有服务和SystemUI都是由它启动。 一、SystemServer进程主函数流程 1、主函数三部曲 //frameworks/base/services/java/com/android/server/SystemServer.java /** * The main entry point from zy…

mysql实战开发之 mysql 删除一张表某个字段的sql语句

有一张表, 我需要删除这张表其中的某一个或者某几个字段, 相信大家在日常开发中应该会遇到这种情况, 然后刚好自己接触的项目安装的mysql关闭了允许远程连接的设置, 也就是说不允许使用类似于navicat 等可视化工具连接, 那么就没办法通过可视化工具直接去通过鼠标操作就可以 完…

美团大规模KV存储挑战与架构实践

KV 存储作为美团一项重要的在线存储服务&#xff0c;承载了在线服务每天万亿级的请求量&#xff0c;并且保持着 99.995% 的服务可用性。在 DataFunSummit 2023 数据基础架构峰会上&#xff0c;我们分享了《美团大规模 KV 存储挑战与架构实践》&#xff0c;本文为演讲内容的整理…

CentOS7 部署 k8s

准备两台虚拟机192.168.152.129192.168.152.130更改主机名192.168.152.129&#xff1a;hostnamectl set-hostname k8s-masterhostnamectl192.168.152.130&#xff1a;hostnamectl set-hostname k8s-node1hostnamectl master节点配置 1.配置hosts 在两台节点上执行vim /etc/h…

JavaScript 知识点整理

JavaScript 知识点整理 学习课程参考&#xff1a;Java程序员用学前端么&#xff1f;java开发所需的前端技术全教程&#xff08;HTML/CSS/js/vue2/vue3/react&#xff09;bilibili 什么是 ES6 &#xff1f; 根据维基百科解释 ECMAScript 规范是由 Netscape 的 Brendan Eich 开发…

[S-Clustr]利用环形网络高匿名性控制骇客设备

地址 https://github.com/MartinxMax/S-Clustr_Ring_Network_Test_V1.2 当前软件处于待测试运行阶段,遇到bug及时反馈 影子集群 S-Clustr_Root_Server 收集显示设备状态的根服务器&#xff0c;部署在A服务器上UDP端口10091用于收集核心控制服务器的设备状态开放TCP端口1009…

pdf文件属性的删除

pdf文件属性的删除 投标过程中需要处理文件属性&#xff0c;特别是word文件属性以及pdf文件的处理 这里讲解pdf文件属性的处理 word处理在我的另外一个博客中&#xff0c;word文件属性的处理 https://ht666666.blog.csdn.net/article/details/134102504 一般用 adobe acroba…

Spring Boot Actuator介绍

大家在yaml中经常见到的这个配置 management: endpoints: web: exposure: #该配置线上需要去掉&#xff0c;会有未授权访问漏洞 include: "*" 他就是Actuator&#xff01; 一、什么是 Actuator Spring Boot Actuator 模块提供了生产级别…

力扣题目训练(20)

2024年2月13日力扣题目训练 2024年2月13日力扣题目训练594. 最长和谐子序列598. 区间加法 II599. 两个列表的最小索引总和284. 窥视迭代器287. 寻找重复数135. 分发糖果 2024年2月13日力扣题目训练 2024年2月13日第二十天编程训练&#xff0c;今天主要是进行一些题训练&#x…