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

网站制作怎么学产品设计招聘网站

网站制作怎么学,产品设计招聘网站,做网站前端的软件,商城网站开发 多少钱鸿蒙 next 即将发布#xff0c;让我们先喊3遍 遥遥领先~ 遥遥领先~ 遥遥领先~ 作为一门新的系统#xff0c;本人也是刚入门学习中#xff0c;如果对于一些理解有问题的#xff0c;欢迎即使指出哈 首先这里要讲一下#xff0c;在鸿蒙 next 中#xff0c;要实现摄像头预览…鸿蒙 next 即将发布让我们先喊3遍 遥遥领先~ 遥遥领先~ 遥遥领先~ 作为一门新的系统本人也是刚入门学习中如果对于一些理解有问题的欢迎即使指出哈 首先这里要讲一下在鸿蒙 next 中要实现摄像头预览编码有两种方式。第一种通过摄像头的预览流录制流来实现其中预览很简单直接使用 xcomponent 即可对于编码则可以通过创建编码器获取到的 surfaceid 传递给录制流即可。第二种是通过 nativeimage 类似于 android 的 surfacetexture 然后将纹理通过 opengl 绘制到预览 surface 和编码 surface 上去这边文章主要将第一种简单的方式步骤大致如下 第一步创建 xcomponaent代码如下 XComponent({id: ,type: XComponentType.SURFACE,libraryname: ,controller: this.XcomponentController}).onLoad(() {this.XcomponentController.setXComponentSurfaceSize({surfaceWidth: this.cameraWidth, surfaceHeight: this.cameraHeight})this.XcomponentSurfaceId this.XcomponentController.getXComponentSurfaceId()}) 创建 xcomponeant 的关键是获取 surfaceid这个后面会用来传给摄像头预览流用的。 第二步获取编码器的 surfaceid由于目前鸿蒙没有为编码器这块提供 arkts 接口所以需要用到 napi 作为中间桥接通过 arkts 来调用 c 代码大致代码如下 arkts 部分 import recorder from librecorder.so recorder.initNative() librecorder.so 为工程中 c 的部分具体可以参考项目模板中关于 c 的示例 napi 部分 #include RecorderNative.h #include bits/alltypes.h#undef LOG_DOMAIN #undef LOG_TAG #define LOG_DOMAIN 0xFF00 #define LOG_TAG recorderstruct AsyncCallbackInfo {napi_env env;napi_async_work asyncWork;napi_deferred deferred;int32_t resultCode 0;std::string surfaceId ;SampleInfo sampleInfo; };void DealCallBack(napi_env env, void *data) {AsyncCallbackInfo *asyncCallbackInfo static_castAsyncCallbackInfo *(data);napi_value code;napi_create_int32(env, asyncCallbackInfo-resultCode, code);napi_value surfaceId;napi_create_string_utf8(env, asyncCallbackInfo-surfaceId.data(), NAPI_AUTO_LENGTH, surfaceId);napi_value obj;napi_create_object(env, obj);napi_set_named_property(env, obj, code, code);napi_set_named_property(env, obj, surfaceId, surfaceId);napi_resolve_deferred(asyncCallbackInfo-env, asyncCallbackInfo-deferred, obj);napi_delete_async_work(env, asyncCallbackInfo-asyncWork);delete asyncCallbackInfo; }void SetCallBackResult(AsyncCallbackInfo *asyncCallbackInfo, int32_t code) {asyncCallbackInfo-resultCode code; }void SurfaceIdCallBack(AsyncCallbackInfo *asyncCallbackInfo, std::string surfaceId) {asyncCallbackInfo-surfaceId surfaceId; }void NativeInit(napi_env env, void *data) {AsyncCallbackInfo *asyncCallbackInfo static_castAsyncCallbackInfo *(data);int32_t ret Recorder::GetInstance().Init(asyncCallbackInfo-sampleInfo);if (ret ! AVCODEC_SAMPLE_ERR_OK) {SetCallBackResult(asyncCallbackInfo, -1);}uint64_t id 0;ret OH_NativeWindow_GetSurfaceId(asyncCallbackInfo-sampleInfo.window, id);if (ret ! AVCODEC_SAMPLE_ERR_OK) {SetCallBackResult(asyncCallbackInfo, -1);}asyncCallbackInfo-surfaceId std::to_string(id);SurfaceIdCallBack(asyncCallbackInfo, asyncCallbackInfo-surfaceId); }napi_value RecorderNative::Init(napi_env env, napi_callback_info info) {SampleInfo sampleInfo;napi_value promise;napi_deferred deferred;napi_create_promise(env, deferred, promise);AsyncCallbackInfo *asyncCallbackInfo new AsyncCallbackInfo();asyncCallbackInfo-env env;asyncCallbackInfo-asyncWork nullptr;asyncCallbackInfo-deferred deferred;asyncCallbackInfo-resultCode -1;asyncCallbackInfo-sampleInfo sampleInfo;napi_value resourceName;napi_create_string_latin1(env, recorder, NAPI_AUTO_LENGTH, resourceName);napi_create_async_work(env, nullptr, resourceName, [](napi_env env, void *data) { NativeInit(env, data); },[](napi_env env, napi_status status, void *data) { DealCallBack(env, data); }, (void *)asyncCallbackInfo,asyncCallbackInfo-asyncWork);napi_queue_async_work(env, asyncCallbackInfo-asyncWork);return promise; }EXTERN_C_START static napi_value Init(napi_env env, napi_value exports) {napi_property_descriptor classProp[] {{initNative, nullptr, RecorderNative::Init, nullptr, nullptr, nullptr, napi_default, nullptr}};return exports; } EXTERN_C_ENDstatic napi_module RecorderModule {.nm_version 1,.nm_flags 0,.nm_filename nullptr,.nm_register_func Init,.nm_modname recorder,.nm_priv ((void *)0),.reserved {0}, };extern C __attribute__((constructor)) void RegisterRecorderModule(void) { napi_module_register(RecorderModule); }鸿蒙这边的 napi 其实是参考的 nodejs 的语法基本一致这里的大致逻辑就是调用 Recorder::GetInstance().Init() 获取编码器的 surfaceid 然后通过 ts 的 promise 传递给前端 c 编码器部分 int32_t Recorder::Init(SampleInfo sampleInfo) {std::lock_guardstd::mutex lock(mutex_);sampleInfo_ sampleInfo;videoEncoder_ std::make_uniqueVideoEncoder();muxer_ std::make_uniqueMuxer();videoEncoder_-Create(sampleInfo_.videoCodecMime);ret muxer_-Create(sampleInfo_.outputFd);encContext_ new CodecUserData;videoEncoder_-Config(sampleInfo_, encContext_);muxer_-Config(sampleInfo_);sampleInfo.window sampleInfo_.window;releaseThread_ nullptr;return AVCODEC_SAMPLE_ERR_OK; } 其中核心的在于 videoEncoder_-Config()这一步会将 nativewindow 赋值给 sampleInfo 结构体然后就可以获取到nativewindow 的 surfaceid了 代码如下 int32_t VideoEncoder::Config(SampleInfo sampleInfo, CodecUserData *codecUserData) {Configure(sampleInfo);OH_VideoEncoder_GetSurface(encoder_, sampleInfo.window);SetCallback(codecUserData);OH_VideoEncoder_Prepare(encoder_)return AVCODEC_SAMPLE_ERR_OK; } 到此为止xcomponents 的 surfaceid 和编码器的 surtfaceid 都获取到了接着就是在 arkts 层创建摄像头并设置预览编码输出了这块比较简单照着文档来就行代码如下 let cameraManager camera.getCameraManager(globalThis.context) let camerasDevices: Arraycamera.CameraDevice getCameraDevices(cameraManager) let profiles: camera.CameraOutputCapability cameraManager.getSupportedOutputCapability(camerasDevices[0],camera.SceneMode.NORMAL_VIDEO)// 获取预览流profilelet previewProfiles: Arraycamera.Profile profiles.previewProfiles// 获取录像流profilelet videoProfiles: Arraycamera.VideoProfile profiles.videoProfiles// Xcomponent预览流let XComponentPreviewProfile: camera.Profile previewProfiles[0]// 创建 编码器 输出对象encoderVideoOutput cameraManager.createVideoOutput(videoProfile, encoderSurfaceId)// 创建 预览流 输出对象XcomponentPreviewOutput cameraManager.createPreviewOutput(XComponentPreviewProfile, this.XcomponentSurfaceId)// 创建cameraInput对象cameraInput cameraManager.createCameraInput(camerasDevices[0])// 打开相机await cameraInput.open()// 会话流程videoSession cameraManager.createSession(camera.SceneMode.NORMAL_VIDEO) as camera.VideoSession// 开始配置会话videoSession.beginConfig()// 把CameraInput加入到会话videoSession.addInput(cameraInput)// 把 Xcomponent 预览流加入到会话videoSession.addOutput(XcomponentPreviewOutput)// 把编码器录像流加入到会话videoSession.addOutput(encoderVideoOutput)// 提交配置信息await videoSession.commitConfig()// 会话开始await videoSession.start() 至此关于预览编码的大致流程就是这样了整体流程其实还是很简单的核心就是获取两个 surfaceid然后传入到摄像头录制预览流中即可。这里就大致讲一下思路相信做安卓或者前端的同学都能看明白。不过这种模式的一个缺点在于无法做一些深层次的操作例如水印、美白、瘦脸等优点在于代码量比较少。第二篇要将的是关于如何通过 opengl 来绘制预览 编码 surface未完待续~
http://www.w-s-a.com/news/230756/

