0

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:

  1. At start, read pip.webm into a DataBuffer.
  2. Call createPipFile() to create an temporary file, an AsynchroniousFileChannel, and writing the DataBuffer into the temporary file.
  3. Calling override() to read "transparent_short.webm" into a second Databuffer and then writing the second DataBuffer 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();
    }
}
Macster
  • 81
  • 2
  • 9
  • [catch (Exception e) {}](https://technojeeves.com/index.php/aliasjava1/94-ignoring-exceptions-is-dangerous) – g00se Nov 07 '22 at 14:25
  • @g00se I kept the code as short as possible – Macster Nov 07 '22 at 14:27
  • 2
    I don't know this api, so can't comment. What I can say is that generally speaking, there are few file formats where you can concatenate files successfully with a simple buffer copy owing to the metadata in each applying *only* to each. Whether that's what's happening, I don't know – g00se Nov 07 '22 at 14:36
  • 1
    @g00se seems to be right, you can't just concat WebM files byte by byte. I found [this](https://stackoverflow.com/questions/35939131/how-can-i-merge-webm-audio-file-and-a-mp4-video-file-using-java) post. It is not exactly what you're looking for, but you'll get an idea which tools do you need. – 0x1C1B Nov 07 '22 at 15:35
  • @0x1C1B Oh i see. Makes sense. I just hoped it would work, because it is working if you receive payloads with chunked data which is then written into a databuffer which then is beeing wirtten to the file after each chunk, but those chunks probably got the right metadata to be treated as a whole. Fortunately using FFMPEG isn't much of a problem. Thanks guys :) – Macster Nov 07 '22 at 16:46

0 Answers0