C#实现国产Linux视频录制生成mp4

一. 技术方案

要完成这些功能,具体来说,需要解决如下几个技术问题:

(1)麦克风数据采集。

(2)摄像头数据采集。

(3)音频数据编码。

(4)视频数据编码。

(5)将编码后的数据按.mp4文件格式写入到文件容器中。

(6)保证音频视频播放的同步。

我们使用跨平台的 C# .NET Core ,跨平台的UI框架Avalonia,再借助 Oraycn.LinuxCapture 和 Oraycn.MFile.NetCore 这两个组件,就很容易采集到麦克风和摄像头的数据,并且将它们编码写入到mp4文件中。

我们先看看录制程序在银河麒麟上的运行效果:

两个下拉列表可以选择要使用的麦克风和摄像头设备。

点击“开始”按钮,麦克风和摄像头将开始采集数据,并录制生成mp4文件(在运行目录下)。

点击“结束”按钮,则将完成录制,此时可以打开生成的mp4文件进行播放。

二.具体实现

(1)ICameraCapturer是摄像头视频采集组件;IMicrophoneCapturer是麦克风声音采集组件。

(2)我们可以通过调用CapturerFactory的CreateXXXX方法来创建对应的采集器实例。

(3)得到采集器实例后,调用Start方法,即可开始采集;调用Stop方法,即停止采集。

(4)采集得到的数据,将通过相应的事件(ImageCaptured、AudioCaptured)暴露出来,我们预定这些事件,即可拿到采集的数据。

(5)将拿到的数据喂给VideoFileMaker,VideoFileMaker就会将其编码并写入到mp4文件中。

我们这里列一下核心代码,完整的代码大家可以从文末下载源码进行了解。

创建并启动采集器:

            //摄像头采集器this.cameraCapturer = CapturerFactory.CreateCameraCapturer(cameraIndex, videoSize, frameRate);this.cameraCapturer.ImageCaptured += CameraCapturer_ImageCaptured;this.cameraCapturer.CaptureError += CameraCapturer_CaptureError;//麦克风采集器this.microphoneCapturer = CapturerFactory.CreateMicrophoneCapturer(micIndex);this.microphoneCapturer.AudioCaptured += MicrophoneCapturer_AudioCaptured;this.microphoneCapturer.CaptureError += MicrophoneCapturer_CaptureError;this.microphoneCapturer.Start();this.cameraCapturer.Start();

创建并启动录制器:

            this.videoFileMaker = new VideoFileMaker();this.videoFileMaker.Initialize("test.mp4", VideoCodecType.H264, videoSize.Width, videoSize.Height, frameRate, VideoQuality.High, AudioCodecType.AAC, audioSampleRate, channelCount, true);

将采集到的数据喂给录制器:

    private void CameraCapturer_ImageCaptured(byte[] obj){if (this.isRecording){this.videoFileMaker.AddVideoFrame(obj);}}private void MicrophoneCapturer_AudioCaptured(byte[] obj){if (this.isRecording){this.videoFileMaker.AddAudioFrame(obj);}}

停止录制:

    private void FinishRecorded(object? sender, Avalonia.Interactivity.RoutedEventArgs e){this.RecordState_Changed(false);this.cameraCapturer?.Stop();this.cameraCapturer?.Dispose();this.microphoneCapturer?.Stop();this.microphoneCapturer?.Dispose();this.videoFileMaker?.Close(true);MessageBox.Show("录制完成!", this);}

三. 部署运行

如果要在银河麒麟或统信UOS上运行这里的录制程序,则需要现在目标操作系统上安装.NET Core 3.1。

然后将VS生成目录下的 netcoreapp3.1 文件夹拷贝到目标电脑上,进入netcoreapp3.1文件夹,打开终端,并在终端中输入如下命令:

dotnet Oraycn_Avalonias_RecordDemo.Desktop.dll

回车运行后,就会出现前面截图的UI界面,然后我们就可以录制麦克风摄像头了。

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

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

相关文章

低代码与AI:赋能企业数字化转型

引言 随着全球经济的快速发展和科技的飞速进步,数字化转型已成为各个行业和企业发展的重要趋势。数字化转型的背景不仅是提升效率和竞争力的手段,更是适应市场变化、满足客户需求的必由之路。 在当今信息化时代,技术的变革推动了企业运营方式…

嵌入式系统:全面解读与关键要点

嵌入式系统,这个看似专业而遥远的技术词汇,其实早已渗透进了我们日常生活的方方面面。从智能手机到家用电器,再到汽车中的电子控制系统,嵌入式系统无处不在。你是否好奇它们是如何工作的,又有哪些关键点值得我们关注&a…

【STM32 FreeRTOS】队列和缓冲区

队列简介 队列是任务到任务、任务到中断、中断到任务数据交流的一种机制。 队列可以容纳有限数量的固定大小的数据项。一个队列可以容纳的最大项目数称为它的长度。 数据入队出队方式:队列通常用作先进先出(FIFO)缓冲区,其中数…

强大的接口测试可视化工具:Postman Flows

Postman Flows是一种接口测试可视化工具,可以使用流的形式在Postman工作台将请求接口、数据处理和创建实际流程整合到一起。如下图所示 Postman Flows是以API为中心的可视化应用程序开发界面。它提供了一个无限的画布用于编排和串连API,数据可视化来显示…

html转vue项目

HTML是一种用于构建网页的标记语言,而Vue是一种用于构建用户界面的JavaScript框架。在HTML中使用Vue可以提供更加灵活和动态的用户界面功能。本文将介绍如何将HTML代码转换为Vue,并提供具体的代码示例。 首先,我们需要在项目中引入Vue框架。…

30. 串联所有单词的子串【 力扣(LeetCode) 】

