当前位置: 首页 > news >正文

鸿蒙(API 12 Beta3版)【音视频解封装】 文件解析封装

开发者可以调用本模块的Native API接口,完成音视频解封装,即从比特流数据中取出音频、视频等媒体帧数据。

当前支持的数据输入类型有:远程连接(http协议、HLS协议)和文件描述符(fd)。

支持的解封装格式如下:

媒体格式封装格式码流格式
音视频mp4视频码流:AVC(H.264)、HEVC(H.265)音频码流:AAC、MPEG(MP3)、AudioVivid
音视频fmp4视频码流:AVC(H.264)、HEVC(H.265)音频码流:AAC、MPEG(MP3)、AudioVivid
音视频mkv视频码流:AVC(H.264)、HEVC(H.265)音频码流:AAC、MPEG(MP3)、OPUS
音视频mpeg-ts视频码流:AVC(H.264)、HEVC(H.265)音频码流:AAC、MPEG(MP3)、Audio Vivid
音视频flv视频码流:AVC(H.264)、HEVC(H.265)音频码流:AAC
音频m4a音频码流:AAC、AudioVivid
音频aac音频码流:AAC
音频mp3音频码流:MPEG(MP3)
音频ogg音频码流:OGG
音频flac音频码流:FLAC
音频wav音频码流:PCM
音频amr音频码流:AMR(AMR-NB、AMR-WB)
音频ape音频码流:APE
外挂字幕srt字幕流:SRT

适用场景

  • 播放

    播放媒体文件时,需要先对音视频流进行解封装,然后使用解封装获取的帧数据进行解码和播放。

  • 音视频编辑

    编辑媒体文件时,需要先对音视频流进行解封装,获取到指定帧进行编辑。

  • 媒体文件格式转换(转封装)

    媒体文件格式转换时,需要先对音视频流进行解封装,然后按需将音视频流封装至新的格式文件内。

开发指导

说明

  • 调用解封装能力解析网络播放路径,需要[声明权限]:ohos.permission.INTERNET
  • 调用解封装能力解析本地文件,需要[向用户申请授权]:ohos.permission.READ_MEDIA
  • 如果使用ResourceManager.getRawFd打开HAP资源文件描述符,使用方法请参考[ResourceManager API参考]

在 CMake 脚本中链接动态库

target_link_libraries(sample PUBLIC libnative_media_codecbase.so)
target_link_libraries(sample PUBLIC libnative_media_avdemuxer.so)
target_link_libraries(sample PUBLIC libnative_media_avsource.so)
target_link_libraries(sample PUBLIC libnative_media_core.so)

开发步骤

  1. 添加头文件。
#include <multimedia/player_framework/native_avdemuxer.h>
#include <multimedia/player_framework/native_avsource.h>
#include <multimedia/player_framework/native_avcodec_base.h>
#include <multimedia/player_framework/native_avformat.h>
#include <multimedia/player_framework/native_avbuffer.h>
#include <fcntl.h>
#include <sys/stat.h>
  1. 创建资源管理实例对象。
// 创建文件操作符 fd,打开时对文件句柄必须有读权限(filePath 为待解封装文件路径,需预置文件,保证路径指向的文件存在)
std::string filePath = "test.mp4";
int fd = open(filePath.c_str(), O_RDONLY);
struct stat fileStatus {};
size_t fileSize = 0;
if (stat(filePath.c_str(), &fileStatus) == 0) {fileSize = static_cast<size_t>(fileStatus.st_size);
} else {printf("get stat failed");return;
}
// 为 fd 资源文件创建 source 资源对象, 传入 offset 不为文件起始位置 或 size 不为文件大小时,可能会因不能获取完整数据导致 source 创建失败、或后续解封装失败等问题
OH_AVSource *source = OH_AVSource_CreateWithFD(fd, 0, fileSize);
if (source == nullptr) {printf("create source failed");return;
}
// 为 uri 资源文件创建 source 资源对象(可选)
// OH_AVSource *source = OH_AVSource_CreateWithURI(uri);// 为自定义数据源创建 source 资源对象(可选)。使用该方式前,需要先实现AVSourceReadAt接口函数实现。
// 当使用OH_AVSource_CreateWithDataSource时需要补充g_filePath
// g_filePath = filePath ;
// OH_AVDataSource dataSource = {fileSize, AVSourceReadAt};
// OH_AVSource *source = OH_AVSource_CreateWithDataSource(&dataSource);

