c# 视频播放之Vlc.DotNet.Forms

news2024/11/18 1:51:52

先说下优缺点

优点:与电脑无关,能播放主流编码格式视频。

缺点:只能播放本地视频,网络视频播放不了。

下面是具体操作和代码

1. 安装Vlc.DotNet.Forms 和 VideoLAN.LibVLC.Windows

Vlc.DotNet.Forms 是播放库,VideoLAN.LibVLC.Windows用于播放显示

2. 界面布局

用到 vlcControl: 视频播放组件 ;滑块 TrackBar :自定义控件,用于显示视频播放进度和音量;button:视频播放和快进

我播放是网上的视频, 所以调用线程先将视频下载到本地,下载完成后在播放。

lTrackBar_vedio 和 lTrackBar_voice 是我自定义的滑块,可以直接用系统默认的滑块控件。

 public partial class Form1 : Form
    {
        private string url = @"http://www.xxxxx.com/video/20240111155329.mp4";
        private string vedioPath = AppDomain.CurrentDomain.BaseDirectory + @"Vedio\123.mp4";
        private long vedioLength = 0;
        private string vedioTime;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + @"\Vedio"))
                Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + @"\Vedio");

            if (!File.Exists(vedioPath))
            {
                VedioDownloader urlDownloader = new VedioDownloader(vedioPath, url);
                new Thread(new ThreadStart(urlDownloader.DownloadFileAsync)).Start(); ;
            }
            else
            {
                InitVedio();  
            }
        }

        private void InitVedio()
        {
            vlcControl1.Play(new FileInfo(vedioPath));
            button_play.BackgroundImage = Properties.Resources.audioPlay;
            vlcControl1.Audio.Volume = this.lTrackBar_voice.L_Value;
            lTrackBar_vedio.L_Maximum = this.lTrackBar_vedio.Width;
            lTrackBar_vedio.L_Minimum = 0;
        }

        //加载播放需要的库
        private void vlcControl1_VlcLibDirectoryNeeded(object sender, Vlc.DotNet.Forms.VlcLibDirectoryNeededEventArgs e)
        {
            var currentAssembly = Assembly.GetEntryAssembly();
            var currentDirectory = new FileInfo(currentAssembly.Location).DirectoryName;

            if (currentDirectory != null)
            {
                if (IntPtr.Size == 4)
                {
                    e.VlcLibDirectory = new DirectoryInfo(Path.GetFullPath(@".\libvlc\win-x86"));
                }
                else
                {
                    e.VlcLibDirectory = new DirectoryInfo(Path.GetFullPath(@".\libvlc\win-x64"));
                }
            }

            if (!e.VlcLibDirectory.Exists)
            {
                var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
                folderBrowserDialog.Description = "Select Vlc libraries folder.";
                folderBrowserDialog.RootFolder = Environment.SpecialFolder.Desktop;
                folderBrowserDialog.ShowNewFolderButton = true;
                if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
                {
                    e.VlcLibDirectory = new DirectoryInfo(folderBrowserDialog.SelectedPath);
                }
            }
        }

        private void vlcControl1_TimeChanged(object sender, Vlc.DotNet.Core.VlcMediaPlayerTimeChangedEventArgs e)
        {
            vedioLength = vlcControl1.VlcMediaPlayer.Length;

            string allTime = ConvertTimeStampToDateTime(vedioLength);
            string current = ConvertTimeStampToDateTime(vlcControl1.VlcMediaPlayer.Time);

            this.lTrackBar_vedio.L_Value = Convert.ToInt32(1.0f * (lTrackBar_vedio.L_Maximum - lTrackBar_vedio.L_Minimum) * vlcControl1.VlcMediaPlayer.Time / vedioLength);
           
            vedioTime = current + " / " + allTime;

            SetVedioTime(vedioTime);
        }

        /// <summary>
        /// 使用委托显示视频时间
        /// </summary>
        /// <param name="text"></param>
        delegate void SetTextCallBack(string text);
        private void SetVedioTime(string vedioTime)
        {
            if (this.label_vedioTime.InvokeRequired)
            {
                SetTextCallBack stcb = new SetTextCallBack(SetVedioTime);
                this.BeginInvoke(stcb, new object[] { vedioTime });
            }
            else
            {
                this.label_vedioTime.Text = vedioTime;
            }
        }

        private string ConvertTimeStampToDateTime(long vedioLength)
        {
            DateTime dt = new DateTime(vedioLength * 10000);
            return dt.Hour.ToString().PadLeft(2, '0') + ":" + dt.Minute.ToString().PadLeft(2, '0') + ":" + dt.Second.ToString().PadLeft(2, '0');
        }

        private void button_play_Click(object sender, EventArgs e)
        {
            if (vlcControl1.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.Playing)
            {
                vlcControl1.Pause();
                button_play.BackgroundImage = Properties.Resources.audioPause2;
            }
            else
            {
                if (vlcControl1.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.Ended)
                {
                    InitVedio();
                }
                else
                {
                    button_play.BackgroundImage = Properties.Resources.audioPlay;
                    vlcControl1.Play();
                }
            }
        }

        private void button_voice_Click(object sender, EventArgs e)
        {
            if (lTrackBar_voice.L_Value != 0)
            {
                lTrackBar_voice.L_Value = 0;
                button_voice.BackgroundImage = Properties.Resources.voice_close;
            }
            else
            {
                lTrackBar_voice.L_Value = 80;
                button_voice.BackgroundImage = Properties.Resources.voice_open;
            }
        }

        private void lTrackBar_voice_LValueChanged(object sender, LEventArgs e)
        {
            vlcControl1.Audio.Volume = lTrackBar_voice.L_Value;
        }

        private void vlcControl1_Stopped(object sender, Vlc.DotNet.Core.VlcMediaPlayerStoppedEventArgs e)
        {
            button_play.BackgroundImage = Properties.Resources.audioPause2;
        }

        private void lTrackBar_vedio_MouseMove(object sender, MouseEventArgs e)
        {
            PlayInNewLocation(sender,e);
        }

        private void lTrackBar_vedio_MouseDown(object sender, MouseEventArgs e)
        {
            PlayInNewLocation(sender,e);
        }

        private void PlayInNewLocation(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (vlcControl1.State == Vlc.DotNet.Core.Interops.Signatures.MediaStates.Ended)
                {
                    InitVedio();
                }

                vlcControl1.VlcMediaPlayer.Time = this.lTrackBar_vedio.L_Value * vedioLength / (lTrackBar_vedio.L_Maximum - lTrackBar_vedio.L_Minimum);
            }
        }

        private void button1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                vlcControl1.Rate = 2.5f;
        }

        private void button1_MouseUp(object sender, MouseEventArgs e)
        {
            vlcControl1.Rate = 1;
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            // vlcControl在stop的过程中可能会产生子窗口消息,然而子窗口消息是在主线程(UI线程)中处理的,而stop()方法也是在主线程中调用的,这就造成了竞争性死锁。所以先释放掉主窗体,在释放vlcControl
            this.Dispose();

            if (vlcControl1.State != Vlc.DotNet.Core.Interops.Signatures.MediaStates.Stopped)
                vlcControl1.Stop();
            vlcControl1.Dispose();
        }
    }

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

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

