2016-08-09 11 views
1

У меня возникла проблема с потоком 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(); 

Иногда андроид рисует на поверхности. Я не могу контролировать скорость этих рисунков. Также я не могу ничего рисовать на этой поверхности. Когда что-то меняется на поверхности, MediaCodec создает новый байтовый баффер с фреймом h264. Я отправляю этот кадр по rtmp.

На стороне клиента У меня есть HTML-страницу с jwplayer

<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, кадров в секунду кодирования, BufferLength .. Ничто не является действительно полезным.

Есть ли какая-либо возможность сразу показать встроенные рамки?

ответ

1

Что вы имеете в виду? Если я правильно понял - у вас есть: vlc (клиент) ---- протокол rtmp ---- андроид (продюсер) Вы кодируете видео с чего-то (может быть, с камеры) с помощью MediaCodec, а в vlc есть время задержки? правильно?

Сначала - что вы используете - буфер прямого ввода или MediaCodec.Callback()? В обратном вызове - вы можете проверить каждый кадр в onOutputBufferAvailable и рассчитать время от одного кадра к другому - это покажет вам - это проблема на стороне Android.

Затем вы можете попытаться решить проблему кадров transef

  1. Вы можете использовать WireShark, чтобы определить рамки отправки времени и Chek - может быть, это проблема сети
  2. чем - VLC и другие игроки пытаются заполнить некоторый внутренний буфер и только после этого начала показывать видео. Попробуйте включить буфер vlc (https://forum.videolan.org/viewtopic.php?t=40408). Затем - общее правило, что vlc ждет кадра IDR. Вы можете установить интервал для отправки кадров IDR в коде

    format.setInteger (MediaFormat.KEY_I_FRAME_INTERVAL, iframeInterval); iframeInterval в секундах (попробуйте установить 1 секунду) (это увеличит размер потоковый)

Извините за мой плохой английский

0

Вы можете надеяться что видеокадры на постоянной скорости, даже больше, чем 20 кадров в секунду для создания плавного видео с приемлемой задержкой. h264 будет обрабатывать стабильное изображение (одно изменение один раз в ~ 30 секунд) изящно, а когда нет изменений, размер кадра будет минимальным.