Hi,
I am trying to use Vertx Pump, to send a video file from server to client ensuring correct video playback with html5 video tag.
The playback is fine when playing small video files without using the Pump, for instance:
Buffer buffer = vertx.fileSystem().readFileSync(pathToFile);
req.response().write(buffer.getBuffer(start, fileSize);
But this does not work with larger video files due to memory overload.
Using the Pump my code looks as follows:
vertx.fileSystem().open(pathToFile, new Handler<AsyncResult<AsyncFile>>() {
@Override
public void handle(AsyncResult<AsyncFile> fileResult) {
if (fileResult.succeeded()) {
final AsyncFile asyncFile = fileResult.result();
Buffer buff = new Buffer();
final Pump pump = pumpGenerator.getPump(asyncFile.read(buff, 0, startByte, fileSize - startByte, new AsyncResultHandler<Buffer>() {
public void handle(AsyncResult<Buffer> ar) {
if (ar.succeeded()) {
LOG.info("Read file chunk OK");
} else {
LOG.error("Failed to write", ar.cause());
}
}
}), req.response()).start();
asyncFile.endHandler(new Handler<Void>() {
@Override
public void handle(Void event) {
req.response().end();
}
});
}
}
});
This works OK with the small video (when a single HTTP request is enough to load the full video). With slightly bigger files, when the browser sends several requests with Http Header "Range" (i.e.
Range:
bytes=673223804-), this causes Broken Pipe exception coming from client side (video tag), as if the sent data is corrupt or does not correspond to the Http response headers (i.e. Content-Length, Content-Range). As far as I understand the pump sends the file bytewise, so the response might actually be inaccurate. What is the right solution in this case?
Stack:
Schwerwiegend: Exception in Java verticle
java.io.IOException: Datenübergabe unterbrochen (broken pipe)
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:51)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:487)
at io.netty.buffer.PooledUnsafeDirectByteBuf.getBytes(PooledUnsafeDirectByteBuf.java:208)
at io.netty.buffer.PooledUnsafeDirectByteBuf.readBytes(PooledUnsafeDirectByteBuf.java:215)
at io.netty.channel.socket.nio.NioSocketChannel.doWriteBytes(NioSocketChannel.java:214)
at io.netty.channel.nio.AbstractNioByteChannel.doWrite(AbstractNioByteChannel.java:194)
at io.netty.channel.socket.nio.NioSocketChannel.doWrite(NioSocketChannel.java:231)
at io.netty.channel.AbstractChannel$AbstractUnsafe.flush0(AbstractChannel.java:682)
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.flush0(AbstractNioChannel.java:271)