相关文章

算法 动态分析 及Java例题讲解

动态规划 动态规划&#xff08;英语&#xff1a;Dynamic programming&#xff0c;简称 DP&#xff09;&#xff0c;是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的&#xff0c;通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划常常适…

Ant Design Vue上传多个图片

模板代码&#xff1a; 定义变量&#xff1a; 文件限制的函数&#xff1a; 上传的函数&#xff1a; 样式函数&#xff1a; 完整代码&#xff1a; <template><div class"dialog-upload" v-if"showUploadDialog"><div class"dialog-uplo…

2018年认证杯SPSSPRO杯数学建模A题(第二阶段)海豚与沙丁鱼全过程文档及程序

2018年认证杯SPSSPRO杯数学建模 基于聚类分析的海豚捕食合作策略 A题 海豚与沙丁鱼 原题再现&#xff1a; 沙丁鱼以聚成大群的方式来对抗海豚的捕食。由于水下光线很暗&#xff0c;所以在距离较远时&#xff0c;海豚只能使用回声定位方法来判断鱼群的整体位置&#xff0c;难…

python|写一个简单的http服务器

本篇文章的python版本为: 什么是http http是一个应用层协议&#xff0c;准确的来说是基于TCP/IP4层网络协议中的传输层中的TCP应用层协议。 额&#xff0c;4层模型大概是这样的: 在网络通信中&#xff0c;用户的数据是以报文来传输的&#xff0c;但是在实际通信中&#xff0…

密码学学习笔记(二十四):TCP/IP协议栈

TCP/IP协议栈的基础结构包括应用层、传输层、网络层、数据链路层和物理层。 应用层 应用层位于TCP/IP协议栈的最顶层&#xff0c;是用户与网络通信的接口。这一层包括了各种高级应用协议&#xff0c;如HTTP&#xff08;用于网页浏览&#xff09;、FTP&#xff08;用于文件传输…

【安全篇 / FortiGuard】(7.4) ❀ 02. 独立VDOM下的FortiGuard服务升级 ❀ FortiGate 防火墙

【简介】由于业务的需要&#xff0c;创建两个独立VDOM&#xff0c;每个VDOM有各自的宽带&#xff0c;但是FortiGuard服务却无法升级&#xff0c;有什么办法解决吗&#xff1f; VDOM概念 首先我们看看什么是VDOM。 ① VDOM将你的FortiGate划分为多个逻辑设备&#xff0c;并将一个…

深入理解Linux文件系统

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;晴る—ヨルシカ 0:20━━━━━━️&#x1f49f;──────── 4:30 &#x1f504; ◀️ ⏸ ▶️ ☰ &…

力扣精选算法100题——长度最小的子数组(滑动窗口专题)

