【FFmpeg】解封装 ① ( 封装与解封装流程 | 解封装函数简介 | 查找码流标号和码流参数信息 | 使用 MediaInfo 分析视频文件 )
文章目录
- 一、解封装
- 1、封装与解封装流程
- 2、解封装 常用函数
- 二、解封装函数简介
- 1、avformat_alloc_context 函数
- 2、avformat_free_context 函数
- 3、avformat_open_input 函数
- 4、avformat_close_input 函数
- 5、avformat_find_stream_info 函数
- 6、av_read_frame 函数
- 7、avformat_seek_file 函数
- 8、av_seek_frame 函数
- 三、查找码流标号和参数信息
- 1、码流标号
- 2、查找码流标号 - av_find_best_stream 函数
- 3、查找码流参数信息 - avformat_find_stream_info 函数
- 4、查找码流参数信息延迟分析
- 四、视频文件解封装示例
- 1、使用 MediaInfo 分析视频文件
- 2、使用 MediaInfo 分析视频文件的每个字节的信息
FFmpeg 4.0 版本源码地址 :
- GitHub : https://github.com/FFmpeg/FFmpeg/tree/release/4.0
- GitCode : https://gitcode.com/gh_mirrors/ff/FFmpeg/tree/release/4.0
- FFmpeg/libavcodec/avpacket.c 源码 : https://gitcode.com/gh_mirrors/ff/FFmpeg/blob/release/4.0/libavcodec/avpacket.c
一、解封装
1、封装与解封装流程
" 封装 " 是 将 音频流 / 视频流 / 字幕流 等多媒体流 , 按照一定的规则 组合成 特定格式的 视频文件 ;
- 封装 主要是由 " 复用器 " 完成的 ;
- 封装示例 : 将 AAC 格式的 音频流 和 H.264 格式的 视频流 封装成一个 .mp4 文件 ;
" 解封装 " 是 将 特定格式的 视频文件 , 按照一定的规则 拆分成 音频流 / 视频流 / 字幕流 等多媒体流 ;
- 解封装 主要是由 " 解复用器 " 完成的 ;
- 解封装示例 : 将 .mp4 文件 拆分成 AAC 格式的 音频流 和 H.264 格式的 视频流 ;
2、解封装 常用函数
解封装 常用函数 简介 :
- avformat_alloc_context 函数 : 用于 申请 AVFormatContext 结构体内存 , 并 对 结构体的字段 进行简单初始化操作 ;
- avformat_free_context 函数 : 释放 AVFormatContext 结构体 及其 关联的资源 ;
- avformat_open_input 函数 : 使用 解复用器 打开 视频文件 / 媒体流 ;
- avformat_close_input 函数 : 关闭 解复用器 ;
- avformat_find_stream_info 函数 : 获取 媒体流信息 ;
- av_read_frame 函数 : 读取 媒体流 中的 AVPacket 数据包 ;
- avformat_seek_file 函数 : 根据 时间戳 跨多个流 定位文件 中的位置 ;
- av_seek_frame 函数 : 根据 时间戳 跳转到指定流的指定位置 ;
二、解封装函数简介
下面的 解封装 函数 可 参考 【FFmpeg】FFmpeg 函数简介 ② ( 封装格式相关函数解析 | 封装格式与解复用器 | avformat_alloc_context 函数 | avformat_open_input函数 ) 博客 ;
解封装流程如下 :
1、avformat_alloc_context 函数
avformat_alloc_context 函数原型 :
AVFormatContext *avformat_alloc_context(void);
- 函数作用 : 该函数用于 分配并初始化一个 AVFormatContext 结构体 ;
- 函数参数 : 函数参数为空 ;
- 函数返回值 : 函数 返回一个 AVFormatContext 指针 , 指向分配的结构体 ; 如果分配失败 , 则返回 NULL ;
AVFormatContext 结构体 用于 存储 文件格式相关信息 , 其中包括文件中 各个媒体流 的参数信息 ;
2、avformat_free_context 函数
avformat_free_context 函数 用于 释放 AVFormatContext 结构体 以及相关的资源 , 包括 流信息 / IO 资源 / 解码器 / 格式上下文 等数据 ,
avformat_free_context 函数原型如下 :
void avformat_free_context(AVFormatContext *s);
avformat_free_context 函数 与 avformat_alloc_context 函数 一般都要成对使用 , 防止内存泄漏 ;
如果 之前调用过 avformat_alloc_context 函数 , 则必须调用 avformat_free_context 函数 释放内存 ;
如果 之前没有调用过 avformat_alloc_context 函数 , 则不必调用 avformat_free_context 函数 ;
3、avformat_open_input 函数
avformat_open_input 函数 使用 " 解复用器 " 打开 视频文件 , 该函数 在内部会调用 avformat_alloc_context 函数 用于为 AVFormatContext 结构体分配内存 ;
avformat_open_input 函数原型如下 :
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);
- 函数参数 :
- AVFormatContext **ps : 指向 AVFormatContext 指针的指针 ;
- const char *url : 输入流的地址或文件名 , 文件路径 或 网络流的 URL ;
- AVInputFormat *fmt : 设置输入格式 , 一般都是 NULL , FFmpeg 自动选择输入格式 ;
- AVDictionary **options : 附加参数 , 设置解码器 , 网络连接 等参数 ;
- 函数返回值 : 关闭成功 返回 0 , 关闭失败 返回 负值错误码 ;
注意 : avformat_open_input 函数 要与 avformat_close_input 函数 成对使用 ;
4、avformat_close_input 函数
avformat_close_input 函数 用于 关闭 " 解复用器 " , 该函数 在内部会调用 avformat_free_context 函数 ;
avformat_close_input 函数原型如下 :
int avformat_close_input(AVFormatContext **ps);
- 函数参数 : 其中的参数 ps 是 指向 AVFormatContext 指针的指针 ;
- 函数返回值 : 关闭成功 返回 0 , 关闭失败 返回 负值错误码 ;
注意 : avformat_open_input 函数 要与 avformat_close_input 函数 成对使用 ;
5、avformat_find_stream_info 函数
avformat_find_stream_info 函数 用于获取 媒体流 信息 ;
一般情况下 , 调用 avformat_open_input 函数 就可以获取到 视频文件的 媒体流信息 ;
如果调用 avformat_open_input 函数 无法获取 媒体流信息 , 此时 需要 开发者 手动调用 avformat_find_stream_info 函数 用于获取媒体流信息 ;
函数原型如下 :
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
- 函数参数 :
- AVFormatContext *ic : 指向 AVFormatContext 的指针 ;
- AVDictionary **options : 可选附加参数 , 设置解码器 , 网络连接 等参数 ;
- 函数返回值 : 关闭成功 返回 0 , 关闭失败 返回 负值错误码 ;
6、av_read_frame 函数
av_read_frame 函数 用于 读取 音视频流 中的 数据包 , 这是压缩后的数据 , 不能直接播放 , 需要经过解码后才能播放 ;
AAC 格式的 音频流 数据包 , 需要转为 PCM 格式 才能播放 ;
H.264 格式的 视频流 数据包 , 需要转为 YUV 或 RGB 格式 才能播放 ;
av_read_frame 函数 原型 :
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
- 函数参数 :
- AVFormatContext *s : 指向 AVFormatContext 的指针 , 这是已经打开的 多媒体流 的格式上下文 ;
- AVPacket *pkt : 指向 AVPacket 的指针 , 用于存储读取的 一帧 音视频数据 ;
- 函数返回值 : 关闭成功 返回 0 , 关闭失败 返回 负值错误码 ;
7、avformat_seek_file 函数
avformat_seek_file 函数 参考 【FFmpeg】FFmpeg 函数简介 ② ( 封装格式相关函数解析 | 封装格式与解复用器 | avformat_alloc_context 函数 | avformat_open_input函数 ) 一、FFmpeg 音视频文件 封装格式相关函数 8、avformat_seek_file 函数 博客章节 ;
8、av_seek_frame 函数
av_seek_frame 函数 参考 【FFmpeg】FFmpeg 函数简介 ② ( 封装格式相关函数解析 | 封装格式与解复用器 | avformat_alloc_context 函数 | avformat_open_input函数 ) 一、FFmpeg 音视频文件 封装格式相关函数 9、av_seek_frame 函数 博客章节 ;
avformat_seek_file 函数 与 av_seek_frame 函数 对比 :
- 跳转粒度 :
- avformat_seek_file : 支持 视频文件 跨多个媒体流 定位跳转 到 指定时间戳 , 并且 可以控制最小、最大时间戳范围 ;
- av_seek_frame : 跳转到 特定流 的 指定时间戳 ;
- 跳转控制 :
- avformat_seek_file : 可以 精细控制时间戳范围 , 设置最小时间戳和最大时间戳 ;
- av_seek_frame : 跳转到关键帧 , 灵活性较低 ;
- 常用场景 :
- avformat_seek_file : 适用于 跨多个媒体流 的文件 的 精准跳转 ;
- av_seek_frame : 适用于 单个媒体流操作 , 通常用于快速定位到 视频流、音频流 或 字幕流 的 关键帧 ;
三、查找码流标号和参数信息
1、码流标号
在 FFmpeg 中 , 每个 多媒体文件 可能 包含 多个多媒体流 , 如 : 视频流、音频流、字幕流 等 ;
这些 媒体流都 会 被分配 一个 唯一的索引号 来标识 , 称为 " Stream index " , 用于区分文件中的不同流 ;
上述 流索引号 可以称为 " 码流标号 " , 从 0 开始进行递增编号 , 其中 标号为 0 的码流 可能是 视频流 / 音频流 / 字幕流 ;
2、查找码流标号 - av_find_best_stream 函数
av_find_best_stream 函数 用于查找 媒体文件 中的 最佳流 ;
int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type, int wanted_stream, int related_stream, AVCodec **decoder_ret, int flags);
- 函数参数 :
- AVFormatContext *ic : 指向已打开媒体文件的 AVFormatContext 结构体的指针 , 其中封装了 媒体信息 包括 流的数量 以及 每个流的详细信息 ;
- enum AVMediaType type : 要查找的 媒体流的类型 , 可选的媒体流类型如下 :
- AVMEDIA_TYPE_VIDEO : 视频流类型 ;
- AVMEDIA_TYPE_AUDIO : 音频流类型 ;
- AVMEDIA_TYPE_DATA : 数据流类型 ;
- AVMEDIA_TYPE_SUBTITLE : 字幕流类型 ;
- AVMEDIA_TYPE_UNKNOWN : 未知类型 ;
- AVMEDIA_TYPE_ATTACHMENT : 附件类型 ;
- int wanted_stream : 用户期望的流索引 , 默认设置 -1 ;
- int related_stream : 与之相关的最佳流的索引 , 默认设置 -1 ;
- AVCodec **decoder_ret : 指向找到的流的对应解码器 , 默认设置 NULL ;
- int flags : 指定额外的查找选项 , 默认设置 0 ;
- 函数返回值 : 查找成功返回流索引 , 查找失败返回 AVERROR_STREAM_NOT_FOUND 或 错误码 ;
查找视频流示例 :
int video_index = av_find_best_stream(ic, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0)
查找音频流示例 :
int audio_index = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0)
3、查找码流参数信息 - avformat_find_stream_info 函数
视频文件 在 播放前 , 必须要进行解码 , 解码的前提就是要知道 文件中的如下信息 :
- 媒体流数量
- 媒体流类型 : 视频流、音频流、字幕流 等 ;
- 每个流的详细信息 : 编码格式、比特率、分辨率 等 ;
获取到这些信息后 , 都设置到 AVFormatContext 结构体中 ;
avformat_open_input 函数 在 打开 输入媒体文件 后 , 会读取 文件的头部信息 , 函数执行过程中会 初始化 AVFormatContext 结构体 , 并将读取到的文件流信息填充到该结构体中 ;
有些类型的文件 , 如 : FLV 文件 / H.264 文件 / 网络直播流 , 文件的 头部信息 中并没有完整的流信息 , 甚至就没有头部信息 ;
此时就需要 调用 avformat_find_stream_info 函数 , 获取每个媒体流的完整流信息 , 包括流的 编码参数、比特率、分辨率 等信息 ;
avformat_find_stream_info 函数 可以 在 信息缺失的情况下 , 通过分析 数据包 格式 , 探测并分析 流 的 缺失参数信息 ;
4、查找码流参数信息延迟分析
avformat_find_stream_info 函数会尝试读取足够的数据 , 来确定每个流的参数 , 如 : 编解码器、比特率、采样率 等 ;
读取数据 , 分析数据 , 然后获取流的参数信息 , 这个过程 需要花费一定的时间 , 这就会造成延迟 , 设置的 读取数据越多 , 造成的延迟越大 ;
开发者 通过 AVFormatContext 相关结构设置的一些参数 , 设置 avformat_find_stream_info 函数 读取数据的多少 ;
四、视频文件解封装示例
视频文件 封装在 文件容器中 , 将容器中的数据提取出来 , 就是解封装过程 ;
在本章节中 使用 MediaInfo 分析视频文件 提取视频文件的信息 , 之后在下一篇博客中自己编写代码提取视频文件中的数据 , 并在 输出日志 中展示出来 ;
1、使用 MediaInfo 分析视频文件
MediaInfo 软件 可 用于 提取 视频文件 的 技术信息和元数据 , 支持多种格式和编码 , 可以快速显示文件的详细信息 ;
下面我们使用 MediaInfo 软件 分析 mp4 格式的 视频文件 ;
MediaInfo 软件 默认显示的 文件内容细节是 Details - 0 级别 , 在 " 菜单栏 / 调试 " 选项中可以查看当前的 调试级别 ;
在 Details - 0 调试级别下 , 只能看到 文件的 容器格式 一般信息 , 有几个文件流 , 每个文件流都是什么格式的 , 具体的文件流的内容是无法看到的 ;
下图就是 mp4 文件的 Details - 0 调试级别 显示的文件的容器信息 , 很简略 ;
2、使用 MediaInfo 分析视频文件的每个字节的信息
在 " 菜单栏 / 调试 " 选项中 , 设置 调试级别为 Details - 10 级别 , 这样就可以分析文件中每个字节的信息 ;
此时再打开上个章节中的 mp4 文件 , 就会显示如下信息 , MediaInfo 会将文件的每个字节的数据都解析出来 , 同时将每个字节的含义也展出出来 ;
相关文章:

