Генерация видео из обработанных изображений вместе со звуком
Я следовал этому примеру http://nezarobot.blogspot.com/2016/03/android-surfacetexture-camera2-opencv.html, чтобы обработать кадры перед отправкой их в предварительный просмотр.
Это делается путем отправки Image
а также Surface
в нативную функцию, где выполняется обработка.
Я также успешно записал поток изображений в видео, используя openCV
а также VideoWriter
,
К сожалению, единственный формат .avi
и я хотел бы иметь .mp4
, Кроме того, я также хочу аудио в созданном видео.
У меня есть этот код для обработки и записи в видео:
extern "C"
JNIEXPORT void JNICALL
Java_com_erikbylow_mycamera3_JNIUtils_drawCircle(
JNIEnv *env, jobject type, jint srcWidth, jint srcHeight, jobject srcBuf, jobject dstSurface,
jstring path_, jint saveFile) {
uint8_t *srcLumaPtr = reinterpret_cast<uint8_t *>(env->GetDirectBufferAddress(srcBuf));
if (srcLumaPtr == nullptr){
LOGE("blit NULL pointer Error");
}
int dstWidth;
int dstHeight;
cv::Mat mYuv(srcHeight + srcHeight / 2, srcWidth, CV_8UC1, srcLumaPtr);
uint8_t*srcChromaUVInterleavedptr = nullptr;
bool swapDstUV;
ANativeWindow *win = ANativeWindow_fromSurface(env, dstSurface);
ANativeWindow_Buffer buf;
dstWidth = srcHeight;
dstHeight = srcWidth;
ANativeWindow_setBuffersGeometry(win, dstWidth, dstHeight, 0);
if (int32_t err = ANativeWindow_lock(win, &buf, NULL)){
LOGE("ANativeWindow_lock failed with error code %d\n", err);
ANativeWindow_release(win);
}
uint8_t *dstLumaPtr = reinterpret_cast<uint8_t*>(buf.bits);
cv::Mat dstRgba(dstHeight, buf.stride, CV_8UC4, dstLumaPtr);
cv::Mat srcRgba(srcHeight, srcWidth, CV_8UC4);
cv::Mat flipRgba(dstHeight, dstWidth, CV_8UC4);
// Convert YUV to RGBA
cv::cvtColor(mYuv, srcRgba, CV_YUV2RGBA_NV21);
// Rotate 90 degree
// cv::transpose(srcRgba, flipRgba);
cv::flip(srcRgba, flipRgba, 1);
cv::flip(flipRgba, flipRgba, 0);
// flipRgba = srcRgba;
// LaneDetect(flipRgba, str, savefile, outStr);
// Copy to TextureView surface
uchar *dbuf;
uchar *sbuf;
dbuf = dstRgba.data;
sbuf = flipRgba.data;
LOGE("buf.height: %d", buf.height);
LOGE("buf.width: %d", buf.width);
LOGE("buf.stride: %d", buf.stride);
LOGE("flipRgba.cols %d", flipRgba.cols);
for (int i = 0; i < flipRgba.rows; i++){
dbuf = dstRgba.data + i * buf.stride*4;
memcpy(dbuf, sbuf, buf.stride*4); // Is this one row at a time?
sbuf += flipRgba.cols * 4;
}
cv::Point p1(100,100);
int radius = 10;
cv::circle(flipRgba, p1, radius, cv::Scalar(255,255,255), CV_FILLED);
cv::circle(dstRgba, p1, radius, cv::Scalar(255,255,255), CV_FILLED);
mWriter.write(flipRgba);
ANativeWindow_unlockAndPost(win);
ANativeWindow_release(win);
}
Как будет лучшим способом продолжить? Собирается для ffmpeg
или собственные Android MediaCodec
? У меня уже есть кадры как Mat
файлы так было бы неплохо, если бы можно было просто продолжить с этого. В том числе со звуком.