|
20 | 20 | package org.ebml.matroska;
|
21 | 21 |
|
22 | 22 | import java.io.Closeable;
|
| 23 | +import java.io.IOException; |
| 24 | +import java.nio.file.Files; |
| 25 | +import java.nio.file.Path; |
23 | 26 | import java.util.HashSet;
|
24 | 27 | import java.util.Set;
|
25 |
| -import java.util.concurrent.*; |
26 | 28 |
|
27 | 29 | import org.ebml.MasterElement;
|
28 | 30 | import org.ebml.StringElement;
|
29 | 31 | import org.ebml.UnsignedIntegerElement;
|
30 | 32 | import org.ebml.io.DataWriter;
|
| 33 | +import org.ebml.io.FileDataWriter; |
31 | 34 | import org.slf4j.Logger;
|
32 | 35 | import org.slf4j.LoggerFactory;
|
33 | 36 |
|
@@ -88,10 +91,26 @@ void initialize()
|
88 | 91 | segmentInfoElem.writeElement(ioDW);
|
89 | 92 |
|
90 | 93 | metaSeek.addIndexedElement(MatroskaDocTypes.Tracks.getType(), ioDW.getFilePointer());
|
91 |
| - tracks.writeTracks(ioDW); |
| 94 | + try |
| 95 | + { |
| 96 | + tracks.writeTracks(ioDW, false); |
| 97 | + } |
| 98 | + catch (VoidOutOfBoundException e) |
| 99 | + { |
| 100 | + // when initializing tracks are empty so this should never happen |
| 101 | + LOG.error("Tracks element size exceeds block size?", e); |
| 102 | + } |
92 | 103 |
|
93 | 104 | metaSeek.addIndexedElement(MatroskaDocTypes.Tags.getType(), ioDW.getFilePointer());
|
94 |
| - tags.writeTags(ioDW); |
| 105 | + try |
| 106 | + { |
| 107 | + tags.writeTags(ioDW, false); |
| 108 | + } |
| 109 | + catch (VoidOutOfBoundException e) |
| 110 | + { |
| 111 | + // when initializing tags are empty so this should never happen |
| 112 | + LOG.error("Tags element size exceeds block size?", e); |
| 113 | + } |
95 | 114 |
|
96 | 115 | cluster = new MatroskaCluster();
|
97 | 116 | metaSeek.addIndexedElement(MatroskaDocTypes.Cluster.getType(), ioDW.getFilePointer());
|
@@ -283,13 +302,65 @@ public void close()
|
283 | 302 | segmentInfoElem.setDuration(maxSegmentTimecode - minSegmentTimecode);
|
284 | 303 | segmentLen += segmentInfoElem.update(ioDW);
|
285 | 304 |
|
286 |
| - segmentLen += tracks.update(ioDW); |
287 |
| - segmentLen += tags.update(ioDW); |
| 305 | + try |
| 306 | + { |
| 307 | + segmentLen += tracks.update(ioDW, true); |
| 308 | + } |
| 309 | + catch (VoidOutOfBoundException e) |
| 310 | + { |
| 311 | + LOG.info("Tracks element size exceeds block size. Will expand file."); |
| 312 | + |
| 313 | + try (FileDataWriter dw = copyBeginningOfFile()) |
| 314 | + { |
| 315 | + segmentLen += tracks.update(dw, false); |
| 316 | + copyEndOfFileAndClose(dw); |
| 317 | + } |
| 318 | + catch (VoidOutOfBoundException | IOException ex) |
| 319 | + { |
| 320 | + throw new RuntimeException(ex); |
| 321 | + } |
| 322 | + } |
| 323 | + try |
| 324 | + { |
| 325 | + segmentLen += tags.update(ioDW, true); |
| 326 | + } |
| 327 | + catch (VoidOutOfBoundException e) |
| 328 | + { |
| 329 | + LOG.info("Tags element size exceeds block size. Will expand file."); |
| 330 | + try (FileDataWriter dw = copyBeginningOfFile()) |
| 331 | + { |
| 332 | + segmentLen += tags.update(dw, false); |
| 333 | + copyEndOfFileAndClose(dw); |
| 334 | + } |
| 335 | + catch (VoidOutOfBoundException | IOException ex) |
| 336 | + { |
| 337 | + throw new RuntimeException(ex); |
| 338 | + } |
| 339 | + } |
288 | 340 | segmentLen += clusterLen;
|
289 | 341 |
|
290 | 342 | segmentElem.setUnknownSize(false);
|
291 | 343 | segmentElem.setSize(segmentLen);
|
292 | 344 | segmentElem.update(ioDW);
|
293 | 345 | }
|
294 | 346 | }
|
| 347 | + |
| 348 | + private FileDataWriter copyBeginningOfFile() |
| 349 | + throws IOException |
| 350 | + { |
| 351 | + FileDataWriter dw = new FileDataWriter(Files.createTempFile("mka", ".tmp").toFile().getPath()); |
| 352 | + dw.copyToPosition((FileDataWriter)ioDW); |
| 353 | + |
| 354 | + return dw; |
| 355 | + } |
| 356 | + |
| 357 | + private void copyEndOfFileAndClose(FileDataWriter dw) |
| 358 | + throws IOException |
| 359 | + { |
| 360 | + dw.copyFromPosition((FileDataWriter)ioDW); |
| 361 | + |
| 362 | + ((FileDataWriter) ioDW).close(); |
| 363 | + ((FileDataWriter) ioDW).replaceWithFile(dw); |
| 364 | + |
| 365 | + } |
295 | 366 | }
|
0 commit comments