Я пытаюсь сделать приложение для Android, которое отправит вывод камеры на сервер как поток rtp, но он не работает должным образом. я делаю следующие шагиНевозможно отправить видео как поток rtp с android
В классе активность реализуется
SurfaceTextureListener
интерфейс и вonCreate()
созданTextureView
и добавил слушателя.В
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)
метод создан и инициализированCamera
иMediaCodec
экземпляр для кодирования выхода камеры кH.264
. Также добавлены PreviewCallback для камеры следующим образом -mCamera.setPreviewCallback(new Camera.PreviewCallback() { @Override public void onPreviewFrame(byte[] data, Camera camera) { // Here encode method will encode frame using Mediacodec and send it to LocalSocket. encode(data); } });
Теперь другой
AsyncTask
прочтет этуLocalSocket
и отправить его вDatagramSocket
путем добавления RTP заголовка в каждом пакете.- Я тестирую этот код на VLC, передавая файл sdp, но VLC не воспроизводит видео. Если я открою udp-сокет в VLC
udp://@:5001
, тогда в Media Information VLC отображаются некоторые данные в «Read At Media» и «Input Bitrate», это означает, что мое приложение отправляет некоторые данные в этот udp-порт. Также я попытался сохранить видео в Android-устройстве, и мое приложение сохраняет правильное видео с того же кодаMediaCoded
иCamera
.
RTP заголовка и пакетов кода формирования
int Version; // 2 bits
int Padding; // 1 bit
int Extension; // 1 bit
int CC; // 4 bits
int Marker; // 1 bit
int PayloadType=96; // 7 bits
int Ssrc; // 32 bits
Version = 2;
Padding = 0;
Extension = 0;
CC = 0;
Marker = 0;
Ssrc = 0;
byte[] header = new byte[ 12 ];
long timeStamp = System.currentTimeMillis();
mSeq = ++mSeq + 1;
header[0] = (byte)(Version << 6);
header[0] = (byte)(header[0] | Padding << 5);
header[0] = (byte)(header[0] | Extension << 4);
header[0] = (byte)(header[0] | CC);
header[1] = (byte)(header[1] | Marker << 7);
header[1] = (byte)(header[1] | PayloadType);
header[2] = (byte)(mSeq >> 8);
header[3] = (byte)(mSeq & 0xFF);
header[4] = (byte)(timeStamp >> 24);
header[5] = (byte)(timeStamp >> 16);
header[6] = (byte)(timeStamp >> 8);
header[7] = (byte)(timeStamp & 0xFF);
header[8] = (byte)(Ssrc >> 24);
header[9] = (byte)(Ssrc >> 16);
header[10] = (byte)(Ssrc >> 8);
header[11] = (byte)(Ssrc & 0xFF);
mBuffers = new byte[1400];
System.arraycopy(header, 0, mBuffers, 0, header.length);
System.arraycopy(buf, 0, mBuffers, 12, buf.length);
DatagramPacket out = new DatagramPacket(mBuffers, mBuffers.length, hostAddress, 5001);
socket.send(out);
Я пытался исправить мой код, удаляя первые 4 байта пакета, как кто-то из StackOverflow говорит, что в АВК нам нужно удалить 1-го по 4 байта. Также дважды проверял мой заголовок RTP, но не повезло ...
Любая идея, почему мой код не отправляет видео как rtp?
https://code.google.com/p/spydroid-ipcamera/ искать, где он устанавливает пакеты в rtp –