我们正在制作视频流应用, 目前,我们能够捕获视频并逐帧处理,然后在两个设备之间发送/接收数据。
问题出在接收方,因为我们发送固定大小的帧,所以在接收方也应该用固定大小处理它们,否则他将无法获得帧。
希望这张图能够澄清问题。
代码:
public void process(@NonNull Frame frame) {
byte[] data = frame.getData();
frameWidth = frame.getSize().getWidth();
frameHieght = frame.getSize().getHeight();
YuvImage yuv = new YuvImage(data, frame.getFormat(), frameWidth, frameHieght, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
yuv.compressToJpeg(new Rect(0, 0, frameWidth, frameHieght), 25, out);
final byte[] bytes = out.toByteArray();
frameByteSize = bytes.length;
OutputStream outputStream = StreamHandler.getOutputStream();
if (out != null) {
try {
outputStream.write(bytes, 0, frameByteSize);
} catch (IOException e) {
e.printStackTrace();
}
}
代码:
public void run() {
int read = 0;
int hold = 0;
int frameSize = StreamHandler.getFrameByteSize();
try {
Thread.sleep(10000);
if (SrtreamHandler != null) {
InputStream inputStream = StreamHandler.getInputStream();
if (inputStream != null) {
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
while (microPhoneActive) {
byte[] frame = new byte[frameSize];
read = bufferedInputStream.read(frame, 0, frame.length);
Bitmap bitmap = BitmapFactory.decodeByteArray(frame, 0, frame.length);
if (bitmap != null) {
final Bitmap rotatedBitmap = rotateBitmap(bitmap, -90);
frameEvent.onNewFrame(rotatedBitmap);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
目前缓冲读取器正在读取不同大小的数据块,因此构建的位图将如下所示:
尚未收到图像的黑色边,因为缓冲的阅读器没有阻塞并等待所有缓冲区都被填满。
答案 0 :(得分:0)
目前缓冲读取器正在读取不同大小的数据块
好吧,那有什么不对?
由于各种原因, read
并不会始终阅读您要求的所有数据。在您阅读了想要阅读的所有数据之前,您需要继续阅读。
答案 1 :(得分:0)
所以问题是框架尺寸固定的错误假设,
逻辑是获取摄像头提供的第一个帧大小,然后将其发送到另一个控制Chanel的另一侧,然后继续传输该信息的其余流, 如果我没有对图像进行有损压缩,那将会奏效
yuv.compressToJpeg(new Rect(0, 0, frameWidth, frameHieght), 25, out);
由于@Oleg对此有所评论,导致不同的帧大小
发表 How to read all of Inputstream in Server Socket JAVA
代码看起来像这样, 发送:
public void process(@NonNull Frame frame) {
byte[] data = frame.getData();
frameWidth = frame.getSize().getWidth();
frameHieght = frame.getSize().getHeight();
YuvImage yuv = new YuvImage(data, frame.getFormat(), frameWidth, frameHieght, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
yuv.compressToJpeg(new Rect(0, 0, frameWidth, frameHieght), 25, out);
final byte[] bytes = out.toByteArray();
frameByteSize = bytes.length;
if (StreamHandler != null) {
OutputStream outputStream = StreamHandler.getOutputStream();
if (out != null) {
try {
byte firstByte = (byte) ((bytes.length & 0xff00) >> 8);
byte secondByte = (byte) (bytes.length & 0xFF);
outputStream.write(firstByte);
outputStream.write(secondByte);
outputStream.write(bytes, 0, frameByteSize);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
收到:
public void run() {
int read = 0;
int hold = 0;
int frameSize = StreamHandler.getFrameByteSize();
try {
if (StreamHandler != null) {
InputStream inputStream = SrtreamHandler.getInputStream();
if (inputStream != null) {
DataInputStream dataInputStream = new DataInputStream(inputStream);
byte[] frameInfo = new byte[2];
while (microPhoneActive) {
frameInfo[0] = dataInputStream.readByte();
frameInfo[1] = dataInputStream.readByte();
ByteBuffer byteBuffer = ByteBuffer.wrap(frameInfo, 0, 2);
int bytesToRead = byteBuffer.getShort();
byte[] frame = new byte[bytesToRead];
dataInputStream.readFully(frame, 0, bytesToRead);
Bitmap bitmap = BitmapFactory.decodeByteArray(frame, 0, frame.length);
if (bitmap != null) {
final Bitmap rotatedBitmap = rotateBitmap(bitmap, -90);
frameEvent.onNewFrame(rotatedBitmap);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}