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

平台网站建设协议建立网站的基本流程有哪些步骤

平台网站建设协议,建立网站的基本流程有哪些步骤,wordpress 女装小说,如何提高网站百度权重往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录) ✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~ ✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~ ✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景&#…

往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)

✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~

✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~

✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

✏️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

✏️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

✏️ 记录一场鸿蒙开发岗位面试经历~

✏️ 持续更新中……


1:场景描述

场景:基于VideoCoder的音视频解码及二次处理播放。

首先导入选择器picker模块,使用PhotoViewPicker方法拉起图库选择视频文件,将视频文件传递到native侧使用Demuxer解封装器进行解封装,再使用OH_VideoDecoder进行解码(surface模式)送显播放

使用的核心API:

  • picker :提供拉起图库选择视频的功能接口。
  • AVDemuxer :音视频解封装,用于获取视频等媒体帧数据。
  • VideoDecoder:视频解码,将视频数据解码后送显播放。

2:方案描述

Step1:导入picker模块(仅代表选择一个视频路径,还有其它获取媒体文件的方式), 拉起图库选择视频文件保存到自定义路径。

Step2:将文件传递到native侧进行交互。

Step3:使用AVDemuxer接口对文件进行解封装获取视频流数据。

Step4:使用VideoDecoder接口将视频数据解码,结合Xcomponent送显播放。

效果图如下:

具体步骤如下:

步骤一:导入picker模块, 拉起图库选择视频文件自定义保存。

import { picker } from '@kit.CoreFileKit';
let photoSelectOptions = new picker.PhotoSelectOptions();
photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.VIDEO_TYPE;
photoSelectOptions.maxSelectNumber = 1;
let photoPicker = new picker.PhotoViewPicker();
photoPicker.select(photoSelectOptions).then((PhotoSelectResult: picker.PhotoSelectResult) => {hilog.info(0x0000, TAG, 'PhotoViewPicker.select successfully, PhotoSelectResult uri: ' + JSON.stringify(PhotoSelectResult));this.selectFilePath = PhotoSelectResult.photoUris[0];hilog.info(0x0000, TAG, 'Get selectFilePath successfully: ' + JSON.stringify(this.selectFilePath));
}).catch((err: BusinessError) => {hilog.error(0x0000, TAG, 'PhotoViewPicker.select failed with err: ' + JSON.stringify(err));
})
}

步骤二:将文件传递到native侧进行交互。

import player from 'libplayer.so';
export const playNative: (inputFileFd: number,inputFileOffset: number,inputFileSize: number,cbFn: () => void
) => void;
static napi_value Init(napi_env env, napi_value exports) {napi_property_descriptor classProp[] = {{"playNative", nullptr, Play, nullptr, nullptr, nullptr, napi_default, nullptr},
};
napi_value PlayerNative = nullptr;
const char *classBindName = "playerNative";
napi_define_class(env, classBindName, strlen(classBindName), nullptr, nullptr, 1, classProp, &PlayerNative);
PluginManager::GetInstance()->Export(env, exports);
napi_define_properties(env, exports, sizeof(classProp) / sizeof(classProp[0]), classProp);
return exports;
}

步骤三:使用Demuxer接口对文件进行解封装获取视频流数据。

Step1:创建解封装器,传入媒体文件格式信息。

int32_t Demuxer::CreateDemuxer(SampleInfo &info) {source = OH_AVSource_CreateWithFD(info.inputFd, info.inputFileOffset, info.inputFileSize);demuxer = OH_AVDemuxer_CreateWithSource(source);auto sourceFormat = std::shared_ptr<OH_AVFormat>(OH_AVSource_GetSourceFormat(source), OH_AVFormat_Destroy);int32_t ret = GetTrackInfo(sourceFormat, info);return AV_ERR_OK;
}

Step2:添加解封装轨道,获取文件轨道信息。

