I have two video files, which I'm trying to merge into one temporary file. But I always end up having a file which contains only the longer first file "pip.webm". If I write to position: 0
instead of channel.size()
it will obviously override the existing data.
pip.webm
Duration: 5:00 Minutes
transparent_short.webm
Duration: 10 Seconds
What I did so far:
- At start, read pip.webm into a DataBuffer.
- Call
createPipFile()
to create an temporary file, an AsynchroniousFileChannel, and writing the DataBuffer into the temporary file. - Calling
override()
to read "transparent_short.webm" into a second Databuffer and then writing the secondDataBuffer
into the same teporary file as before.
I tried using StandardOpenOperation.APPEND
for the channel, but this will throw an APPEND not allowed
Error.
Another approach would be, to first merge both DataBuffers into one and then writing to the file at position: 0
. But I couldn't figure out how to merge the DataBuffers or how to add data to an DataBuffer which already contains data. Maybe using DataBufferUtils.join()
but I didn't get how to do that.
Code
OverrideOverlayVideo.java
@Component
public class OverrideOverlayVideo {
private static Log log = LogFactory.getLog(OverrideOverlayVideo.class);
final static Path sourceFile = FileSystems.getDefault().getPath("C:\\x\\pip.webm");
final static int DATABUFFERSIZE = 256*64;
final static DataBufferFactory dbf = new DefaultDataBufferFactory();
static Flux<DataBuffer> dataBuffer = DataBufferUtils.read(sourceFile, dbf, DATABUFFERSIZE);
public static String newClipPath2;
public LinkedList<String> clipPathList = new LinkedList<>();
public String createPipFile() {
try {
Path targetFolder = FileSystems.getDefault().getPath("C:\\x\\pip");
Path newClipPath = Files.createTempFile(targetFolder,"pip" , ".webm");
String newClipPath2 = newClipPath.normalize().toString();
clipPathList.add(0, newClipPath2);
AsynchronousFileChannel channel = AsynchronousFileChannel.open(newClipPath, StandardOpenOption.WRITE);
DataBufferUtils.write(dataBuffer, channel, 0)
.subscribe(DataBufferUtils.releaseConsumer());
return newClipPath2;
} catch (Exception e) {
}
return newClipPath2;
}
public Mono<Void> override() {
Path pathToInsertionClip = FileSystems.getDefault().getPath("C:\\x\\pip\\transparent_short.webm");
Flux<DataBuffer> databufferNewClip = DataBufferUtils.read(pathToInsertionClip, dbf, DATABUFFERSIZE);
Path newClipPath2 = FileSystems.getDefault().getPath(clipPathList.get(0));
try {
AsynchronousFileChannel channel = AsynchronousFileChannel.open(newClipPath2, StandardOpenOption.WRITE);
DataBufferUtils.write(databufferNewClip, channel, channel.size())
.subscribe(DataBufferUtils.releaseConsumer());
} catch (IOException e) {
e.printStackTrace();
}
return Mono.empty();
}
}
SendVideoInController.java
@RestController
public class SendVideoInController {
private static Log log = LogFactory.getLog(SendVideoInController.class);
private final OverrideOverlayVideo overrideOverlayVideo;
public SendVideoInController(OverrideOverlayVideo overrideOverlayVideo) {
this.overrideOverlayVideo = overrideOverlayVideo;
}
@GetMapping(value = "send/sendVideo")
private Mono<Void> sendVideoIn() {
log.info("Video received");
return overrideOverlayVideo.override();
}
}