AVSourceReadAt接口函数,需要放在创建资源管理实例对象前实现::

// 添加头文件
#include <fstream>
static std::string g_filePath;enum MediaDataSourceError : int32_t {SOURCE_ERROR_IO = -2,SOURCE_ERROR_EOF = -1
};int32_t AVSourceReadAt(OH_AVBuffer *data, int32_t length, int64_t pos)
{if (data == nullptr) {printf("AVSourceReadAt : data is nullptr!\n");return MediaDataSourceError::SOURCE_ERROR_IO;}std::ifstream infile(g_filePath, std::ofstream::binary);if (!infile.is_open()) {printf("AVSourceReadAt : open file failed! file:%s\n", g_filePath.c_str());return MediaDataSourceError::SOURCE_ERROR_IO;  // 打开文件失败}infile.seekg(0, std::ios::end);int64_t fileSize = infile.tellg();if (pos >= fileSize) {printf("AVSourceReadAt : pos over or equals file size!\n");return MediaDataSourceError::SOURCE_ERROR_EOF;  // pos已经是文件末尾位置,无法读取}if (pos + length > fileSize) {length = fileSize - pos;    // pos+length长度超过文件大小时,读取从pos到文件末尾的数据}infile.seekg(pos, std::ios::beg);if (length <= 0) {printf("AVSourceReadAt : raed length less than zero!\n");return MediaDataSourceError::SOURCE_ERROR_IO;}char* buffer = new char[length];infile.read(buffer, length);infile.close();memcpy(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(data)),buffer, length);delete[] buffer;return length;
}
  1. 创建解封装器实例对象。
// 为资源对象创建对应的解封装器
OH_AVDemuxer *demuxer = OH_AVDemuxer_CreateWithSource(source);
if (demuxer == nullptr) {printf("create demuxer failed");return;
}
  1. 注册[DRM信息监听函数](可选,若非DRM码流或已获得[DRM信息],可跳过此步)。

添加头文件

#include <multimedia/drm_framework/native_drm_common.h>

在 CMake 脚本中链接动态库

target_link_libraries(sample PUBLIC libnative_drm.so)

设置DRM信息监听的接口有两种,可根据需要选择。

使用示例一:

// DRM信息监听回调OnDrmInfoChanged实现
static void OnDrmInfoChanged(DRM_MediaKeySystemInfo *drmInfo)
{// 解析DRM信息,包括数量、DRM类型及对应pssh
}DRM_MediaKeySystemInfoCallback callback = &OnDrmInfoChanged;
Drm_ErrCode ret = OH_AVDemuxer_SetMediaKeySystemInfoCallback(demuxer, callback);

使用示例二:

// DRM信息监听回调OnDrmInfoChangedWithObj实现
static void OnDrmInfoChangedWithObj(OH_AVDemuxer *demuxer, DRM_MediaKeySystemInfo *drmInfo)
{// 解析DRM信息,包括数量、DRM类型及对应pssh
}Demuxer_MediaKeySystemInfoCallback callback = &OnDrmInfoChangedWithObj;
Drm_ErrCode ret = OH_AVDemuxer_SetDemuxerMediaKeySystemInfoCallback(demuxer, callback);

在监听到DRM信息后,也可主动调用获取DRM信息(uuid及对应pssh)接口。

DRM_MediaKeySystemInfo mediaKeySystemInfo;
OH_AVDemuxer_GetMediaKeySystemInfo(demuxer, &mediaKeySystemInfo);
  1. 获取文件轨道数(可选,若用户已知轨道信息,可跳过此步)。
// 从文件 source 信息获取文件轨道数,用户可通过该接口获取文件级别属性,具体支持信息参考附表 1
OH_AVFormat *sourceFormat = OH_AVSource_GetSourceFormat(source);
if (sourceFormat == nullptr) {printf("get source format failed");return;
}
int32_t trackCount = 0;
if (!OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &trackCount)) {printf("get track count from source format failed");return;
}
OH_AVFormat_Destroy(sourceFormat);
  1. 获取轨道index及信息(可选,若用户已知轨道信息,可跳过此步)。