int32_t Demuxer::GetTrackInfo(std::shared_ptr<OH_AVFormat> sourceFormat, SampleInfo &info) {int32_t trackCount = 0;OH_AVFormat_GetIntValue(sourceFormat.get(), OH_MD_KEY_TRACK_COUNT, &trackCount);for (int32_t index = 0; index < trackCount; index++) {int trackType = -1;auto trackFormat = std::shared_ptr<OH_AVFormat>(OH_AVSource_GetTrackFormat(source, index), OH_AVFormat_Destroy);OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_TRACK_TYPE, &trackType);if (trackType == MEDIA_TYPE_VID) {OH_AVDemuxer_SelectTrackByID(demuxer, index);OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_WIDTH, &info.videoWidth);OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_HEIGHT, &info.videoHeight);OH_AVFormat_GetDoubleValue(trackFormat.get(), OH_MD_KEY_FRAME_RATE, &info.frameRate);OH_AVFormat_GetLongValue(trackFormat.get(), OH_MD_KEY_BITRATE, &info.bitrate);OH_AVFormat_GetIntValue(trackFormat.get(), "video_is_hdr_vivid", &info.isHDRVivid);OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_ROTATION, &info.rotation);char *codecMime;OH_AVFormat_GetStringValue(trackFormat.get(), OH_MD_KEY_CODEC_MIME, const_cast<char const **>(&codecMime));info.codecMime = codecMime;OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_PROFILE, &info.hevcProfile);videoTrackId_ = index;OH_LOG_ERROR(LOG_APP, "Demuxer config: %{public}d*%{public}d, %{public}.1ffps, %{public}ld" "kbps",info.videoWidth, info.videoHeight, info.frameRate, info.bitrate / 1024);}}return AV_ERR_OK;
}

Step3:开始解封装,循环获取视频帧数据。

int32_t Demuxer::ReadSample(OH_AVBuffer *buffer, OH_AVCodecBufferAttr &attr) {int32_t ret = OH_AVDemuxer_ReadSampleBuffer(demuxer, videoTrackId_, buffer);ret = OH_AVBuffer_GetBufferAttr(buffer, &attr);return AV_ERR_OK;
}

解封装支持的文件格式:

步骤四:使用VideoDecoder接口将视频数据解码,结合Xcomponent送显播放。

Step1:将解封装后的数据送去解码器进行解码

void Player::DecInputThread() {while (true) {std::unique_lock<std::mutex> lock(signal->inputMutex_);bool condRet = signal->inputCond_.wait_for(lock, 5s, [this]() { return !isStarted_ || !signal->inputBufferInfoQueue_.empty(); });if (!isStarted_) {OH_LOG_ERROR(LOG_APP, "Work done, thread out");break;}if (signal->inputBufferInfoQueue_.empty()) {OH_LOG_ERROR(LOG_APP, "Buffer queue is empty, continue, cond ret: %{public}d", condRet);}CodecBufferInfo bufferInfo = signal->inputBufferInfoQueue_.front();signal->inputBufferInfoQueue_.pop();signal->inputFrameCount_++;lock.unlock();demuxer_->ReadSample(reinterpret_cast<OH_AVBuffer *>(bufferInfo.buffer), bufferInfo.attr);int32_t ret = videoDecoder_->PushInputData(bufferInfo);
}
StartRelease();
}

Step2:获取解码后的数据

void Player::DecOutputThread() {sampleInfo_.frameInterval = MICROSECOND / sampleInfo_.frameRate;while (true) {thread_local auto lastPushTime = std::chrono::system_clock::now();if (!isStarted_) {OH_LOG_ERROR(LOG_APP, "Decoder output thread out");break;}std::unique_lock<std::mutex> lock(signal->outputMutex_);bool condRet = signal->outputCond_.wait_for(lock, 5s, [this]() { return !isStarted_ || !signal->outputBufferInfoQueue_.empty(); });if (!isStarted_) {OH_LOG_ERROR(LOG_APP, "Decoder output thread out");break;}if (signal->outputBufferInfoQueue_.empty()) {OH_LOG_ERROR(LOG_APP, "Buffer queue is empty, continue, cond ret: %{public}d", condRet);}CodecBufferInfo bufferInfo = signal->outputBufferInfoQueue_.front();signal->outputBufferInfoQueue_.pop();if (bufferInfo.attr.flags & AVCODEC_BUFFER_FLAGS_EOS) {OH_LOG_ERROR(LOG_APP, "Catch EOS, thread out");break;}signal->outputFrameCount_++;OH_LOG_ERROR(LOG_APP, "Out buffer count: %{public}u, size: %{public}d, flag: %{public}u, pts: %{public}ld",signal->outputFrameCount_, bufferInfo.attr.size, bufferInfo.attr.flags, bufferInfo.attr.pts);lock.unlock();int32_t ret = videoDecoder_->FreeOutputData(bufferInfo.bufferIndex, true);if (ret != AV_ERR_OK) {OH_LOG_ERROR(LOG_APP, "Decoder output thread out");break;}std::this_thread::sleep_until(lastPushTime + std::chrono::microseconds(sampleInfo_.frameInterval));lastPushTime = std::chrono::system_clock::now();
}
OH_LOG_ERROR(LOG_APP, "Exit, frame count: %{public}u", signal->outputFrameCount_);
StartRelease();
}

