카메라 출력을 rtp 스트림으로 서버에 보낼 Android 응용 프로그램을 만들려고하는데 예상대로 작동하지 않습니다. 다음 단계를 수행하고 있습니다.
활동 클래스에서 구현 된 SurfaceTextureListener
인터페이스와 onCreate()
생성 TextureView
및 추가 된 리스너.
In 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 헤더를 추가하여.
udp://@:5001
미디어 정보에서 VLC가 "Read At Media"및 "Input Bitrate"에 일부 데이터를 표시하고 있다는 것은 내 앱이 해당 udp 포트로 일부 데이터를 보내고 있음을 의미합니다. 또한 비디오를 안드로이드 장치에 저장하려고 시도했는데 내 앱이 동일한 코드 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);
stackoverflow의 누군가가 AVC에서 첫 번째 4 바이트를 제거해야한다고 말하면서 처음 4 바이트의 패킷을 제거하여 코드를 수정하려고했습니다. 또한 내 RTP 헤더를 두 번 확인했지만 운이 없었습니다 ...
내 코드가 비디오를 rtp로 보내지 못하는 이유를 아십니까?
RTP 헤더 만 추가 할 수는 없습니다. H264 RTP 페이로드 형식에 대해 하나 이상의 고정 길이 RTP 패킷 (일명 "패킷 화")에 맞게 인코딩 된 버퍼를 다시 형식화해야합니다 . 전체 사양 은 RFC 6184 를 참조하십시오 .
H.264 패킷이 1400 패킷 크기에 맞을만큼 충분히 짧으면 처음 4 바이트 만 제거하면됩니다 (처음 4 바이트가 0, 0, 0, 1이라고 가정). 인코더의 출력 버퍼에 둘 이상의 NAL 단위가 포함되어있는 경우 (버퍼에 시퀀스 [0,] 0, 0, 1이 더 많이 발생하는 경우) 각 NAL 단위를 별도의 패킷으로 보내야합니다. , 또는보다 정교한 패킷 화 체계 중 하나를 사용하십시오. 이에 대한 자세한 내용은 RFC를 참조하십시오.
둘째, 현재 실제 인코딩 된 페이로드가 더 짧더라도 전체 1400 바이트 패킷을 전송하고 있습니다. 얼마나 많은 문제가 발생할 수 있는지 또는 눈에 띄지 않게 통과 할 수 있는지 잘 모르겠지만 실제로는 실제로 채운 바이트 수만 보내야합니다. (즉, 대신을 mBuffers.length
사용하십시오 12 + buf.length
.)
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다