uint32_t audioTrackIndex = 0;
uint32_t videoTrackIndex = 0;
int32_t w = 0;
int32_t h = 0;
int32_t trackType;
for (uint32_t index = 0; index < (static_cast<uint32_t>(trackCount)); index++) {// 获取轨道信息,用户可通过该接口获取对应轨道级别属性,具体支持信息参考附表 2OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index);if (trackFormat == nullptr) {printf("get track format failed");return;}if (!OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &trackType)) {printf("get track type from track format failed");return;}static_cast<OH_MediaType>(trackType) == OH_MediaType::MEDIA_TYPE_AUD ? audioTrackIndex = index : videoTrackIndex = index;// 获取视频轨宽高if (trackType == OH_MediaType::MEDIA_TYPE_VID) {if (!OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_WIDTH, &w)) {printf("get track width from track format failed");return;}if (!OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_HEIGHT, &h)) {printf("get track height from track format failed");return;}}OH_AVFormat_Destroy(trackFormat);
}
  1. 添加解封装轨道。
if(OH_AVDemuxer_SelectTrackByID(demuxer, audioTrackIndex) != AV_ERR_OK){printf("select audio track failed: %d", audioTrackIndex);return;
}
if(OH_AVDemuxer_SelectTrackByID(demuxer, videoTrackIndex) != AV_ERR_OK){printf("select video track failed: %d", videoTrackIndex);return;
}
// 取消选择轨道(可选)
// OH_AVDemuxer_UnselectTrackByID(demuxer, audioTrackIndex);
  1. 调整轨道到指定时间点(可选)。
// 调整轨道到指定时间点,后续从该时间点进行解封装
// 注意:
// 1. mpegts格式文件使用OH_AVDemuxer_SeekToTime功能时,跳转到的位置可能为非关键帧。可在跳转后调用OH_AVDemuxer_ReadSampleBuffer,通过获取到的OH_AVCodecBufferAttr判断当前帧是否为关键帧。若非关键帧影响应用侧显示等功能,可在跳转后循环读取,获取到后续第一帧关键帧后,再进行解码等处理。
// 2. ogg格式文件使用OH_AVDemuxer_SeekToTime功能时,会跳转到传入时间millisecond所在时间间隔(秒)的起始处,可能会导致一定数量的帧误差。
OH_AVDemuxer_SeekToTime(demuxer, 0, OH_AVSeekMode::SEEK_MODE_CLOSEST_SYNC);
  1. 开始解封装,循环获取帧数据(以含音频、视频两轨的文件为例)。
// 创建 buffer,用与保存用户解封装得到的数据
OH_AVBuffer *buffer = OH_AVBuffer_Create(w * h * 3 >> 1);
if (buffer == nullptr) {printf("build buffer failed");return;
}
OH_AVCodecBufferAttr info;
bool videoIsEnd = false;
bool audioIsEnd = false;
int32_t ret;
while (!audioIsEnd || !videoIsEnd) {// 在调用 OH_AVDemuxer_ReadSampleBuffer 接口获取数据前,需要先调用 OH_AVDemuxer_SelectTrackByID 选中需要获取数据的轨道// 获取音频帧数据if(!audioIsEnd) {ret = OH_AVDemuxer_ReadSampleBuffer(demuxer, audioTrackIndex, buffer);if (ret == AV_ERR_OK) {// 可通过 buffer 获取并处理音频帧数据OH_AVBuffer_GetBufferAttr(buffer, &info);printf("audio info.size: %d\n", info.size);if (info.flags == OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {audioIsEnd = true;}}}if(!videoIsEnd) {ret = OH_AVDemuxer_ReadSampleBuffer(demuxer, videoTrackIndex, buffer);if (ret == AV_ERR_OK) {// 可通过 buffer 获取并处理视频帧数据OH_AVBuffer_GetBufferAttr(buffer, &info);printf("video info.size: %d\n", info.size);if (info.flags == OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {videoIsEnd = true;}}}
}
OH_AVBuffer_Destroy(buffer);
  1. 销毁解封装实例。