Step3:使用OH_VideoDecoder_SetSurface设置surface数据和window绑定

int32_t VideoDecoder::Config(const SampleInfo &sampleInfo, VDecSignal *signal) {// Configure video decoderint32_t ret = ConfigureVideoDecoder(sampleInfo);// SetSurface from video decoderif (sampleInfo.window != nullptr) {int ret = OH_VideoDecoder_SetSurface(decoder, sampleInfo.window);if (ret != AV_ERR_OK || sampleInfo.window == nullptr) {OH_LOG_ERROR(LOG_APP, "Set surface failed, ret: %{public}d", ret);return AV_ERR_UNKNOWN;}}// SetCallback for video decoderret = SetCallback(signal);if (ret != AV_ERR_OK) {OH_LOG_ERROR(LOG_APP, "Set callback failed, ret: %{public}d", ret);return AV_ERR_UNKNOWN;}// Prepare video decoder{int ret = OH_VideoDecoder_Prepare(decoder);if (ret != AV_ERR_OK) {OH_LOG_ERROR(LOG_APP, "Prepare failed, ret: %{public}d", ret);return AV_ERR_UNKNOWN;}}return AV_ERR_OK;
}

Step4: native层获取 NativeXComponent

void PluginManager::Export(napi_env env, napi_value exports) {napi_value exportInstance = nullptr;if (napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "PluginManager", "Export: napi_get_named_property fail");return;}OH_NativeXComponent *nativeXComponent = nullptr;if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "PluginManager", "Export: napi_unwrap fail");return;}char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "PluginManager", "Export: OH_NativeXComponent_GetXComponentId fail");return;}std::string id(idStr);auto context = PluginManager::GetInstance();if ((context != nullptr) && (nativeXComponent != nullptr)) {context->SetNativeXComponent(id, nativeXComponent);auto render = context->GetRender(id);OH_NativeXComponent_RegisterCallback(nativeXComponent, &PluginRender::m_callback);}
}

step5:通过回调将window渲染播放

void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "Callback", "OnSurfaceCreatedCB");auto context = PluginManager::GetInstance();context->m_window = (OHNativeWindow *)window;
}
http://www.dtcms.com/wzjs/835345.html

相关文章:

  • 广告发布包括哪些关于seo关键词选择有哪些方法
  • 网站 内容 营销沧州网站推广优化
  • 有域名怎么做公司网站wordpress 4.1分页
  • 什么是自适应网站优化步骤
  • 网站腾讯备案吗国家信息公示系统官网
  • 旅游论坛网站建设网站建设的目的与意义是什么意思
  • 个人域名备案做企业网站最新国际军事新闻
  • 网站建设的客户在哪里定制系统软件开发
  • 个人网站建设方案模板建站工具哪个好用
  • 仿做网站要多少钱seo优化包括哪些内容
  • 成都flash互动网站开发免费链接转换短网址
  • 正规的企业网站建设公司深圳西乡建网站
  • 做销售的 都有什么网站一个人可以建设几个网站
  • 网站运营团队管理广州广告公司
  • 书写网站建设策划书wordpress 内页打不开
  • 南京地区网站开发房产网名字叫啥好听
  • 学校网站怎么做的好处wordpress有中文版没
  • 深圳建站网站网站公司天津网站开发价格
  • 有没有做家具特卖的网站网站网站建设网站
  • 佛山做外贸网站如何怎么开店
  • 上海创意型网站建设姑苏区住房和建设局网站
  • 网站浮动窗口怎么设置国际网站怎么做
  • 爱墙 网站怎么做网站用模板为什么不利于seo推广
  • 网站开发用什么软件用手机做网站的流程
  • 厦门做网站的公司有哪些网站建设刂搜金手指下拉贰肆
  • 淘客建站程序wordpress怎么做
  • 鲜花网站建设的总体目标网站集群建设要求
  • 阿里云二级域名建设网站友情链接的英文
  • 海南网站制做的公司龙岗 营销型网站建设
  • 怎么做网站快捷方式产品宣传网站的重点