【FFmpeg】解封装 ① ( 封装与解封装流程 | 解封装函数简介 | 查找码流标号和码流参数信息 | 使用 MediaInfo 分析视频文件 )
文章目录 一、解封装1、封装与解封装流程2、解封装 常用函数 二、解封装函数简介1、avformat_alloc_context 函数2、avformat_free_context 函数3、avformat_open_input 函数4、avformat_close_input 函数5、avformat_find_stream_info 函数6、av_read_frame 函数7、avformat_s…...

Spring Boot 集成 MyBatis 全面讲解
Spring Boot 集成 MyBatis 全面讲解 MyBatis 是一款优秀的持久层框架,与 Spring Boot 集成后可以大大简化开发流程。本文将全面讲解如何在 Spring Boot 中集成 MyBatis,包括环境配置、基础操作、高级功能和最佳实践。 一、MyBatis 简介 1. SqlSession …...

C语言小练习-打印字母倒三角
编写一个程序,在用户输入某个大写字母后,产生一个金字塔图案。 #include <stdio.h>int main(int argc,char *argv[]) {char ch; loop:printf("请输入大写字母!\n");scanf("%c",&ch);getchar();if(ch < A ||…...

Linux -- 线程控制相关的函数
目录 pthread_create -- 创建线程 参数 返回值 代码 -- 不传 args: 编译时带 -lpthread 运行结果 为什么输出混杂? 如何证明两个线程属于同一个进程? 如何证明是两个执行流? 什么是LWP? 代码 -- 传 args&a…...

