读取固定大小的 inputStream 字节
Read fixed size of bytes of inputSream
我们正在开发视频流应用程序,
目前我们能够捕获视频并逐帧处理,然后 send/receive 两个设备之间的数据。
问题出在接收方,因为我们发送的是固定大小的帧,所以接收方也应该以固定大小处理它们,否则他将无法获得帧。
希望这张图能说明问题。
传输过程:
代码:
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();
}
}
当前缓冲区reader正在读取不同大小的数据块,因此生成的位图如下:
由于缓冲的reader没有阻塞,等待所有缓冲都被填满,图像的黑色部分还没有被接收。
currently the buffer reader is reading chunks of data with different sizes
好的,这有什么问题吗?
由于各种原因,read
并不总是读取您要求的所有数据。您需要继续阅读,直到阅读完所有您想阅读的数据。
所以问题是帧大小固定的错误假设,
逻辑是获取相机提供的第一个帧大小,然后将其发送到另一侧的不同控件 Chanel,然后根据该信息继续流的其余部分,
如果我不对图像进行有损压缩,那会起作用
yuv.compressToJpeg(new Rect(0, 0, frameWidth, frameHieght), 25, out);
导致不同的帧大小,在@Oleg 评论的帮助下
post如何读取服务器套接字中的所有输入流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();
}
}
我们正在开发视频流应用程序, 目前我们能够捕获视频并逐帧处理,然后 send/receive 两个设备之间的数据。
问题出在接收方,因为我们发送的是固定大小的帧,所以接收方也应该以固定大小处理它们,否则他将无法获得帧。
希望这张图能说明问题。
传输过程:
代码:
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();
}
}
当前缓冲区reader正在读取不同大小的数据块,因此生成的位图如下:
由于缓冲的reader没有阻塞,等待所有缓冲都被填满,图像的黑色部分还没有被接收。
currently the buffer reader is reading chunks of data with different sizes
好的,这有什么问题吗?
由于各种原因,read
并不总是读取您要求的所有数据。您需要继续阅读,直到阅读完所有您想阅读的数据。
所以问题是帧大小固定的错误假设,
逻辑是获取相机提供的第一个帧大小,然后将其发送到另一侧的不同控件 Chanel,然后根据该信息继续流的其余部分, 如果我不对图像进行有损压缩,那会起作用
yuv.compressToJpeg(new Rect(0, 0, frameWidth, frameHieght), 25, out);
导致不同的帧大小,在@Oleg 评论的帮助下 post如何读取服务器套接字中的所有输入流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();
}
}