// 需要用户调用 OH_AVSource_Destroy 接口成功后,手动将对象置为 NULL,对同一对象重复调用 OH_AVSource_Destroy 会导致程序错误
if (OH_AVSource_Destroy(source) != AV_ERR_OK) {printf("destroy source pointer error");
}
source = NULL;
// 需要用户调用 OH_AVDemuxer_Destroy 接口成功后,手动将对象置为 NULL,对同一对象重复调用 OH_AVDemuxer_Destroy 会导致程序错误
if (OH_AVDemuxer_Destroy(demuxer) != AV_ERR_OK) {printf("destroy demuxer pointer error");
}
demuxer = NULL;
close(fd);

附表

文件级别属性支持范围

说明

正常解析时才可以获取对应属性数据;如果文件信息错误或缺失,将导致解析异常,无法获取数据。

表1 文件级别属性支持范围

名称描述
OH_MD_KEY_TITLE文件标题的键
OH_MD_KEY_ARTIST文件艺术家的键
OH_MD_KEY_ALBUM文件专辑的键
OH_MD_KEY_ALBUM_ARTIST文件专辑艺术家的键
OH_MD_KEY_DATE文件日期的键
OH_MD_KEY_COMMENT文件注释的键
OH_MD_KEY_GENRE文件流派的键
OH_MD_KEY_COPYRIGHT文件版权的键
OH_MD_KEY_LANGUAGE文件语言的键
OH_MD_KEY_DESCRIPTION文件描述的键
OH_MD_KEY_LYRICS文件歌词的键
OH_MD_KEY_TRACK_COUNT文件轨道数量的键
OH_MD_KEY_DURATION文件时长的键
OH_MD_KEY_START_TIME文件起始时间的键

轨道级别属性支持范围

说明

正常解析时才可以获取对应属性数据;如果文件信息错误或缺失,将导致解析异常,无法获取数据。

表2 轨道级别属性支持范围

名称描述视频轨支持音频轨支持字幕轨支持
OH_MD_KEY_CODEC_MIME码流编解码器类型的键
OH_MD_KEY_TRACK_TYPE码流媒体类型的键
OH_MD_KEY_BITRATE码流比特率的键-
OH_MD_KEY_LANGUAGE码流语言类型的键-
OH_MD_KEY_CODEC_CONFIG编解码器特定数据的键,视频中表示传递xps,音频中表示传递extraData-
OH_MD_KEY_WIDTH视频流宽度的键--
OH_MD_KEY_HEIGHT视频流高度的键--
OH_MD_KEY_FRAME_RATE视频流帧率的键--
OH_MD_KEY_ROTATION视频流旋转角度的键--
OH_MD_KEY_VIDEO_SAR视频流样本长宽比的键--
OH_MD_KEY_PROFILE视频流编码档次,只针对 h265 码流使用--
OH_MD_KEY_RANGE_FLAG视频流视频YUV值域标志的键,只针对 h265 码流使用--
OH_MD_KEY_COLOR_PRIMARIES视频流视频色域的键,只针对 h265 码流使用--
OH_MD_KEY_TRANSFER_CHARACTERISTICS视频流视频传递函数的键,只针对 h265 码流使用--
OH_MD_KEY_MATRIX_COEFFICIENTS视频矩阵系数的键,只针对 h265 码流使用--
OH_MD_KEY_VIDEO_IS_HDR_VIVID视频流标记是否为 HDRVivid 的键,只针对 HDRVivid 码流使用--
OH_MD_KEY_AUD_SAMPLE_RATE音频流采样率的键--
OH_MD_KEY_AUD_CHANNEL_COUNT音频流通道数的键--
OH_MD_KEY_CHANNEL_LAYOUT音频流所需编码通道布局的键--
OH_MD_KEY_AUDIO_SAMPLE_FORMAT音频流样本格式的键--
OH_MD_KEY_AAC_IS_ADTSaac格式的键,只针对 aac 码流使用--
OH_MD_KEY_BITS_PER_CODED_SAMPLE音频流每个编码样本位数的键--

最后呢

很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造的《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

