android - javaCV Android,在流式传输到 rtmp 服务器时叠加层出现奇怪的颜色

标签 android rtmp javacv

我想从 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/

我很沮丧,因为我已经尝试过很多像素格式。都有不同的输出,有时 Logo 会出现多次。

有没有办法找出我应该从 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

最佳答案

我想通了:

  1. 通过运行找出你的 android 相机支持哪些格式

    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);
    
  2. 转到 https://developer.android.com/reference/android/graphics/ImageFormat.html并检查您支持的格式是如何准确定义的。 842094169 是 YV12 是一种 4:2:0 YCrCb 平面格式,由一个 WxH Y 平面和后跟 (W/2) x (H/2) Cr 和 Cb 平面组成。

    <
  3. 转到 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);
    
  4. 记录帧时设置正确的像素格式:

    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?

我没有尝试过,因为我教过这会很慢,所以我先尝试了一个更简单的解决方案。

关于android - javaCV Android,在流式传输到 rtmp 服务器时叠加层出现奇怪的颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39479205/

相关文章:

delphi - LIBRTMP德尔福: mapping of the DLL

ffmpeg - 将 ffmpeg 用于传入的 youtube HLS 直播并输出到 rtmp

audio - JavaCV FFmpegFrameGrabber 预加载音频

java - 使用 CameraDevice 和 CameraSettings javacv

android - listView.setSelection(n); m=listView.getSelectedItemPosition();//m != n.为什么?

java - 可以将图像作为 ByteBuffer 发送到我的 Servlet 吗?

mysql - Nginx rtmp模块(m3u8)在本地播放?

java - 如何在 JavaCV 中更改网络摄像头格式?

Android 客户端无法使用自签名证书连接到 Tomcat

android - 有没有办法检测 apk 是否存储在 SD 卡上?