视频、音频录制

1,项目介绍。

实现全屏录屏选择区域录屏摄像头录像麦克风录音主板音频录音截屏画板的自由组合。并通过FFmpeg完成音频与视频的合并。

功能界面
在这里插入图片描述
画板画笔

在这里插入图片描述

参考的项目

https://github.com/yangjinming1062/RecordWin

本项目是在此项目的基础上修复了部分bug,并增加了屏幕区域录屏,与主板音频录音功能。

2,知识点总结

2.1,热键注册。

WPF中进行热键注册需要添加钩子,用以监视热键输入。

public IntPtr winHandle;
private HwndSource hWndSource;
private void Window_Loaded(object sender, RoutedEventArgs e)
{//获取窗口句柄winHandle = new WindowInteropHelper(this).Handle;//在Win32窗口呈现wpf内容hWndSource = HwndSource.FromHwnd(winHandle);GoToScreenTopMiddle();SetHotKey(true);}private void SetHotKey(bool Add){if (Add){hWndSource.AddHook(MainWindowProc);HotKeyBF = HotKey.GlobalAddAtom($"{SettingHelp.Settings.播放暂停.Item1}-{Enum.GetName(typeof(System.Windows.Forms.Keys), SettingHelp.Settings.播放暂停.Item2)}");HotKeyTZ = HotKey.GlobalAddAtom($"{SettingHelp.Settings.停止关闭.Item1}-{Enum.GetName(typeof(System.Windows.Forms.Keys), SettingHelp.Settings.停止关闭.Item2)}");HotKeyHB = HotKey.GlobalAddAtom($"{SettingHelp.Settings.开关画笔.Item1}-{Enum.GetName(typeof(System.Windows.Forms.Keys), SettingHelp.Settings.开关画笔.Item2)}");HotKey.RegisterHotKey(winHandle, HotKeyBF, SettingHelp.Settings.播放暂停.Item1, SettingHelp.Settings.播放暂停.Item2);HotKey.RegisterHotKey(winHandle, HotKeyTZ, SettingHelp.Settings.停止关闭.Item1, SettingHelp.Settings.停止关闭.Item2);HotKey.RegisterHotKey(winHandle, HotKeyHB, SettingHelp.Settings.开关画笔.Item1, SettingHelp.Settings.开关画笔.Item2);}else//暂时没起作用,todo{hWndSource.RemoveHook(MainWindowProc);HotKey.GlobalDeleteAtom((short)HotKeyBF);HotKey.GlobalDeleteAtom((short)HotKeyTZ);HotKey.GlobalDeleteAtom((short)HotKeyHB);HotKey.UnregisterHotKey(winHandle, HotKeyBF);HotKey.UnregisterHotKey(winHandle, HotKeyTZ);HotKey.UnregisterHotKey(winHandle, HotKeyHB);}}private IntPtr MainWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled){switch (msg){case HotKey.WM_HOTKEY:{int sid = wParam.ToInt32();if (Visibility == Visibility.Visible){if (!SettingPop.IsOpen){if (sid == HotKeyBF){if (btBegin.Visibility == Visibility.Visible)btBegin_Click(null, null);elsebtParse_Click(null, null);}else if (sid == HotKeyTZ){if (btStop.Visibility == Visibility.Visible)btStop_Click(null, null);elseBtClose_Click(null, null);}}if (sid == HotKeyHB){btPen.IsChecked = !btPen.IsChecked;OpenDraweWin();}}handled = true;break;}}return IntPtr.Zero;}

外部函数

 public class HotKey{/// <summary> /// 如果函数执行成功,返回值不为0。 /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。.NET方法:Marshal.GetLastWin32Error() /// </summary> /// <param name="hWnd">要定义热键的窗口的句柄</param> /// <param name="id">定义热键ID(不能与其它ID重复) </param> /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param> /// <param name="vk">定义热键的内容,WinForm中可以使用Keys枚举转换, /// WPF中Key枚举是不正确的,应该使用System.Windows.Forms.Keys枚举,或者自定义正确的枚举或int常量</param> [DllImport("user32.dll", SetLastError = true)]public static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifiers fsModifiers, int vk);/// <summary> /// 取消注册热键 /// </summary> /// <param name="hWnd">要取消热键的窗口的句柄</param> /// <param name="id">要取消热键的ID</param> [DllImport("user32.dll", SetLastError = true)]public static extern bool UnregisterHotKey(IntPtr hWnd, int id);/// <summary> /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0 /// </summary> [DllImport("kernel32", SetLastError = true)]public static extern short GlobalAddAtom(string lpString);[DllImport("kernel32", SetLastError = true)]public static extern short GlobalDeleteAtom(short nAtom);/// <summary> /// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值) /// </summary> [Flags()]public enum KeyModifiers{None = 0,Alt = 1,Ctrl = 2,Shift = 4,WindowsKey = 8}/// <summary> /// 热键的对应的消息ID /// </summary> public const int WM_HOTKEY = 0x312;}
2. 2,两种透明。

根据实际需要可以定义两种透明,一种是真透明Transparent,一种是假透明#01000000

 <Color x:Key="FakeTransparentColor" >#01000000</Color><Color x:Key="TrueTransparentColor" >Transparent</Color>
 Background = Application.Current.Resources[enable ? "FakeTransparent" : "TrueTransparent"] as Brush;

在窗口定义为接受透明时:AllowsTransparency="True",采用真透明背景的窗体A,覆盖在应用B上时,应用B的控件可透过窗体A被操作。采用假透明背景的窗体A,覆盖在应用B上时,应用B的控件不能透过窗体A被操作。

2. 3,音视频合并。

音视频的合并一般以命令的形式调用软件FFmpeg完成。

下载FFmpeg软件

常用语法:

  1. ‌直接合并(视频流复制+音频转码)

    若需保持视频无损且兼容MP4容器,建议将WAV转码为AAC:

ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -strict experimental output.mp4

​ 参数说明:

  • -c:v copy:复制视频流不重新编码

  • -c:a aac:将WAV音频转码为MP4支持的AAC格式

  • -strict experimental:早期版本需此参数支持AAC‌

  1. 强制替换原视频音频轨道

若原视频已含音频需替换,可指定映射关系:

ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 output.mp4

参数说明

  • -map 0:v:0:选择第一个输入文件(video.mp4)的视频流
  • -map 1:a:0:选择第二个输入文件(audio.wav)的音频流‌
  1. 无损合并(需视频无音频)

若视频本身无音频轨道,可直接复制流:

ffmpeg -i video.mp4 -i audio.wav -c copy output.mkv

注意:需改用MKV容器以支持PCM音频流‌。

  1. 示例:

    将视频1.mp4与音频1.wav合并为output.mkv
    在这里插入图片描述

2. 4,自定义动画。
public class CornerRadiusAnimation : AnimationTimeline{static CornerRadiusAnimation(){FromProperty = DependencyProperty.Register("From", typeof(CornerRadius), typeof(CornerRadius));ToProperty = DependencyProperty.Register("To", typeof(CornerRadius), typeof(CornerRadius));}private bool _fromSetted;private bool _toSetted;public static readonly DependencyProperty FromProperty;public CornerRadius From{get => (CornerRadius)GetValue(FromProperty);set{SetValue(FromProperty, value);_fromSetted = true;}}public static readonly DependencyProperty ToProperty;public CornerRadius To{get => (CornerRadius)GetValue(ToProperty);set{SetValue(ToProperty, value);_toSetted = true;}}public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock){var fromVal = _fromSetted ? (CornerRadius)GetValue(FromProperty) : (CornerRadius)defaultOriginValue;var toVal = _toSetted ? (CornerRadius)GetValue(ToProperty) : (CornerRadius)defaultDestinationValue;if (animationClock.CurrentProgress != null)return new CornerRadius(animationClock.CurrentProgress.Value * (toVal.TopLeft - fromVal.TopLeft) + fromVal.TopLeft,animationClock.CurrentProgress.Value * (toVal.TopRight - fromVal.TopRight) + fromVal.TopRight,animationClock.CurrentProgress.Value * (toVal.BottomRight - fromVal.BottomRight) + fromVal.BottomRight,animationClock.CurrentProgress.Value * (toVal.BottomLeft - fromVal.BottomLeft) + fromVal.BottomLeft);return new CornerRadius();}protected override Freezable CreateInstanceCore() => new CornerRadiusAnimation();public override Type TargetPropertyType => typeof(CornerRadius);}
2.5,注意事项

不同目标框架的.NetFramework,编译后的.dll不一定相同,例如使用.NetFramerwork4.6.1将生成大量系统自带的.dll

如下:面对同一个解决方案

.NetFramerwork4.7编译清单。
在这里插入图片描述

.NetFramerwork4.6.1编译清单

在这里插入图片描述

3,项目链接

https://download.csdn.net/download/lingxiao16888/91461603

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

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

相关文章

Linux文件系统理解1

目录一、初步理解系统层面的文件1. 文件操作的本质2. 进程管理文件核心思想二、系统调用层1. 打开关闭文件函数2. 读写文件函数三、操作系统文件管理1. 文件管理机制2. 硬件管理机制四、理解重定向1. 文件描述符分配规则2. 重定向系统调用3. 重定向命令行调用五、理解缓冲区1. …

科技向善,银发向暖:智慧养老与经济共筑适老未来

人口老龄化是当今中国社会面临的重大课题&#xff0c;也是推动社会变革与经济转型的重要引擎。随着数字技术的飞速发展&#xff0c;“智慧养老”正以科技向善的温度&#xff0c;为老年群体构建更舒适、更安全、更有尊严的晚年生活&#xff0c;同时为银发经济注入蓬勃活力&#…

numpy库 降维,矩阵创建与元素的选取,修改

目录 1.降维函数ravel()和flatten ravel(): flatten(): 2.矩阵存储与内存结构 3.修改矩阵形状的方法 4.特殊矩阵创建 全零矩阵: 如np.zeros(5) 创建含5个零的一维数组&#xff0c;输出中零后的点&#xff08;如 0.&#xff09;表示浮点数类型。 全一矩阵&#xff1a;如n…

SpringCloud seata全局事务

项目https://github.com/apache/incubator-seata docker拉取启动server $ docker run --name seata-server -p 8091:8091 apache/seata-server:2.1.0 seata注册到nacos <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-…

OpenLayers 快速入门(八)事件系统

看过的知识不等于学会。唯有用心总结、系统记录&#xff0c;并通过温故知新反复实践&#xff0c;才能真正掌握一二 作为一名摸爬滚打三年的前端开发&#xff0c;开源社区给了我饭碗&#xff0c;我也将所学的知识体系回馈给大家&#xff0c;助你少走弯路&#xff01; OpenLayers…

【Linux | 网络】应用层(HTTPS)

目录一、HTTPS的概念二、准备概念2.1 什么是加密和解密2.2 为什么要加密2.3 常见的加密方式2.3.1 对称加密2.3.1 非对称加密2.4 数据摘要&&数据指纹三、HTTPS理解过程3.1 只使用对称加密3.2 只使用非对称加密3.3 双方都使用非对称加密3.4 对称加密 非对称加密3.5 中间…

GRE协议

一、实验拓扑二、实验配置1、静态路由实现GRERT1配置&#xff1a;RT1(config)# int fa1/0RT1(config-if)# ip add 192.168.20.1 255.255.255.0RT1(config-if)# no shutdownRT1(config)# int fa0/0RT1(config-if)# ip add 172.1.1.2 255.255.255.0RT1(config-if)# no shutdownRT…

JDialong弹窗

public class DialogDemo extends JFrame {public DialogDemo(){this.setVisible(true);this.setSize(700,500);this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//JFrame 放东西&#xff0c;容器Container contentPane this.getContentPane();//绝对布局conte…

tlias智能学习辅助系统--违纪处理(实战)

目录 1.StudentController.java 2.interface StudentService 3.StudentServiceImpl.java 4.interface StudentMapper 1.StudentController.java // 违纪处理PutMapping("/violation/{id}/{score}")Operation(summary "违纪处理")public Result violat…

传统RNN模型笔记:输入数据长度变化的结构解析

一、案例背景 本案例通过PyTorch的nn.RNN构建单隐藏层RNN模型&#xff0c;重点展示RNN对变长序列数据的处理能力&#xff08;序列长度从1变为20&#xff09;&#xff0c;帮助理解RNN的输入输出逻辑。 二、核心代码与结构拆解 def dm_rnn_for_sequencelen():# 1. 定义RNN模型rnn…

OpenLayers 快速入门(四)View 对象

看过的知识不等于学会。唯有用心总结、系统记录&#xff0c;并通过温故知新反复实践&#xff0c;才能真正掌握一二 作为一名摸爬滚打三年的前端开发&#xff0c;开源社区给了我饭碗&#xff0c;我也将所学的知识体系回馈给大家&#xff0c;助你少走弯路&#xff01; OpenLayers…

测试左移方法论

测试左移&#xff08;Shift-Left Testing&#xff09;​是一种软件测试方法论&#xff0c;核心思想是将测试活动从传统的开发后期&#xff08;如系统测试、验收测试阶段&#xff09;提前到软件生命周期的更早期阶段&#xff08;如需求分析、设计、编码阶段&#xff09;&#xf…

OpenCV(01)基本图像操作、绘制,读取视频

图像基础 import cv2 as cv#读取图像 cv.imread(path,读取方式)默认读为彩色图像 #cv.imread(path) cat cv.imread(E:\hqyj\code\opencv\images\\face.png)#显示图像 cv.imshow(window,img) cv.imshow(myimg,cat)print(cat) print(cat.shape) #(h,w,c) 元组(1,1) print(cat…

biji 1

1.应用层&#xff1a;为应用程序提供网络服务。2.表示层&#xff1a;定义数据的格式&#xff0c;对数据进行压缩、解压缩、加密、解密、编码、解码。3.会话层&#xff1a;对通信双方间的会话进行建立、维护、拆除-----session id---区分同一应用程序的不同进程4.传输层&#x…

mongodb的备份和还原(精简)

1 官网下载对应版本msi2 运行msi mongodb-database-tools-windows-x86_64-100.12.2.msi3 将安装地址加到环境变量 C:\Program Files\MongoDB\Tools\100\bin4 查看version mongodump --version mongorestore --version5 运行 备份命令 mongodump --host 127.0.0.1 --db dbname--…

Mac安装Typescript报错

目录 Mac上安装Typescript报错: 原因分析 1. 默认 npm 全局安装目录的权限问题 2. Node.js 的安装方式 如何解决?(无需每次用 `sudo`) 方法 1:修改 npm 全局目录的权限(推荐) 方法 2:配置 npm 使用用户级目录 方法 3:使用 `nvm` 管理 Node.js(最推荐) 为什么建议避免…

spring-cloud概述

单体架构 把业务的所有功能实现都打包在一个war包或者jar包&#xff0c;这种方式就成为单体架构。 比如Spring课程中的博客系统,前端后端数据库实现&#xff0c;都在一个项目中&#xff0c;这种架构就称为单体架构. 举个例子&#xff1a; 比如在电商系统中&#xff0c;我们…

android ROOM kotlin官方文档完全学习

android ROOM kotlin官方文档完全学习2.6 使用 Room 将数据保存到本地数据库 | Android Developers (google.cn) 一、简介 1.1 引入 dependencies {def room_version "2.6.1"implementation "androidx.room:room-runtime:$room_version"//如下三选一a…

DOM编程全解析:操作、事件与存储实战指南

引言&#xff1a;DOM——JavaScript与网页交互的桥梁 DOM&#xff08;文档对象模型&#xff09; 是JavaScript操作HTML/XML文档的接口&#xff0c;它将网页文档抽象为一个树形结构&#xff0c;允许开发者通过API动态修改文档的内容、结构和样式。无论是实现动态交互&#xff0…

Ansible命令

Ansible命令 ansible 常用命令 /usr/bin/ansible   #Ansibe AD-Hoc 临时命令执行工具&#xff0c;常用于临时命令的执行 /usr/bin/ansible-doc    #Ansible 模块功能查看工具 /usr/bin/ansible-galaxy   #下载/上传优秀代码或Roles模块 的官网平台&#xff0c;基于网…