在这里插入图片描述

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细鸿蒙(OpenHarmony )手册(共计1236页)与鸿蒙(OpenHarmony )开发入门视频,帮助大家在技术的道路上更进一步。

  • 《鸿蒙 (OpenHarmony)开发学习视频》
  • 《鸿蒙生态应用开发V2.0白皮书》
  • 《鸿蒙 (OpenHarmony)开发基础到实战手册》
  • OpenHarmony北向、南向开发环境搭建
  • 《鸿蒙开发基础》
  • 《鸿蒙开发进阶》
  • 《鸿蒙开发实战》

在这里插入图片描述

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发。

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用。那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才。鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行! 自↓↓↓拿

相关文章:

鸿蒙(API 12 Beta3版)【音视频解封装】 文件解析封装

开发者可以调用本模块的Native API接口&#xff0c;完成音视频解封装&#xff0c;即从比特流数据中取出音频、视频等媒体帧数据。 当前支持的数据输入类型有&#xff1a;远程连接(http协议、HLS协议)和文件描述符(fd)。 支持的解封装格式如下&#xff1a; 媒体格式封装格式码…...

智能马桶盖和普通马桶盖有什么不同?

智能马桶盖与普通马桶盖之间存在显著的差异&#xff0c;主要体现在以下几个方面&#xff1a; 一、功能差异 1.清洗功能&#xff1a; 智能马桶盖&#xff1a;配备了清洗功能&#xff0c;包括臀洗、妇洗等&#xff0c;特别针对女性设计了贴心功能&#xff0c;如移动喷水、水流按…...

C# OnnxRuntime部署LivePortrait实现快速、高质量的人像驱动视频生成

目录 效果 说明 项目 模型信息 代码 下载 效果 LivePortrait实现快速、高质量的人像驱动视频生成 说明 官网地址&#xff1a;https://github.com/KwaiVGI/LivePortrait 代码实现参考&#xff1a;https://github.com/hpc203/liveportrait-onnxrun 模型下载&#xff1a;…...

Spring boot框架指南

1. Spring Boot 概述 1.1 定义与起源 Spring Boot是一种基于Spring框架的开源框架&#xff0c;旨在简化Spring应用程序的创建和开发过程。它通过提供一系列默认配置和自动配置功能&#xff0c;减少了开发者在配置上的工作量&#xff0c;使得快速搭建生产级别的Spring应用程序…...

数据结构--树与二叉树

数据结构分类 集合 线性结构(一对一) 树形结构(一对多) 图结构(多对多) 数据结构三要素 1、逻辑结构 2、数据的运算 3、存储结构&#xff08;物理结构&#xff09; 树的概念 树的分类 满二叉树和完全二叉树 二叉排序树 平衡二叉树 二叉树分类总结 二叉树的存储结构 …...

C#项目实战经验——计时方法总结

前言 我们在开发C#程序的过程中经常需要计算某段程序执行的时间&#xff0c;比如调用的某个算法的时间&#xff0c;这时候我们就需要利用计时工具&#xff0c;本文就是详细介绍在C#中我们常用哪些计时工具。 1、计时方法—StopWatch 在C#中我们可以利用Stopwatch这个类来实现…...

电子盖章软件哪个好|盖章软件

在选择电子盖章软件时&#xff0c;需要考虑多个因素&#xff0c;包括软件的功能、安全性、易用性、兼容性以及成本等。以下是根据当前市场情况推荐的一些优秀的电子盖章软件&#xff1a; e章宝&#xff1a; 功能丰富&#xff1a;e章宝是国内领先的电子盖章系统&#xff0c;功能…...

ThreejsWebGPU运动残影demo

功能点 实例化SkinnedMesh 修改NodeMaterial着色器 节点材质系统 shader 语言 使用uniform和attribute 中合其他几篇博客中的内容 代码仓库 克隆后需要放到three源码同级别目录下 运行 three源码部分不在git仓库中(太大了) 使用vscode的live-server启动后访问 http://127.0.0.…...

HttpSession常用方法

1.HttpSession常用方法 是在Java Servlet中用来管理会话状态的重要接口&#xff0c;它提供了一种在多个请求或页面之间存储用户特定信息的方式。以下是一些 HttpSession 常用的方法和用法&#xff1a; 获取会话对象&#xff1a; HttpSession session request.getSession();…...

【JavaEE初阶】文件操作和IO

