【问题标题】:Streaming video of android surfaceandroid表面的流媒体视频
【发布时间】:2016-12-14 21:48:56
【问题描述】:

我在将 android 表面的 rtmp 流式传输到客户端应用程序时遇到问题。我的解决方案有一个很大的延迟,因为我的表面不是每秒产生 60 次帧,它可以在任何时间产生它(例如每 30 秒一次)。所以我想立即向客户展示每个新生成的帧。

Android 正在推送每一帧,看起来不错。客户端应用程序(jwplayer 或 vlc)接收它,但它正在等待某些东西。只有在接收到若干帧后才会显示视频。但是我需要在客户端接收到每个传入帧时查看它。

现在的工作方式: 我有一个Surface 对象,从MediaCodec 类获得。 MediaCodec 设置为 h264 视频编码。

MediaCodec mEncoder;

.....

MediaFormat format = MediaFormat.createVideoFormat("video/avc", width, height);
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
format.setInteger(MediaFormat.KEY_BIT_RATE, videoBitrate);
format.setInteger(MediaFormat.KEY_FRAME_RATE, videoFramePerSecond);
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iframeInterval);

try {
    mEncoder = MediaCodec.createEncoderByType("video/avc");
} catch (IOException e) {
    e.printStackTrace();
}
mEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
mSurface = mEncoder.createInputSurface();
if (mSurfaceCallback!=null)
    mSurfaceCallback.onSurfaceCreated(mSurface);
mEncoder.start();

有时 android 会浮出水面。我无法控制这幅画的速度。我也不能在那个表面上画任何东西。当表面发生变化时,MediaCodec 会生成带有 h264 帧的新 byteBuffer。我通过 rtmp 发送此帧。

在客户端我有带有 jwplayer 的 html 页面

<pre id="myElement"></pre>
<script>
var playerInstance = jwplayer("myElement");
playerInstance.setup({
file:"rtmp://127.0.0.1:1935/live/stream",
height: 800,
width: 480,
autostart: true,
controls: false,
    rtmp: {
        bufferlength: 0.1
    }
});
</script>

我尝试更改 iframeInterval、编码的 fps、缓冲区长度。没有什么是真正有用的。

是否有可能立即显示传入的帧?

【问题讨论】:

    标签: android video-streaming h.264 rtmp


    【解决方案1】:

    您有望以恒定速率(甚至超过 20 fps)生成视频帧,从而以可接受的延迟生成流畅的视频。 h264 编码器会优雅地处理稳定的图片(大约 30 秒改变一次),当没有变化时,帧大小将最小。

    【讨论】:

      【解决方案2】:

      什么意思? 如果我理解正确 - 你有: vlc(client) ---- rtmp 协议 ---- android (producer) 您使用 MediaCodec 对来自某些东西(可能是相机)的视频进行编码,并且在 vlc 中存在时间延迟?对吧?

      首先 - 你在使用什么 - 直接输入缓冲区或 MediaCodec.Callback() ? 在回调中-您可以检查 onOutputBufferAvailable 中的每一帧并计算从一帧到另一帧的时间-这将告诉您-这是android端的问题。

      那你可以尝试解决frame transef问题

      1. 您可以使用 WireShark 来确定帧发送时间和检查 - 可能这是网络问题
      2. Than - vlc 和其他播放器尝试填充一些内部缓冲区,然后才开始显示视频。尝试关闭 vlc 缓冲区 (https://forum.videolan.org/viewtopic.php?t=40408)。然后 - 常见的是 vlc 等待 IDR 帧。您可以在代码中设置发送 IDR 帧的间隔

        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, iframeInterval); iframeInterval 以秒为单位(尝试设置为 1 秒) (这会增加流媒体大小)

      对不起我的英语不好

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-27
        • 1970-01-01
        • 1970-01-01
        • 2011-09-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多