一、题目描述 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如,如果 words [“ab”,“cd”,“ef”], 那么 “abcdef”,…

配置oss cdn加速静态资源访问 阿里云

效果对比 配置cdn下载速度对比 步骤 1: 登录阿里云控制台控制台主页,找到并点击“对象存储 OSS” 创建存储空间(Bucket) 设置权限 步骤 2: 获取外网访问地址 步骤 3 在 CDN 中使用该地址 复制该外网访问地址 打开全站加速 DCDN/域名管理 添…

thinkphp8 定时任务

在ThinkPHP8中创建定时任务通常涉及到Cron作业调度或者操作系统的定时任务功能(如cronjob)。以下是一个使用操作系统的cronjob的例子。 创建一个命令: // app/Command/ExampleCommand.php namespace app\Command;use think\console\Command; …

社群机器人的崛起:重塑社群管理的智慧未来

在数字化浪潮的推动下,社群作为连接人与人、促进信息交流与情感共鸣的桥梁,其重要性日益凸显。然而,随着社群规模的日益庞大和成员需求的多元化,传统的人工管理方式已难以满足高效、精准的管理需求。此时,社群机器人的…

P9750 [CSP-J 2023] 一元二次方程

[题目通道]([CSP-J 2023] 一元二次方程 - 洛谷) #include<bits/stdc.h> using namespace std; int T,m,a,b,c,d,k,t; int gcd(int a,int b){return b?gcd(b,a%b):a; } void kkksc03(){cin>>a>>b>>c;if(a<0)a-a,b-b,c-c;db*b-4*a*c,k1;if(d<0)…

Shell——读取命令read

在 Shell 编程中&#xff0c;read 命令用于从标准输入&#xff08;通常是键盘&#xff09;读取数据并将其存储在变量中。它非常适合用于交互式脚本&#xff0c;让用户能够输入数据。 基本用法 以下是 read 命令的基本用法&#xff1a; #!/bin/bashecho "请输入您的名字…

STM32 PWR电源控制 与 低功耗模式 详解

目录 STM32 PWR电源控制 与 低功耗模式 详解 1. PWR 电源控制 简介 2. PWR 电源控制 框图 3. 上电复位和掉电复位 与 可编程电压检测器&#xff08;PVD&#xff09; 3.1 内嵌复位与电源控制模块特性图 3.2 上电复位和掉电复位 3.3 可编程电压检测器&#xff08;PVD&…

微分方程(Blanchard Differential Equations 4th)中文版Section1.6

平衡点与相直线 给定一个微分方程 d y d t = f ( t , y ) , \frac{dy}{dt} = f(t, y), dtdy​=f(t,y), 我们可以通过绘制斜率场和勾勒图形来大致了解解的行为,或者使用欧拉法计算近似解。有时我们甚至可以推导出解的显式公式并绘制结果。所有这些技术都需要相当多的工作,无…

Python酷库之旅-第三方库Pandas(089)

目录 一、用法精讲 376、pandas.Series.list.flatten方法 376-1、语法 376-2、参数 376-3、功能 376-4、返回值 376-5、说明 376-6、用法 376-6-1、数据准备 376-6-2、代码示例 376-6-3、结果输出 377、pandas.Series.list.__getitem__魔法方法 377-1、语法 377-…

数据仓库: 3- ETL过程

目录 3- ETL过程3.1 数据抽取&#xff08;Extract&#xff09;3.1.1 数据抽取的挑战3.1.2 数据抽取的方式3.1.2.1 全量抽取3.1.2.2 增量抽取3.1.2.3 实时抽取 3.1.3 数据抽取的技术3.1.4 数据抽取工具3.1.5 总结 3.2 数据转换&#xff08;Transform&#xff09;3.2.1 定义3.2.2…

24.8.19学习笔记(MNIST,)

pytorch MNIST手写数字识别&#xff1a; import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms# 设定随机种子以保证结果可复现 torch.manual_seed(0)# 定义超参数 batch_size 32 learning_rate 0.001 num_epochs…

机器学习第十一章--特征选择与稀疏学习

一、子集搜索与评价 我们将属性称为 “特征”(feature&#xff09;&#xff0c;对当前学习任务有用的属性称为 “相关特征”(relevant feature&#xff09;、没什么用的属性称为 “无关特征”(irrelevant feature)&#xff0e;从给定的特征集合中选择出相关特征子集的过程&…

C++竞赛初阶L1-13-第五单元-循环嵌套(29~30课)535: T456454 数字统计

题目内容 请统计某个给定范围 [L,R] 的所有整数中&#xff0c;数字 2 出现的次数。 比如给定范围 [2,22]&#xff0c;数字 2 在数 2 中出现了 1 次&#xff0c;在数 12 中出现 1 次&#xff0c;在数 20 中出现 1 次&#xff0c;在数 21 中出现 1 次&#xff0c;在数 22 中出现…

【开发语言】编译型语言和解释性语言有啥区别?

作为一名从业多年的程序员,对于编译型语言和解释型语言之间的区别有着深入的理解。这两种类型的编程语言在将源代码转换成可执行代码的过程中采用了不同的机制,这导致了它们在执行效率、跨平台性、安全性以及开发效率等方面存在一些差异。 编译型语言(Compiled Languages)…

Java项目集成RocketMQ

文章目录 1.调整MQ的配置1.进入bin目录2.关闭broker和namesrv3.查看进程确认关闭4.编辑配置文件broker.conf&#xff0c;配置brokerIP15.开放端口109116.重新启动1.进入bin目录2.启动mqnamesrv和mqbroker1.启动 NameServer 并将输出重定向到 mqnamesrv.log2.**启动 Broker 并将…