基于quasar,只选择年度与月份的组件
为什么要做 quasar是个基于vue的强大的UI开发库,它提供了非常多的组件,比如日期选择。但是有些时候只需要选择到月份就可以了,quasar中没有,所以自己动手写了一个。因为对界面编程我不熟悉,所以,如果你有更…...

健康养生:拥抱生活的艺术
健康养生:拥抱生活的艺术 在快节奏的现代生活中,健康已成为我们最宝贵的财富。健康养生,不仅仅是一种生活方式的选择,更是一种对待生活的态度,它关乎于如何在日常中寻找到平衡,让身心得以滋养,…...

注意力机制+时空特征融合!组合模型集成学习预测!LSTM-Attention-Adaboost多变量时序预测
注意力机制时空特征融合!组合模型集成学习预测!LSTM-Attention-Adaboost多变量时序预测 目录 注意力机制时空特征融合!组合模型集成学习预测!LSTM-Attention-Adaboost多变量时序预测效果一览基本介绍程序设计参考资料 效果一览 基…...

uniapp 微信小程序 均分数据展示
效果图 数据展示,可自行搭配 html <view class"num-wrapper"><view class"num-item" click.stop"routerGo(跳转的地址)"><text class"num">¥{{ 要展示的数据 || 0}}</text><view…...

