javaCV Android,流式传输到rtmp服务器时覆盖上的奇怪颜色
Posted
技术标签:
【中文标题】javaCV Android,流式传输到rtmp服务器时覆盖上的奇怪颜色【英文标题】:javaCV Android, Strange colors on overlay while streaming to rtmp server 【发布时间】:2017-01-21 14:19:13 【问题描述】:我想从 android 直播到 facebook。我能够将现有示例改编为流式传输到 FB。
第一步或多或少有效(音频仍然是一个问题,但不在她的范围内)。我可以直播到 FB。
我现在想用透明的 png 图像覆盖流。
我在启动时创建了一个 FFmpegFrameFilter:
try
filter = new FFmpegFrameFilter("movie="+path+"/image.png [logo];[in][logo]overlay=0:0:format=rgb [out]",imageWidth, imageHeight);
filter.start();
catch (FrameFilter.Exception e)
Log.e(CLASS_LABEL,"Error while starting filter: "+e.getMessage());
e.printStackTrace();
并且在每一帧上我都执行以下操作:
filter.push(yuvImage);
Frame frame;
while ((frame = filter.pull()) != null)
recorder.record(frame,avutil.AV_PIX_FMT_NV21);
问题是我不知道应该使用哪种像素格式。 我的叠加图像具有 rgb 颜色 (https://postimg.org/image/f1ri3vj43/)
使用上面的像素格式,我得到如下内容:https://postimg.org/image/45ha64q9z/
我很沮丧,因为我已经尝试了许多像素格式。都有不同的输出,有时徽标会出现多次。
有没有办法找出我应该从 avutil.java 的可能性中选择哪一个?
编辑:你可以在https://github.com/y4nnick/android_streaming/blob/master/app/src/main/java/com/example/yannick/olay1/RecordActivity.java找到整个代码
编辑:我已经尝试过以下格式:
// AV_PIX_FMT_ARGB --> 4 at once, all black/white
// AV_PIX_FMT_0RGB --> 4 at once, all black/white
// AV_PIX_FMT_BGR8 --> 1 a bit to big, strange colors
// AV_PIX_FMT_BGR4_BYTE --> 1 a bit to big, stranger blue tint
// AV_PIX_FMT_YUVA422P_LIBAV --> error: Cannot initialize the conversion context.
// AV_PIX_FMT_FLAG_ALPHA --> error: Cannot initialize the conversion context.
// AV_PIX_FMT_FLAG_PLANAR --> error: Cannot initialize the conversion context.
// AV_PIX_FMT_RGB4 --> error: Cannot initialize the conversion context.
// AV_PIX_FMT_RGB32_1 --> 4 at a time, all black/white
// AV_PIX_FMT_0BGR --> 4 at a time, all black/white
// AV_PIX_FMT_YVYU422 --> 2 side by side, gruen, purple tint
// AV_PIX_FMT_YUVJ422P --> Fatal signal 11 (SIGSEGV) at 0x61f7xf000 (code=1), thread 18401 (e.yannick.olay1)
// AV_PIX_FMT_BAYER_BGGR8 --> 1 a bit to big, black/white
// AV_PIX_FMT_BAYER_GBRG8 --> 1 a bit to big, black/white
// AV_PIX_FMT_FLAG_RGB --> 2 a bit to big, black/white
// AV_PIX_FMT_RGB555LE --> 2 a bit to big, strange colors
// AV_PIX_FMT_RGB555BE --> 2 a bit to big, strange colors
// AV_PIX_FMT_RGB555 --> 2 a bit to big, strange colors
// AV_PIX_FMT_RGB4_BYTE --> 1 a bit to big, orange tint
// AV_PIX_FMT_RGBA64 --> 8 side by side, black/white
// AV_PIX_FMT_RGB24 --> 3 side by side, red tint
【问题讨论】:
由于您在过滤器上指定了“format=rgb [out]”,因此您提取的帧可能是 RGB24,所以我会尝试使用 AV_PIX_FMT_RGB24 而不是 AV_PIX_FMT_NV21。 感谢您的帮助。不幸的是,我将徽标与红色并排显示了三遍。 postimg.org/image/he7rq0pev. 使用 AV_PIX_FMT_BGR24 我得到这个:postimg.org/image/bf08l4egh。颜色是现在,但我得到了三个标志,原来的 camview 是黑色/白色。是不是我必须更改 Frame 上的通道号,或者 FFmpegFrameRecorder 上的像素格式? 覆盖过滤器可能不适用于该 YUV 格式,因此您可能需要在应用徽标之前将图像转换为 RGB... 感谢您的提示。我将相机预览格式更改为 YV12,并将滤镜的输出更改为 YUV420。 【参考方案1】:我想通了:
通过运行找出你的安卓相机支持哪些格式
mCamera = Camera.open();
Camera.Parameters params = mCamera.getParameters();
for(int i: params.getSupportedPreviewFormats())
Log.e(TAG, "preview format supported are = "+i);
您将获得一个整数列表。在我的情况下是 17 和 842094169。 我会选择 842094169 (YV12)。所以通过调用来设置你的相机
mCamera.getParameters().setPreviewFormat(ImageFormat.YV12);
转到https://developer.android.com/reference/android/graphics/ImageFormat.html 并检查您支持的格式是如何准确定义的。
842094169 是YV12 is a 4:2:0 YCrCb planar format comprised of a WxH Y plane followed by (W/2) x (H/2) Cr and Cb planes.
转到https://ffmpeg.org/ffmpeg-filters.html#overlay-1 并检查您喜欢使用的过滤器,我的是覆盖过滤器。此过滤器提供了一个名为“格式”的参数,将其设置为您从相机获得的最接近的(YV12 不在列表中)。在我的情况下'yuv420'。 过滤器现在看起来像这样:
filter = new FFmpegFrameFilter("movie="+path+"/image.png [logo];[in][logo]overlay=0:0:format=yuv420 [out]",imageWidth, imageHeight);
在记录帧时设置正确的像素格式:
Frame frame;
while ((frame = filter.pull()) != null)
Log.i(LOG_TAG,"In record-pull");
recorder.record(frame,avutil.AV_PIX_FMT_YUV420P);
事实上,您必须将所有像素格式设置为相同。搜索所有站点以找到所有“组件”都支持的格式有点棘手。
建议的替代方法是将相机中的 YUV 图像转换为 RGB 图像。见Converting YUV->RGB(Image processing)->YUV during onPreviewFrame in android?
我没有尝试过,因为我教过这会变慢并首先尝试更简单的解决方案。
【讨论】:
以上是关于javaCV Android,流式传输到rtmp服务器时覆盖上的奇怪颜色的主要内容,如果未能解决你的问题,请参考以下文章
将音频和视频从 Android 手机流式传输到 RTMP 服务器的最佳方式
将麦克风流式传输到 RTMP (red5) 并返回到 android