目录 &#x1f334;认识文件 &#x1f6a9;树型结构组织和目录 &#x1f6a9;文件路径&#xff08;Path&#xff09; &#x1f6a9; 文件分类 &#x1f38d;Java 中操作文件 &#x1f6a9; File 概述&#xff1a; &#x1f4cc;属性 &#x1f4cc;构造方法 &#x1f4c…...

存储器芯片的基本原理

目录 1.存储元 1.1栅极电容 1.2双稳态触发器 2.存储单元 3.存储体 4.存储器 5.容量计算 6.寻址 1.存储元 1.1栅极电容 给MOS管一个阈值电压&#xff08;5v&#xff09;就能够导电&#xff0c;若是不给那么就是一个绝缘体不会导电。 读出二进制原理&#xff1a; 通常…...

前端实习手记(7):立秋快乐

这周相比上周感觉挺好的哈哈哈&#xff0c;可能只有自己感觉蛮好的&#xff0c;旁边师父忙的飞起了要&#xff0c;不仅赶工作还要回答我乱七八糟的问题&#xff08;心疼一秒&#xff09;。这周也是立秋&七夕咯&#xff0c;立秋快乐哇家人们&#xff08;虽然还是很热嘛&…...

感恩放下,笑对人生,在人生的长河中,每一天都是独特的篇章,或顺心如意,或充满挑战

在人生的长河中,每一天都是独特的篇章,或顺心如意,或充满挑战。然而,无论今日的经历如何,我们都应怀着感恩与放下的心态,因为人生的旅程远不止这短暂的一天,明天依然充满希望,等待我们继续努力前行。 生活,犹如一场变幻莫测的舞台剧,顺心之时,我们仿佛置身于温暖的…...

URLSession之初窥门径

NSURLSession 于 2013 年随 iOS 7 的发布一起面世&#xff0c;苹果将其定位为 NSURLConnection 的替代者。我们使用最广泛的第三方框架如 AFNetworking 和 SDWebImage 的最新版也都已经全面切换至 NSURLSession。 NSURLSession 不仅仅指代同名类 NSURLSession&#xff0c;它还…...

ios创建控制器的3种方法实现页面跳转

ios遵守mvc设计模式&#xff0c;下面介绍创建控制器viewcontroller的几种方法&#xff0c;来实现页面的跳转 1.纯代码创建 // // AppDelegate.m // study2024 // // Created by zhifei zhu on 2024/8/7. //#import "AppDelegate.h" #import "MyViewContro…...

Android逆向题解-boomshakalaka-3-难度5

这个app 是一个cocos游戏&#xff0c;没有用脚本实现&#xff0c;纯c实现。 题目描述:play the game, get the highest score 题目要求是玩游戏得到最高分就可以得到flag&#xff0c;是写到配置文件的&#xff0c;初始flag值看着是base编码的。 核心代码在so里面的ControlLay…...

Linux(Ubuntu 22.04)系统中固定串口

Linux&#xff08;Ubuntu 22.04&#xff09;系统中固定串口 文章目录 前言正文查看linux串口信息修改udev固化串口校验是否修改完成 注意 前言 在Linux系统中固定串口&#xff08;通常指的是串行通信接口&#xff0c;如/dev/ttyS0或/dev/ttyUSB0&#xff09;的原因有几个方面&…...

LeetCode - 209 - 长度最小的子数组

力扣209题 题目描述&#xff1a;长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 target 。 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl1, ..., numsr-1, numsr] &#xff0c;并返回其长度**。**如果不存在符合条件的子数组&…...

探索空间计算与VR中的手势跟踪新纪元:XHand框架详解

在虚拟现实(VR)和扩展现实(XR)技术日新月异的今天,手势跟踪作为实现沉浸式体验的关键技术之一,正逐步从概念走向成熟。今天,我们将深入探索一个创新的框架——XHand,它以其卓越的性能和先进的技术亮点,为空间计算与VR领域的手势跟踪带来了全新的解决方案。 XHand框架…...

leetcode + 项目复习

上午 Leetcode算法 参考文章——代码随想录 1. KMP 概念 主要应用 字符串匹配 主要思想 根据之前匹配的信息&#xff0c;当发现字符串不匹配时&#xff0c;避免从头开始匹配。 什么是前缀表&#xff08;next数组、prefix&#xff09; 是用来回退的&#xff0c;当文本串和…...