Nacos 3.0 考虑升级到 Spring Boot 3 + JDK 17 了!
Nacos 由阿里开源,是 Spring Cloud Alibaba 中的一个重要组件,主要用于发现、配置和管理微服务。 由于 Spring Boot 2 的维护已于近期停止,Nacos 团队考虑升级到 Spring Boot 3 JDK 17,目前正在征求意见和建议。 这其实是一件好…...

跟沐神学读论文-论文阅读管理
摘要 近期有读论文的需求,就需要去了解一下论文到底要怎么读,同一个系列之间的论文如何作整理和归纳,之前也有了解过市面上有成熟的论文阅读工具,但是对于学生党来讲没什么性价比,在B站上看到沐神有讲解他的思路Typor…...

Python 参数配置使用 XML 文件的教程 || Python打包 || 模型部署
当配置项存储在外部文件(如 XML、JSON)时,修改配置无需重新编译和发布代码。通过更新 XML 文件即可调整参数,无需更改源代码,从而提升开发效率和代码可维护性。 1. 为什么选择 XML 配置文件 XML 配置文件具有多种优点…...

[SV]如何在UVM环境中使用C Model
在UVM环境中使用C Memory 一、C语言实现Memory 1.1 代码说明 Memory 初始化: memory_init() 函数将内存空间初始化为 0,并初始化互斥锁。AXI 写操作 (axi_write): 检查地址范围是否合法。使用 memcpy 将数据从输入缓冲区写入模拟内存。使用互斥锁保证线程安全。AXI 读操作 …...

