Я работаю над приложением Java, которое будет передавать видео с IP-камеры. Видеопотоки с IP-камеры в формате MJPEG. Протокол следующий ...Чтение двоичного потока до появления « r n»
--ipcamera (\r\n)
Content-Type: image/jpeg (\r\n)
Content-Length: {length of frame} (\r\n)
(\r\n)
{frame}
(\r\n)
--ipcamera (\r\n)
etc.
Я попытался с помощью классов, таких как BufferedReader и сканер не читать до «\ г \ п», однако те, которые предназначены для текста, а не двоичных данных, так что это становится коррумпированным. Есть ли способ прочитать двоичный поток до тех пор, пока он не встретит «\ r \ n»? Вот мой текущий (сломанный) код.
EDIT: Я получил его на работу. Я обновил код ниже. Тем не менее, это очень медленно. Я не уверен, что это имеет какое-либо отношение к ArrayList или нет, но это может быть преступником. Любые указатели на ускорение кода? В настоящее время он принимает от 500 мс до 900 мс для одного кадра.
public void run() {
long startTime = System.currentTimeMillis();
try {
URLConnection urlConn = url.openConnection();
urlConn.setReadTimeout(15000);
urlConn.connect();
urlStream = urlConn.getInputStream();
DataInputStream dis = new DataInputStream(urlStream);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ArrayList<Byte> bytes = new ArrayList<Byte>();
byte cur;
int curi;
byte[] curBytes;
int length = 0;
while ((curi = dis.read()) != -1) {
cur = (byte) curi;
bytes.add(cur);
curBytes = getPrimativeArray(bytes);
String curBytesString = new String(curBytes, "UTF-8");
if (curBytesString.equals("--ipcamera\r\n")) {
bytes.clear();
continue;
} else if (curBytesString.equals("Content-Type: image/jpeg\r\n")) {
bytes.clear();
continue;
} else if (curBytesString.matches("^Content-Length: ([0-9]+)\r\n$")) {
length = Integer.parseInt(curBytesString.replace("Content-Length: ", "").trim());
bytes.clear();
continue;
} else if (curBytesString.equals("\r\n")) {
if (length == 0) {
continue;
}
byte[] frame = new byte[length];
dis.readFully(frame, 0, length);
writeFrame(frame);
bytes.clear();
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
long curTime = System.currentTimeMillis() - startTime;
System.out.println(curTime);
}
private byte[] getPrimativeArray(ArrayList<Byte> array) {
byte[] bytes = new byte[array.size()];
for (int i = 0; i < array.size(); i++) {
bytes[i] = array.get(i).byteValue();
}
return bytes;
}
private void writeFrame(byte[] bytes) throws IOException {
File file = new File("C:\\test.jpg");
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
fos.close();
System.out.println("done");
}
Да, я не знал, что BufferedReader предназначен только для текста. Это имеет смысл, учитывая, что он возвращает char [], lol. Есть ли другой способ прочитать, пока не будет найден «\ r \ n»? Я бы предпочел не использовать readLine() в DataInputStream, поскольку он устарел. Я пробовал использовать класс Scanner, но это похоже на BufferedReader и предназначено для текста. – CharDev
DataInputStream.readLine() устарел, потому что он читает текст, но предполагаю, что кодировка ISO-8859-1, которую я подозреваю, в порядке.Вы можете написать свой собственный метод readLine(), но я думаю, что он в конечном итоге сделает то же самое. Иногда самым простым выбором является устаревший метод. –
У меня есть работа с ArrayList с чтением заголовков, а затем чтение остального в байт [] после того, как он получит длину и находит «\ r \ n». Однако он очень медленный (500 мс-900 мс). Любые указатели? –
CharDev