树莓派4/5:设置apt、pip、conda首选清华镜像源

一、教程简介 在中国大陆地区&#xff0c;使用清华镜像源可以显著缩短资源下载时间。 本教程介绍如何将清华镜像源设置为树莓派的apt、pip、conda下载的首选项&#xff08;默认项&#xff09;。其中&#xff0c;apt和pip为树莓派系统自带&#xff0c;conda则需要安装miniforg…...

NoSQL 之Redis集群模式

目录 案例概述 redis工作模式 主从模式 哨兵模式 redis cluster模式 Redis集群介绍 Redis集群的优势 Redis集群的实现方法 Redis-Cluster数据分片 Redis-Cluster的主从复制模型 Redis集群部署 案例部署 安装redis 检查redis的状态 修改配置文件 重启启动redis服…...

oracle rac

1、app连接oracle rac集群 连接到 Oracle RAC&#xff08;Real Application Clusters&#xff09;的多种配置方式 1. 使用 JDBC 连接字符串&#xff1a; 使用 JDBC 连接字符串是连接 Oracle RAC 的常见方式。连接字符串的格式如下&#xff1a; jdbc:oracle:thin:(DESCRIPTION…...

计算机毕业设计Python深度学习房价预测 房价可视化 链家爬虫 房源爬虫 房源可视化 卷积神经网络 大数据毕业设计 机器学习 人工智能 AI

Python深度学习房价预测系统开题报告 一、研究背景与意义 随着城市化进程的加速和房地产市场的不断发展&#xff0c;房价成为影响人们生活质量的重要因素之一。准确预测房价不仅有助于政府制定科学的房地产政策&#xff0c;还能为开发商提供市场参考&#xff0c;同时帮助购房…...

【Linux】学习Linux,需要借助具象化的思维

指令与图形化界面 导读一、命令行与图形化界面二、命令行与图形化界面的发展历程1.2.1 打字机的起源1.2.2 肖尔斯和格利登型打字机1.2.3 鼠标的发明1.2.4 图形化界面&#xff08;GUI&#xff09;的发展 三、命令行与图形化之间的联系3.1 图形化界面的人机交互3.2 命令行界面的人…...

R语言贝叶斯方法在生态环境领域技术教程

原文链接&#xff1a;R语言贝叶斯方法在生态环境领域技术教程https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247612056&idx5&snb170122cf5052cc7cb2d858606b9f158&chksmfa82777fcdf5fe69eec092410530e2900c98bcbb84e3d33c823705c948b4db96545bf282747a…...

mojo实现高阶函数(algorithm)

functional 实现高阶函数。 您可以从 algorithm 包导入这些 API。例如: from algorithm import map别名: ​Static1DTileUnitFunc = fn[Int](Int, /) capturing -> None: Signature of a 1d tiled function that performs some work with a static tile size and an off…...

先进制造aps专题二十四 云平台排产aps的方案设计

云平台排产aps的方案设计 针对对象是有排产需求无需定制的中小型工厂企业 一 网站功能&#xff08;b/s架构&#xff09; 1 前端界面 客户登录 排产项目管理 基础数据&#xff08;产品资料&#xff0c;产品工艺&#xff0c;工作日历&#xff0c;生产资源&#xff0c;工艺能力…...

JavaScript 逆向技巧总结

本节属于知识总结&#xff0c;只是对思路的梳理&#xff0c;不对具体内容进行展开 JS 逆向可以分为三大部分&#xff1a; 寻找入口&#xff0c; 调试分析&#xff0c; 模拟执行 寻找入口&#xff1a; 这是非常关键的一步&#xff0c;逆向在大部分情况下就是找一些加密参数到底…...

linux反向代理原理:帮助用户更好地优化网络架构

Linux反向代理原理详解 反向代理是一种在网络架构中常用的技术&#xff0c;尤其在Linux环境下被广泛应用。它可以帮助实现负载均衡、安全防护和请求缓存等功能。本文将深入探讨Linux反向代理的原理、工作机制以及其应用场景。 1. 什么是反向代理 反向代理是指代理服务器接收客…...