HarmonyOS鸿蒙Next中MJPEG网络视频流如何进行实时处理
HarmonyOS鸿蒙Next中MJPEG网络视频流如何进行实时处理 文档显示自API22开始,视频解码器已经可以支持解码MJPEG格式的码流,那么具体如何处理接收到的网络MJPEG视频流进行播放呢,需要对接收到的数据进行手动分帧处理吗?考虑实时性的话是不是需要直接在Native层进行,而且希望加上录制功能,所以解码出的图像数据还需要复制一份送入编码器,请指点一下可以怎么完成。
开发者您好,需要对接收到的数据进行手动分帧处理,解码可以使用buffer模式,将解码器的输出结果重新编码,开发者麻烦请详细描述下你们的使用场景,为什么需要解码后再编码?按照伙伴描述这种情况应该算转码,不算录屏。
更多关于HarmonyOS鸿蒙Next中MJPEG网络视频流如何进行实时处理的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
开发者您好,图像渲染的话,开发者可以参考这个文档:https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/graphics/native-window-guidelines.md;还有就是关于视频流的接收,在ArkTS层接收数据,传递到Native层,性能方面不会有太大差异,如果担心,也可以就把接收数据也放到native侧。
很喜欢HarmonyOS的卡片式设计,信息一目了然,操作也更便捷。
是这样的,因为我最主要的目的就是把接收到的视频流录制几十秒下来,需要播放功能主要是为了掌握录制的时机,可以实时预览到画面。buffer模式的话我需要自己处理图像的渲染,我能得到surfuceId,但是不知道如何渲染,我应该怎么得到XComponent的渲染缓冲区提交渲染任务呢?
还有就是关于视频流的接收,我目前是在ArkTS层接收数据,传递到Native层,这样实时性能满足吗,您有什么建议?
下面是我分帧的处理方式,请问这个帧格式有没有什么问题?
void MjpegProcessor::ParseFromBuffer(std::vector<uint8_t>& buffer) {
const std::vector<uint8_t> SOI = {0xFF, 0xD8};
const std::vector<uint8_t> EOI = {0xFF, 0xD9};
size_t offset = 0;
while (true) {
// 查找 SOI
size_t start = FindPattern(buffer, offset, SOI);
if (start == std::string::npos) {
// 没有 SOI,丢弃整个缓冲区
buffer.clear();
return;
}
// 查找 EOI
size_t end = FindPattern(buffer, start + 2, EOI);
if (end == std::string::npos) {
// 只有 SOI 没有 EOI,保留从 SOI 开始的数据,丢弃之前的部分
if (start > 0) {
buffer.erase(buffer.begin(), buffer.begin() + start);
}
// 等待更多数据
return;
}
// 找到完整帧
size_t frameLen = (end - start) + 2; // 包含 EOI
auto frameData = std::make_shared<std::vector<uint8_t>>(
buffer.begin() + start,
buffer.begin() + start + frameLen
);
int64_t pts = GetCurrentTimestamp();
// 放入帧队列
{
std::lock_guard<std::mutex> lock(frameQueueMutex_);
frameQueue_.push({std::move(frameData), pts});
}
frameQueueCV_.notify_one();
// 更新偏移,继续下一帧
offset = start + frameLen;
}
// 移除已处理的数据(从开头到 offset)
if (offset > 0) {
buffer.erase(buffer.begin(), buffer.begin() + offset);
}
}
在HarmonyOS Next中,可使用@ohos.multimedia.media的AVDecoder解码MJPEG帧数据,通过createAVDecoder创建MJPEG解码器,逐帧送入bufQueue。解码后输出到OH_NativeBuffer或PixelMap,再通过ImageComponent或XComponent进行渲染。利用@ohos.net.http拉流,解析边界标记后提交帧。推荐使用XComponent+NativeWindow实现低延迟实时显示。
在HarmonyOS Next中处理MJPEG网络视频流
核心流程可分三步走。首先,需要从网络流中手动解析JPEG帧边界,因为MJPEG本质是连续的JPEG图像,通常依靠0xFF 0xD8和0xFF 0xD9字节标记来分帧。然后,将每一帧完整的JPEG数据直接喂给视频解码器。
考虑到实时录制需求,推荐在Native层(C/C++)使用NDK接口完成全流程,以避免多次数据拷贝的开销。
处理流程如下:
- 接收与分帧:在Native层通过网络接收数据,按JPEG帧头尾标记分离出单帧数据。
- 解码:创建MJPEG解码器,将已分帧数据通过
OH_VideoDecoder_PushInputBuffer送入。从OH_VideoDecoder_FreeOutputBuffer的回调中获取解码后的OH_NativeWindowBuffer。 - 录制与渲染:实现关键在于数据复用而非拷贝。先利用解码输出的
OH_NativeWindowBuffer进行画面渲染。然后,为编码器创建一个编码输入surface,通过OH_VideoEncoder_GetSurface获取,将之前同一块OH_NativeWindowBuffer直接送入编码器surface进行录制编码。这样解码和编码共享同一内存,无需二次拷贝图像数据,能有效保障低延迟。