本题链接——长度最小的子数组 第一步&#xff1a;了解题意 给定一个数组&#xff0c;要求在这个数组中找到一个必须是连续的子数组并且这个子数组每个元素加起来>target并从找到的这些数组中取一个最短的数组。 第二步&#xff1a;算法原理 滑动窗口是一种在序列&#xff…

【开源】基于JAVA语言的河南软件客服系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统管理人员2.2 业务操作人员 三、系统展示四、核心代码4.1 查询客户4.2 新增客户跟进情况4.3 查询客户历史4.4 新增服务派单4.5 新增客户服务费 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的河…

中仕公考:贵州省统一面向社会公开招录公务员公告

2024年1月22日至1月25日期间,每日10:00、14:00及19:00对报名情况进行更新,供报考者参考。 资格初审时间为2024年1月22日9:00至1月28日17:00。 网上缴费时间为2024年1月22日9:00至1月29日17:00。 打印准考证时间2024年3月11日9:00至3月14日17:00。 公共科目笔试时间为: 202…

深度学习(2)--卷积神经网络(CNN)

卷积神经网络&#xff08;Convolutional Neural Networks&#xff09;是一种深度学习模型或类似于人工神经网络的多层感知器&#xff0c;常用来分析视觉图像。 一.卷积神经网络基础概念 传统网络是二维的&#xff0c;而卷积网络是三维的。 例如32x32x3的图片&#xff0c;在传…

Pure-admin框架 Pure-table中获取所选中的内容的信息

最近在尝试使用Pure-admin框架来进行开发&#xff0c;正好遇到了多选表格需要获取选中项的id的情况&#xff0c;因为平台介绍说是二次封装 element-plus 的 Table &#xff0c;直接拿el-table的方法来试 在table上设置属性ref"multipleTableRef" let idArr [];mult…

为什么需要放行回源IP

为什么需要放行回源IP 网站以“独享模式”成功接入WAF后&#xff0c;所有网站访问请求将先经过独享引擎配置的ELB然后流转到独享引擎实例进行监控&#xff0c;经独享引擎实例过滤后再返回到源站服务器&#xff0c;流量经独享引擎实例返回源站的过程称为回源。在服务器看来&…

从“渲个锤子”,浅析影视动画渲染的困难与挑战!

提起“雷神之锤”&#xff0c;相信大家都不陌生。它是漫威电影宇宙中“雷神”托尔所使用的武器。传说中&#xff0c;这把圣器可以承载魔法咒语&#xff0c;召唤风、雨、雷、电四种自然元素。它能在使用者的意念下对目标进行攻击&#xff0c;无视与使用者之间的距离和障碍物&…

C++进阶(五)二叉搜索树

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、二叉搜索树概念二、二叉搜索树操作三、二叉搜索树的实现四、二叉搜索树的应用五、二叉搜索…

(人才测评)招聘数据分析师的入职测评方案

现在是一个大数据的时代&#xff0c;我们的车载导航、淘宝购物、包括人才招聘、都是大数据的产物&#xff0c;然而光靠数据堆积是没用的&#xff0c;所以如何高效的进行数据挖掘与分析&#xff0c;就成了每一件企业思考的问题。 一、 数据分析师的基本工作标准 1、 平时需要…

【vue2】状态管理之 Vuex

文章目录 一、介绍1、概念 2、工作示意图3、安装4、简单示例 二、核心1、State1.1 组件中获取 Vuex 的状态1.2 mapState 辅助函数1.3 对象展开运算符 2、Getter2.1 基本使用2.2 通过属性访问2.3 通过方法访问2.4 mapGetters 辅助函数 3、Mutation3.1 定义 mutation3.2 commit 提…

C++初阶类与对象(三):详解复制构造函数和运算符重载

上次介绍了构造函数和析构函数&#xff1a;C初阶类与对象&#xff08;二&#xff09;&#xff1a;详解构造函数和析构函数 今天就来接着介绍新的内容&#xff1a; 文章目录 1.拷贝构造函数1.1引入和概念1.2特性 2.赋值运算符重载2.1运算符重载2.2放在哪里2.3运算符重载示例2.3.…

WebRTC视频会议/视频客服系统EasyRTC进入会议室密码验证的开发与实现

基于WebRTC技术的EasyRTC视频会议系统&#xff0c;建设目标是让用户随时随地、快捷方便地进行视频会议&#xff0c;并根据行业需求有针对性地提供多样化、个性化功能&#xff0c;该系统是覆盖全球的实时音视频开发平台&#xff0c;支持一对一、一对多等视频通话&#xff0c;极大…

Vray渲染效果图材质参数设置

渲染是创造出引人入胜视觉效果的关键步骤&#xff0c;在视觉艺术领域尤为重要。不过&#xff0c;渲染作为一个资源密集型的过程&#xff0c;每当面对它时&#xff0c;我们往往都会遭遇到时间消耗和资源利用的巨大挑战。幸运的是&#xff0c;有几种方法能够帮助我们优化渲染&…