十大开源的Cursor AI替代方案
随着AI的兴起,所使用的工具也在不断进步。Cursor AI 作为一个强大的编码助手,已经成为开发人员不可或缺的工具。开源替代方案提供了透明性、个性化和成本效益。本文深入探讨了Cursor AI 的十大开源替代方案,这些方案将丰富您的编码体验&#…...

相机光学(四十六)——镜头马达(VCM)控制策略模式
One Step Mode、Linear Slope Control(LSC)和Acceleration Control是三种不同的控制模式,它们在控制策略和应用场景上有所区别。这些控制模式在VCM中的应用是为了提高其性能,减少振动,加快响应速度,并提高定…...

专业140+总分410+浙江大学842信号系统与数字电路考研经验浙大电子信息与通信工程,真题,大纲,参考书。
考研落幕,本人本中游211,如愿以偿考入浙江大学,专业课842信号系统与数字电路140,总分410,和考前多次模考预期差距不大(建议大家平时做好定期模考测试,直接从实战分数中,找到复习的脉…...

了解ARM的千兆以太网——RK3588
1. 简介 本文并不重点讲解调试内容,重点了解以太网在ARM设计中的框架以及在设备树以及驱动的一个整体框架。了解作为一个驱动开发人员当拿到一款未开发过的ARM板卡应该怎么去把网卡配置使用起来。 2. 基础知识介绍 在嵌入式ARM中实现以太网的解决方案通常有以下两种…...

JavaFX使用jfoenix的UI控件
jfoenix还是一个不错的样式,推荐使用,而且也可以支持scene builder中的拖拖拽拽 需要注意的是过高的javafx版本可能会使得某些样式或控件无法使用 比如alert控件,亲测javaFX 19版本可以正常使用 1.在pom.xml中引入依赖 GitHub地址https://gi…...

Linux(Ubuntu)命令大全——已分类整理,学习、查看更加方便直观!(2024年最新编制)
Hello! 认真好学的小伙伴们,大家好呀(Respect~)!我是 H u a z z i Huazzi Huazzi,欢迎观看本篇博客,接下来让我们一起来学习 Ubuntu命令大全 吧!祝你有所收获! 文章目录 前言&#x…...

单片机:实现教学上下课的自动打玲(附带源码)
单片机实现教学上下课的自动打铃 在学校或其他教育机构中,定时的打铃系统被广泛应用,用于提醒学生和老师上下课的时间。一个简单的自动打铃系统可以通过单片机实现,结合蜂鸣器和定时器控制,可以在设定的时间点自动打铃࿰…...

进程通信方式---共享映射区(无血缘关系用的)
5.共享映射区(无血缘关系用的) 文章目录 5.共享映射区(无血缘关系用的)1.概述2.mmap&&munmap函数3.mmap注意事项4.mmap实现进程通信父子进程练习 无血缘关系 5.mmap匿名映射区 1.概述 原理:共享映射区是将文件…...

深度学习实战智能交通计数
本文采用YOLOv8作为核心算法框架,结合PyQt5构建用户界面,使用Python3进行开发。YOLOv8以其高效的实时检测能力,在多个目标检测任务中展现出卓越性能。本研究针对车辆目标数据集进行训练和优化,该数据集包含丰富的车辆目标图像样本…...

【MySQL】MySQL表的操作
【MySQL】MySQL表的操作 🥕个人主页:开敲🍉 🔥所属专栏:MySQL🍋 🌼文章目录🌼 1. 创建表 2. 查看表结构 3. 修改表 4. 删除表 1. 创建表 create table table_name(表名称)( fiel…...

Redis篇-12--数据结构篇4--Hash内存模型(数组,链表,压缩列表zipList,哈希表,短结构)
Redis的Hash数据结构用于存储键值对(key-value形式)的集合(类似java中HashMap或对象)。为了在保证高效性能的同时节省内存,Redis对Hash的底层实现进行了多种优化。特别是通过使用压缩列表(ziplistÿ…...

二、windows环境下vscode使用wsl教程
本篇文件介绍了在windows系统使用vscode如何连接使用wsl,方便wsl在vscode进行开发。 1、插件安装 双击桌面vscode,按快捷键CtrlShiftX打开插件市场,搜索【WSL】点击安装即可。 2、开启WSL的linux子系统 点击左下方图标【Open a Remote Win…...

Qwen2-VL微调体验
1.配置环境 2.数据集准备 3.模型下载 4.注册SwanLab 5.微调 6.训练过程可视化 1.配置环境 本博客使用的是2B模型,所以仅用了单卡3090,若大一点的模型,自行根据实际情况准备显卡 安装Python>3.8 安装Qwen2-VL必要的库 pip install…...

论文的模拟环境和实验环境
模拟环境和实验环境 在撰写SCI计算机领域论文时,模拟环境和实验环境是两个重要的概念,它们之间存在显著的差异。 模拟环境主要是利用计算机、数学方法等手段对实际系统进行描述和分析的过程。在计算机科学中,模拟环境可以用于模拟各种算法、系统或网络的行为,以便在不需要…...

MySQL EXPLAIN 详解:一眼看懂查询计划
在日常的数据库开发中,我们经常需要分析 SQL 查询性能,而 EXPLAIN 是 MySQL 提供的利器,可以帮我们快速理解查询计划,优化慢查询。本文将详细解析 EXPLAIN 的输出字段及其含义,并结合实际案例分享优化思路。 一、什么是…...

自动呼入机器人如何与人工客服进行无缝切换?
自动呼入机器人如何与人工客服进行无缝切换? 原作者:开源呼叫中心FreeIPCC,其Github:https://github.com/lihaiya/freeipcc 自动呼入机器人与人工客服的无缝切换详解 自动呼入机器人与人工客服之间的无缝切换是确保客户体验连续…...
二分类模型的性能评价指标
1. 混淆矩阵 (Confusion Matrix) 预测正类预测负类实际正类 (P)True Positive (TP)False Negative (FN)实际负类 (N)False Positive (FP)True Negative (TN) True Positive (TP): 模型正确预测为正类的样本数。True Negative (TN): 模型正确预测为负类的样本数。False Positi…...

鸿蒙操作系统简介
华为鸿蒙系统(HUAWEI HarmonyOS),是华为公司于2019年8月9日在东莞举行的华为开发者大会(HDC.2019)上正式发布的面向全场景的分布式操作系统,可以创造一个超级虚拟终端互联的世界,将人、设备、场…...