相关文章:

  • 福州专业网站制作公司金湖建设局网站
  • 好的移动端网站模板下载兰州线上广告推广
  • 宁波高端建站深圳品牌营销策划机构
  • 权威网站优化价格建设厅科技中心网站首页
  • 保定模板建站软件腾讯云做淘客网站
  • 单位建设一个网站的费用正规刷手机单做任务网站
  • 北京定制网站价格开网店怎么卖到外国
  • 做网站 后端是谁来做的工程建设指挥部网站
  • wordpress建站 云打印昆明 网站设计
  • 太原网站建设设计网站建设策划书(建设前的市场分析)
  • 哪里有制作网站电商新手入门知识
  • 制作网站的后台文昌网站建设 myvodo
  • 网站 购买移动网站制作
  • 南京网站网站建设学校英山做网站多少钱
  • 珠海网站建设网如何注册公司公众号
  • 手机网站页面制作网站怎么做快照
  • asp网站怎么仿站推广软件下载平台
  • 电子商务网站建设期末试题08答案互联网怎么做
  • 规范门户网站的建设和管理办法微信网站开发公司电话
  • 免费行情网站凡客的官网
  • 做网站运营的女生多吗海淀企业网站建设
  • 网站运行环境配置网站建设个一般需要花费多少钱
  • 广西平台网站建设报价wordpress 免费 企业 主题
  • 四川省建设厅职称查询网站辽宁省住房和城乡建设部网站
  • 公司网站后台登陆网站放到云服务器上怎么做
  • 济南 网站定制做网站购买域名
  • 代理分佣后台网站开发怎么用源码做网站视频
  • 天津网站建设招标wordpress七牛图片插件
  • 建设合同施工合同示范文本汕头市网络优化推广平台
  • 网站关键词修改老王搜索引擎入口