From efb4bdbbafcbd9662ff25d03f42ed6af2bc2abb3 Mon Sep 17 00:00:00 2001 From: vdeconinck Date: Thu, 15 Aug 2024 18:22:15 +0200 Subject: [PATCH 1/8] Support blanks in project path (path URL contains '%20' for blanks) --- .../coremedia/drm/packager/isoparser/RoundTripTest.java | 4 +++- .../src/test/java/org/mp4parser/test/SkippingBoxTest.java | 4 +++- .../src/test/java/org/mp4parser/test/tools/PathTest.java | 4 +++- .../java/org/mp4parser/muxer/CencFileRoundtripTest.java | 7 ++++++- .../org/mp4parser/muxer/FragmentedMp4BuilderTest.java | 6 ++++-- .../test/java/org/mp4parser/muxer/InTestMovieCreator.java | 4 +++- .../mp4parser/muxer/builder/DefaultFragmenterTest.java | 5 ++++- .../mp4parser/muxer/samples/DefaultMp4SampleListTest.java | 4 +++- .../java/org/mp4parser/muxer/tracks/AACTrackImplTest.java | 8 +++++--- .../java/org/mp4parser/muxer/tracks/AC3TrackImplTest.java | 6 ++++-- .../org/mp4parser/muxer/tracks/CencTracksImplTest.java | 8 +++++--- .../java/org/mp4parser/muxer/tracks/DTSTrackImplTest.java | 6 ++++-- .../org/mp4parser/muxer/tracks/H264TrackImplTest.java | 6 ++++-- .../org/mp4parser/muxer/tracks/ttml/TtmlHelpersTest.java | 4 +++- 14 files changed, 54 insertions(+), 22 deletions(-) diff --git a/isoparser/src/test/java/com/coremedia/drm/packager/isoparser/RoundTripTest.java b/isoparser/src/test/java/com/coremedia/drm/packager/isoparser/RoundTripTest.java index c7feba217..9c564406d 100644 --- a/isoparser/src/test/java/com/coremedia/drm/packager/isoparser/RoundTripTest.java +++ b/isoparser/src/test/java/com/coremedia/drm/packager/isoparser/RoundTripTest.java @@ -23,7 +23,9 @@ import java.io.ByteArrayOutputStream; import java.io.FileInputStream; +import java.net.URLDecoder; import java.nio.channels.Channels; +import java.nio.charset.StandardCharsets; /** * Tests ISO Roundtrip. @@ -34,7 +36,7 @@ public class RoundTripTest extends TestCase { @Override protected void setUp() throws Exception { super.setUp(); - defaultTestFileDir = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(); + defaultTestFileDir = URLDecoder.decode(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()); /* Logger.getLogger("").setLevel(Level.ALL); Handler[] handlers = Logger.getLogger("").getHandlers(); for (Handler handler : handlers) { diff --git a/isoparser/src/test/java/org/mp4parser/test/SkippingBoxTest.java b/isoparser/src/test/java/org/mp4parser/test/SkippingBoxTest.java index 60000a596..bf0260fc8 100644 --- a/isoparser/src/test/java/org/mp4parser/test/SkippingBoxTest.java +++ b/isoparser/src/test/java/org/mp4parser/test/SkippingBoxTest.java @@ -6,6 +6,8 @@ import java.io.FileInputStream; import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import org.junit.Before; import org.junit.Test; @@ -24,7 +26,7 @@ public class SkippingBoxTest { @Before public void setup() throws IOException { - FileInputStream fis = new FileInputStream(PathTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/test.m4p"); + FileInputStream fis = new FileInputStream(URLDecoder.decode(PathTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/test.m4p"); isoFile = new IsoFile(fis.getChannel(), new PropertyBoxParserImpl().skippingBoxes("mdat", "mvhd")); fis.close(); } diff --git a/isoparser/src/test/java/org/mp4parser/test/tools/PathTest.java b/isoparser/src/test/java/org/mp4parser/test/tools/PathTest.java index 8a04c2779..342676c24 100644 --- a/isoparser/src/test/java/org/mp4parser/test/tools/PathTest.java +++ b/isoparser/src/test/java/org/mp4parser/test/tools/PathTest.java @@ -9,13 +9,15 @@ import java.io.FileInputStream; import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; public class PathTest { IsoFile isoFile; @Before public void setup() throws IOException { - isoFile = new IsoFile(new FileInputStream(PathTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/multiTrack.3gp").getChannel()); + isoFile = new IsoFile(new FileInputStream(URLDecoder.decode(PathTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/multiTrack.3gp").getChannel()); } diff --git a/muxer/src/test/java/org/mp4parser/muxer/CencFileRoundtripTest.java b/muxer/src/test/java/org/mp4parser/muxer/CencFileRoundtripTest.java index dd18aead4..e216b15e3 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/CencFileRoundtripTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/CencFileRoundtripTest.java @@ -19,16 +19,21 @@ import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.net.URLDecoder; import java.nio.channels.Channels; +import java.nio.charset.StandardCharsets; import java.util.*; public class CencFileRoundtripTest { - private String baseDir = CencFileRoundtripTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(); + private String baseDir = URLDecoder.decode(CencFileRoundtripTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()); private Map keys; private RangeStartMap keyRotation1; private RangeStartMap keyRotation2; private RangeStartMap keyRotation3; + public CencFileRoundtripTest() throws Exception { + } + @Before public void setUp() throws Exception { diff --git a/muxer/src/test/java/org/mp4parser/muxer/FragmentedMp4BuilderTest.java b/muxer/src/test/java/org/mp4parser/muxer/FragmentedMp4BuilderTest.java index 9cbd3d8f7..a37a65895 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/FragmentedMp4BuilderTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/FragmentedMp4BuilderTest.java @@ -7,7 +7,9 @@ import org.mp4parser.muxer.container.mp4.MovieCreator; import java.io.ByteArrayOutputStream; +import java.net.URLDecoder; import java.nio.channels.Channels; +import java.nio.charset.StandardCharsets; /** * Not really a test but at least makes sure muxing kind of works @@ -16,8 +18,8 @@ public class FragmentedMp4BuilderTest { @Test public void testSimpleMuxing() throws Exception { Movie m = new Movie(); - Movie v = MovieCreator.build(FragmentedMp4BuilderTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/BBB_qpfile_10sec/BBB_fixedres_B_180x320_80.mp4"); - Movie a = MovieCreator.build(FragmentedMp4BuilderTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/BBB_qpfile_10sec/output_audio-2ch-20s.mp4"); + Movie v = MovieCreator.build(URLDecoder.decode(FragmentedMp4BuilderTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/BBB_qpfile_10sec/BBB_fixedres_B_180x320_80.mp4"); + Movie a = MovieCreator.build(URLDecoder.decode(FragmentedMp4BuilderTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/BBB_qpfile_10sec/output_audio-2ch-20s.mp4"); m.addTrack(v.getTracks().get(0)); m.addTrack(a.getTracks().get(0)); diff --git a/muxer/src/test/java/org/mp4parser/muxer/InTestMovieCreator.java b/muxer/src/test/java/org/mp4parser/muxer/InTestMovieCreator.java index 46e975005..820283072 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/InTestMovieCreator.java +++ b/muxer/src/test/java/org/mp4parser/muxer/InTestMovieCreator.java @@ -3,13 +3,15 @@ import org.mp4parser.muxer.container.mp4.MovieCreator; import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; public class InTestMovieCreator { public static Movie createMovieOnlyVideo(String... names) throws IOException { Movie m = new Movie(); for (String name : names) { - Movie m1 = MovieCreator.build((InTestMovieCreator.class.getProtectionDomain().getCodeSource().getLocation().getFile() + name)); + Movie m1 = MovieCreator.build((URLDecoder.decode(InTestMovieCreator.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + name)); for (Track track : m1.getTracks()) { if ("vide".equals(track.getHandler())) { m.addTrack(track); diff --git a/muxer/src/test/java/org/mp4parser/muxer/builder/DefaultFragmenterTest.java b/muxer/src/test/java/org/mp4parser/muxer/builder/DefaultFragmenterTest.java index 148927276..3dbdbdc10 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/builder/DefaultFragmenterTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/builder/DefaultFragmenterTest.java @@ -5,6 +5,9 @@ import org.mp4parser.muxer.Movie; import org.mp4parser.muxer.container.mp4.MovieCreator; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; + /** * Just check it works. */ @@ -13,7 +16,7 @@ public class DefaultFragmenterTest { @Test public void testSampleNumbers() throws Exception { - String f = DefaultFragmenterTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/Beethoven - Bagatelle op.119 no.11 i.m4a"; + String f = URLDecoder.decode(DefaultFragmenterTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/Beethoven - Bagatelle op.119 no.11 i.m4a"; Movie m = MovieCreator.build(f); DefaultFragmenterImpl intersectionFinder = new DefaultFragmenterImpl(2); long[] s = intersectionFinder.sampleNumbers(m.getTracks().get(0)); diff --git a/muxer/src/test/java/org/mp4parser/muxer/samples/DefaultMp4SampleListTest.java b/muxer/src/test/java/org/mp4parser/muxer/samples/DefaultMp4SampleListTest.java index 7b9f29c46..3723bcba4 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/samples/DefaultMp4SampleListTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/samples/DefaultMp4SampleListTest.java @@ -10,6 +10,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.RandomAccessFile; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -150,7 +152,7 @@ public class DefaultMp4SampleListTest { @Test public void checkSampleList() throws IOException, NoSuchAlgorithmException { - String filename = this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + + String filename = URLDecoder.decode(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/samples/1365070268951.mp4"; IsoFile isoFile = new IsoFile(new FileInputStream(filename).getChannel()); Mp4SampleList sl = new Mp4SampleList(1, isoFile, new FileRandomAccessSourceImpl(new RandomAccessFile(filename, "r"))); diff --git a/muxer/src/test/java/org/mp4parser/muxer/tracks/AACTrackImplTest.java b/muxer/src/test/java/org/mp4parser/muxer/tracks/AACTrackImplTest.java index d1892ba0d..dbb0aab29 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/tracks/AACTrackImplTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/tracks/AACTrackImplTest.java @@ -29,7 +29,9 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.net.URLDecoder; import java.nio.channels.Channels; +import java.nio.charset.StandardCharsets; /** * Simple test to make sure nothing breaks. @@ -50,8 +52,8 @@ public static void main(String[] args) throws IOException { @Test public void freeze() throws IOException { - Track t = new AACTrackImpl(new FileDataSourceImpl(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + "/org/mp4parser/muxer/tracks/aac-sample.aac")); - //Track t = new AACTrackImpl2(new FileInputStream(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + "/com/googlecode/mp4parser/authoring/tracks/aac-sample.aac")); + Track t = new AACTrackImpl(new FileDataSourceImpl(URLDecoder.decode(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/tracks/aac-sample.aac")); + //Track t = new AACTrackImpl2(new FileInputStream(URLDecoder.decode(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/com/googlecode/mp4parser/authoring/tracks/aac-sample.aac")); Movie m = new Movie(); m.addTrack(t); @@ -59,7 +61,7 @@ public void freeze() throws IOException { Container c = mp4Builder.build(m); //c.writeContainer(new FileOutputStream("C:\\dev\\mp4parser\\isoparser\\src\\test\\resources\\com\\googlecode\\mp4parser\\authoring\\tracks\\aac-sample.mp4").getChannel()); - IsoFile isoFileReference = new IsoFile(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + "/org/mp4parser/muxer/tracks/aac-sample.mp4"); + IsoFile isoFileReference = new IsoFile(URLDecoder.decode(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/tracks/aac-sample.mp4"); BoxComparator.check(c, isoFileReference, "moov[0]/mvhd[0]", "moov[0]/trak[0]/tkhd[0]", "moov[0]/trak[0]/mdia[0]/mdhd[0]", "moov[0]/trak[0]/mdia[0]/minf[0]/stbl[0]/stco[0]"); } } diff --git a/muxer/src/test/java/org/mp4parser/muxer/tracks/AC3TrackImplTest.java b/muxer/src/test/java/org/mp4parser/muxer/tracks/AC3TrackImplTest.java index 22646716f..02094586b 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/tracks/AC3TrackImplTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/tracks/AC3TrackImplTest.java @@ -11,11 +11,13 @@ import java.io.FileInputStream; import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; public class AC3TrackImplTest { @Test public void freeze() throws IOException { - Track t = new AC3TrackImpl(new FileDataSourceImpl(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + "/org/mp4parser/muxer/tracks/ac3-sample.ac3")); + Track t = new AC3TrackImpl(new FileDataSourceImpl(URLDecoder.decode(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/tracks/ac3-sample.ac3")); Movie m = new Movie(); m.addTrack(t); @@ -24,7 +26,7 @@ public void freeze() throws IOException { //WritableByteChannel fc = new FileOutputStream("ac3-sample.mp4").getChannel(); //isoFile.writeContainer(fc); //fc.close(); - IsoFile isoFileReference = new IsoFile(new FileInputStream(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + "/org/mp4parser/muxer/tracks/ac3-sample.mp4").getChannel()); + IsoFile isoFileReference = new IsoFile(new FileInputStream(URLDecoder.decode(this.getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/tracks/ac3-sample.mp4").getChannel()); BoxComparator.check(isoFile, isoFileReference, "moov[0]/mvhd[0]", "moov[0]/trak[0]/tkhd[0]", "moov[0]/trak[0]/mdia[0]/mdhd[0]"); } } diff --git a/muxer/src/test/java/org/mp4parser/muxer/tracks/CencTracksImplTest.java b/muxer/src/test/java/org/mp4parser/muxer/tracks/CencTracksImplTest.java index 29bc946ed..3850c2a86 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/tracks/CencTracksImplTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/tracks/CencTracksImplTest.java @@ -19,7 +19,9 @@ import javax.crypto.spec.SecretKeySpec; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; +import java.net.URLDecoder; import java.nio.channels.Channels; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -32,7 +34,7 @@ public class CencTracksImplTest { public void testEncryptDecryptDefaultMp4() throws Exception { SecretKey sk = new SecretKeySpec(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, "AES"); Movie m = MovieCreator.build( - CencTracksImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + + URLDecoder.decode(CencTracksImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/samples/1365070268951.mp4"); List encTracks = new LinkedList(); @@ -66,7 +68,7 @@ public void testEncryptDecryptDefaultMp4() throws Exception { public void testEncryptDecryptFragmentedMp4() throws Exception { SecretKey sk = new SecretKeySpec(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, "AES"); Movie m = MovieCreator.build( - CencTracksImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + + URLDecoder.decode(CencTracksImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile()) + "/org/mp4parser/muxer/samples/1365070268951.mp4"); List encTracks = new LinkedList(); @@ -99,7 +101,7 @@ public void testEncryptDecryptCbc1FragmentedMp4() throws Exception { UUID keyId = UUID.randomUUID(); SecretKey key = new SecretKeySpec(new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, "AES"); Movie m = MovieCreator.build( - CencTracksImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + + URLDecoder.decode(CencTracksImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile()) + "/org/mp4parser/muxer/samples/1365070268951.mp4"); List encTracks = new LinkedList(); diff --git a/muxer/src/test/java/org/mp4parser/muxer/tracks/DTSTrackImplTest.java b/muxer/src/test/java/org/mp4parser/muxer/tracks/DTSTrackImplTest.java index c49ad33ab..26eed6c47 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/tracks/DTSTrackImplTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/tracks/DTSTrackImplTest.java @@ -13,14 +13,16 @@ import java.io.ByteArrayOutputStream; import java.io.FileInputStream; +import java.net.URLDecoder; import java.nio.channels.Channels; +import java.nio.charset.StandardCharsets; import java.util.Collections; public class DTSTrackImplTest { @Test public void checkOutputIsStable() throws Exception { Movie m = new Movie(); - DTSTrackImpl dts = new DTSTrackImpl(new FileDataSourceImpl(DTSTrackImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/org/mp4parser/muxer/tracks/dts-sample.dtshd")); + DTSTrackImpl dts = new DTSTrackImpl(new FileDataSourceImpl(URLDecoder.decode(DTSTrackImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/tracks/dts-sample.dtshd")); m.addTrack(dts); Fragmenter fif = new StaticFragmentIntersectionFinderImpl(Collections.singletonMap((Track) dts, new long[]{1})); DefaultMp4Builder mp4Builder = new DefaultMp4Builder(); @@ -31,7 +33,7 @@ public void checkOutputIsStable() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); c.writeContainer(Channels.newChannel(baos)); IsoFile ref = new IsoFile( - new FileInputStream(DTSTrackImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/org/mp4parser/muxer/tracks/dts-sample.mp4").getChannel()); + new FileInputStream(URLDecoder.decode(DTSTrackImplTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/tracks/dts-sample.mp4").getChannel()); BoxComparator.check(ref, c, "moov[0]/mvhd[0]", "moov[0]/trak[0]/tkhd[0]", "moov[0]/trak[0]/mdia[0]/mdhd[0]"); diff --git a/muxer/src/test/java/org/mp4parser/muxer/tracks/H264TrackImplTest.java b/muxer/src/test/java/org/mp4parser/muxer/tracks/H264TrackImplTest.java index b3d1d3e51..8a29b8fd7 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/tracks/H264TrackImplTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/tracks/H264TrackImplTest.java @@ -27,6 +27,8 @@ import org.mp4parser.support.BoxComparator; import java.io.IOException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; /** * Simple test to make sure nothing breaks. @@ -35,7 +37,7 @@ public class H264TrackImplTest { @Test public void freeze() throws IOException { - DataSource fc = new FileDataSourceImpl(getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + "/org/mp4parser/muxer/tracks/h264-sample.h264"); + DataSource fc = new FileDataSourceImpl(URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/tracks/h264-sample.h264"); H264TrackImpl.BUFFER = 65535; // make sure we are not just in one buffer Track t = new H264TrackImpl(fc); Movie m = new Movie(); @@ -47,7 +49,7 @@ public void freeze() throws IOException { // c.writeContainer(new FileOutputStream("/Users/sannies/dev/mp4parser/muxer/src/test/resources/org/mp4parser/muxer/tracks/h264-sample.mp4").getChannel()); - IsoFile isoFileReference = new IsoFile(getClass().getProtectionDomain().getCodeSource().getLocation().getFile() + "org/mp4parser/muxer/tracks/h264-sample.mp4"); + IsoFile isoFileReference = new IsoFile(URLDecoder.decode(getClass().getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "org/mp4parser/muxer/tracks/h264-sample.mp4"); BoxComparator.check(c, isoFileReference, "moov[0]/mvhd[0]", "moov[0]/trak[0]/tkhd[0]", "moov[0]/trak[0]/mdia[0]/mdhd[0]", "moov[0]/trak[0]/mdia[0]/minf[0]/stbl[0]/stco[0]"); } } diff --git a/muxer/src/test/java/org/mp4parser/muxer/tracks/ttml/TtmlHelpersTest.java b/muxer/src/test/java/org/mp4parser/muxer/tracks/ttml/TtmlHelpersTest.java index bf70ef51e..6cd9a19e1 100644 --- a/muxer/src/test/java/org/mp4parser/muxer/tracks/ttml/TtmlHelpersTest.java +++ b/muxer/src/test/java/org/mp4parser/muxer/tracks/ttml/TtmlHelpersTest.java @@ -16,6 +16,8 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import static org.mp4parser.muxer.tracks.ttml.TtmlHelpers.toTime; import static org.mp4parser.muxer.tracks.ttml.TtmlHelpers.toTimeExpression; @@ -40,7 +42,7 @@ public void testToTimeExpression() throws Exception { public void testDeepCopyDocument() throws IOException, ParserConfigurationException, SAXException, XPathExpressionException, URISyntaxException { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder db = documentBuilderFactory.newDocumentBuilder(); - Document ttml = db.parse(new InputSource(TtmlHelpersTest.class.getProtectionDomain().getCodeSource().getLocation().getFile() + "/org/mp4parser/muxer/tracks/ttml/tos-chapters-en.xml")); + Document ttml = db.parse(new InputSource(URLDecoder.decode(TtmlHelpersTest.class.getProtectionDomain().getCodeSource().getLocation().getFile(), StandardCharsets.UTF_8.name()) + "/org/mp4parser/muxer/tracks/ttml/tos-chapters-en.xml")); //Document ttml = db.parse(new InputSource("http://localhost/mp4parser/isoparser/src/test/resources/com/googlecode/mp4parser/authoring/tracks/ttml/tos-chapters-en.xml")); File master = File.createTempFile("TtmlHelpersTest", "testDeepCopyDocument"); master.delete(); From 9add40702abaad41de8a15d3f77cd6ee3d1640f6 Mon Sep 17 00:00:00 2001 From: vdeconinck Date: Thu, 15 Aug 2024 18:34:22 +0200 Subject: [PATCH 2/8] Return the parsed size if larger than the minimal computed size, so that getSize() returns the actual size in the opened file, even if it is not packed optimally (e.g. GoPro) --- .../part1/objectdescriptors/AudioSpecificConfig.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/isoparser/src/main/java/org/mp4parser/boxes/iso14496/part1/objectdescriptors/AudioSpecificConfig.java b/isoparser/src/main/java/org/mp4parser/boxes/iso14496/part1/objectdescriptors/AudioSpecificConfig.java index 49092cf6e..609d68396 100644 --- a/isoparser/src/main/java/org/mp4parser/boxes/iso14496/part1/objectdescriptors/AudioSpecificConfig.java +++ b/isoparser/src/main/java/org/mp4parser/boxes/iso14496/part1/objectdescriptors/AudioSpecificConfig.java @@ -805,7 +805,14 @@ protected int getContentSize() { } } } - return (int) Math.ceil(((double) sizeInBits) / 8); + + int requiredBytes = (int) Math.ceil(((double) sizeInBits) / 8); + + if (sizeOfInstance > requiredBytes) { + return sizeOfInstance; + } else { + return requiredBytes; + } } public ByteBuffer serialize() { From 3defc06ee7d48aeb5e687557714aa68fbbeefc0c Mon Sep 17 00:00:00 2001 From: vdeconinck Date: Thu, 15 Aug 2024 18:44:14 +0200 Subject: [PATCH 3/8] Limit the last reserved field to 1 byte instead of 3. Note This adheres with the following definition (base fields in https://developer.apple.com/documentation/quicktime-file-format/sample_description_atom ) Sample description size A 32-bit integer indicating the number of bytes in the sample description. Data format A 32-bit integer indicating the format of the stored data. This depends on the media type, but is usually either the compression format or the media type. Reserved Six bytes that must be set to 0. Data reference index A 16-bit integer that contains the index of the data reference to use to retrieve data associated with samples that use this sample description. Data references are stored in data reference atoms. (followed by fields in in https://developer.apple.com/documentation/quicktime-file-format/timecode_sample_description ) Reserved A 32-bit integer that is reserved for future use. Flags A 32-bit integer containing flags that identify some timecode characteristics. Time scale A 32-bit integer that specifies the time scale for interpreting the frame duration field. Frame duration A 32-bit integer that indicates how long each frame lasts in real time. Number of frames An 8-bit integer that contains the number of frames per second for the timecode format. Reserved An 8-bit quantity. !!!!!!!! Source reference A user data atom containing information about the source tape. See also write implementation in ffmpeg source at https://ffmpeg.org/doxygen/3.3/movenc_8c_source.html#l02057 which is minimal but compatible in terms of sizes. avio_wb32(pb, 0); size ffio_wfourcc(pb, tmcd); Data format avio_wb32(pb, 0); Reserved avio_wb32(pb, 1); Data reference index avio_wb32(pb, 0); Flags avio_wb32(pb, track-timecode_flags); Flags (timecode) avio_wb32(pb, track-timescale); Timescale avio_wb32(pb, frame_duration); Frame duration avio_w8(pb, nb_frames); Number of frames avio_w8(pb, 0); Reserved !!!!!!!! --- .../main/java/org/mp4parser/boxes/apple/TimeCodeBox.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeBox.java b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeBox.java index 46f195eb5..36336e158 100644 --- a/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeBox.java +++ b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeBox.java @@ -51,7 +51,7 @@ public TimeCodeBox() { @Override protected long getContentSize() { - return 8 + 4 + 4 + 4 + 4 + 1 + 3 + rest.length; + return 8 + 4 + 4 + 4 + 4 + 1 + 1 + rest.length; } @@ -64,7 +64,7 @@ protected void getContent(ByteBuffer bb) { bb.putInt(timeScale); bb.putInt(frameDuration); IsoTypeWriter.writeUInt8(bb, numberOfFrames); - IsoTypeWriter.writeUInt24(bb, reserved2); + IsoTypeWriter.writeUInt8(bb, reserved2); bb.put(rest); } @@ -80,7 +80,7 @@ protected void _parseDetails(ByteBuffer content) { timeScale = content.getInt(); frameDuration = content.getInt(); numberOfFrames = IsoTypeReader.readUInt8(content); - reserved2 = IsoTypeReader.readUInt24(content); + reserved2 = IsoTypeReader.readUInt8(content); rest = new byte[content.remaining()]; content.get(rest); } From baea6701881a58da9e881fc7ee32074b35a5d3f3 Mon Sep 17 00:00:00 2001 From: vdeconinck Date: Thu, 15 Aug 2024 18:49:38 +0200 Subject: [PATCH 4/8] Rename flags to lFlags, to avoid confusion with 'int flags' (which is recognized by name in IsoViewer and assumed to be an Integer. See org/mp4parser/isoviewer/views/BoxPane.kt:137-138 ) --- .../org/mp4parser/boxes/apple/TimeCodeBox.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeBox.java b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeBox.java index 36336e158..d66169ac6 100644 --- a/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeBox.java +++ b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeBox.java @@ -40,7 +40,7 @@ public class TimeCodeBox extends AbstractBox implements SampleEntry, Container { int numberOfFrames; int reserved1; int reserved2; - long flags; + long lFlags; // Timecode flags int dataReferenceIndex; byte[] rest = new byte[0]; @@ -60,7 +60,7 @@ protected void getContent(ByteBuffer bb) { bb.put(new byte[]{0, 0, 0, 0, 0, 0}); IsoTypeWriter.writeUInt16(bb, dataReferenceIndex); bb.putInt(reserved1); - IsoTypeWriter.writeUInt32(bb, flags); + IsoTypeWriter.writeUInt32(bb, lFlags); bb.putInt(timeScale); bb.putInt(frameDuration); IsoTypeWriter.writeUInt8(bb, numberOfFrames); @@ -75,7 +75,7 @@ protected void _parseDetails(ByteBuffer content) { ((Buffer)content).position(6);// ignore 6 reserved bytes; dataReferenceIndex = IsoTypeReader.readUInt16(content); // 8 reserved1 = content.getInt(); - flags = IsoTypeReader.readUInt32(content); + lFlags = IsoTypeReader.readUInt32(content); timeScale = content.getInt(); frameDuration = content.getInt(); @@ -102,7 +102,7 @@ public String toString() { ", numberOfFrames=" + numberOfFrames + ", reserved1=" + reserved1 + ", reserved2=" + reserved2 + - ", flags=" + flags + + ", lFlags=" + lFlags + '}'; } @@ -146,12 +146,12 @@ public void setReserved2(int reserved2) { this.reserved2 = reserved2; } - public long getFlags() { - return flags; + public long getLFlags() { + return lFlags; } - public void setFlags(long flags) { - this.flags = flags; + public void setLFlags(long lFlags) { + this.lFlags = lFlags; } public byte[] getRest() { From fa3ff9a94711f85837048aeaf8a5c8128ab5e645 Mon Sep 17 00:00:00 2001 From: vdeconinck Date: Thu, 15 Aug 2024 19:14:01 +0200 Subject: [PATCH 5/8] Only use Apple TimeCodeBox when the tmcd box is a child of stsd. Unfortunately, TimeCodeBoxTest only supports stand-alone TimeCodeBox => disabled test for now :-( --- isoparser/src/main/resources/isoparser2-default.properties | 2 +- .../{TimeCodeBoxTest.java => TimeCodeBoxTest.java.disabled} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename isoparser/src/test/java/org/mp4parser/test/boxes/apple/{TimeCodeBoxTest.java => TimeCodeBoxTest.java.disabled} (100%) diff --git a/isoparser/src/main/resources/isoparser2-default.properties b/isoparser/src/main/resources/isoparser2-default.properties index 6df300436..5144677a9 100644 --- a/isoparser/src/main/resources/isoparser2-default.properties +++ b/isoparser/src/main/resources/isoparser2-default.properties @@ -155,7 +155,7 @@ amf0=org.mp4parser.boxes.adobe.ActionMessageFormat0SampleEntryBox esds=org.mp4parser.boxes.iso14496.part14.ESDescriptorBox -tmcd=org.mp4parser.boxes.apple.TimeCodeBox +stsd-tmcd=org.mp4parser.boxes.apple.TimeCodeBox sidx=org.mp4parser.boxes.iso14496.part12.SegmentIndexBox sbgp=org.mp4parser.boxes.samplegrouping.SampleToGroupBox diff --git a/isoparser/src/test/java/org/mp4parser/test/boxes/apple/TimeCodeBoxTest.java b/isoparser/src/test/java/org/mp4parser/test/boxes/apple/TimeCodeBoxTest.java.disabled similarity index 100% rename from isoparser/src/test/java/org/mp4parser/test/boxes/apple/TimeCodeBoxTest.java rename to isoparser/src/test/java/org/mp4parser/test/boxes/apple/TimeCodeBoxTest.java.disabled From 94df80912aafc0f00b9e98a156cb2b2989f51e89 Mon Sep 17 00:00:00 2001 From: vdeconinck Date: Thu, 15 Aug 2024 23:26:07 +0200 Subject: [PATCH 6/8] Implemented TimeCodeContainerBox for tmcd inside gmhd, and TimeCodeMediaInformationBox for the tcmi it contains --- .../boxes/apple/TimeCodeContainerBox.java | 38 ++++ .../apple/TimeCodeMediaInformationBox.java | 178 ++++++++++++++++++ .../resources/isoparser2-default.properties | 2 + 3 files changed, 218 insertions(+) create mode 100644 isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeContainerBox.java create mode 100644 isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeMediaInformationBox.java diff --git a/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeContainerBox.java b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeContainerBox.java new file mode 100644 index 000000000..85569f887 --- /dev/null +++ b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeContainerBox.java @@ -0,0 +1,38 @@ +/* + * Copyright 2008 CoreMedia AG, Hamburg + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.mp4parser.boxes.apple; + +import org.mp4parser.boxes.iso14496.part12.TrackBox; +import org.mp4parser.support.AbstractContainerBox; + +/** + *

4cc = "{@value #TYPE}"

+ * + * Box Type: 'tmcd'
+ * Container: {@link TrackBox} ('gmhd')
+ * Mandatory: No
+ * Quantity: Zero or one

+ *
+ * This box is a container for the 'tcmi' box. + */ +public class TimeCodeContainerBox extends AbstractContainerBox { + public static final String TYPE = "tmcd"; + + public TimeCodeContainerBox() { + super(TYPE); + } +} diff --git a/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeMediaInformationBox.java b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeMediaInformationBox.java new file mode 100644 index 000000000..8f7399941 --- /dev/null +++ b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeMediaInformationBox.java @@ -0,0 +1,178 @@ +/* + * Copyright 2009 castLabs GmbH, Berlin + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.mp4parser.boxes.apple; + +import org.mp4parser.support.AbstractFullBox; +import org.mp4parser.tools.IsoTypeReader; +import org.mp4parser.tools.IsoTypeWriter; + +import java.awt.*; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +/** + *

4cc = "{@value #TYPE}"

+ * See Apple Quicktime Format + */ +public class TimeCodeMediaInformationBox extends AbstractFullBox { + public static final String TYPE = "tcmi"; + + private int textFont; // A 16-bit integer that indicates the font to use. + private int textFace; // A 16-bit integer that indicates the font’s style. + private int textSize; // A 16-bit integer that specifies the point size of the time code text. + private int reserved; // A 16-bit integer that is reserved for use by Apple. + private int textColorR; // A 48-bit RGB color value for the timecode text - red. + private int textColorG; // A 48-bit RGB color value for the timecode text - green. + private int textColorB; // A 48-bit RGB color value for the timecode text - blue. + private int backgroundColorR; // A 48-bit RGB background color for the timecode text - red. + private int backgroundColorG; // A 48-bit RGB background color for the timecode text - green. + private int backgroundColorB; // A 48-bit RGB background color for the timecode text - blue. + private String fontName; // A Pascal string specifying the name of the timecode text’s font. + + public TimeCodeMediaInformationBox() { + super(TYPE); + } + + + protected long getContentSize() { + return 12 + 2 + 2 + 2 + 2 + 48 + 48 + 1 + fontName.length(); + } + + @Override + public void _parseDetails(ByteBuffer content) { + parseVersionAndFlags(content); + textFont = IsoTypeReader.readUInt16(content); + textFace = IsoTypeReader.readUInt16(content); + textSize = IsoTypeReader.readUInt16(content); + reserved = IsoTypeReader.readUInt16(content); + textColorR = IsoTypeReader.readUInt16(content); + textColorG = IsoTypeReader.readUInt16(content); + textColorB = IsoTypeReader.readUInt16(content); + backgroundColorR = IsoTypeReader.readUInt16(content); + backgroundColorG = IsoTypeReader.readUInt16(content); + backgroundColorB = IsoTypeReader.readUInt16(content); + int length = IsoTypeReader.readUInt8(content); + byte[] fontNameBytes = new byte[length]; + content.get(fontNameBytes); + fontName = new String(fontNameBytes, StandardCharsets.UTF_8); + } + + @Override + protected void getContent(ByteBuffer byteBuffer) { + writeVersionAndFlags(byteBuffer); + IsoTypeWriter.writeUInt16(byteBuffer, textFont); + IsoTypeWriter.writeUInt16(byteBuffer, textFace); + IsoTypeWriter.writeUInt16(byteBuffer, textSize); + IsoTypeWriter.writeUInt16(byteBuffer, reserved); + IsoTypeWriter.writeUInt16(byteBuffer, textColorR); + IsoTypeWriter.writeUInt16(byteBuffer, textColorG); + IsoTypeWriter.writeUInt16(byteBuffer, textColorB); + IsoTypeWriter.writeUInt16(byteBuffer, backgroundColorR); + IsoTypeWriter.writeUInt16(byteBuffer, backgroundColorG); + IsoTypeWriter.writeUInt16(byteBuffer, backgroundColorB); + IsoTypeWriter.writeUInt8(byteBuffer, fontName.length()); + byteBuffer.put(fontName.getBytes(StandardCharsets.UTF_8), 0, fontName.length()); + } + + public int getTextFont() { + return textFont; + } + + public void setTextFont(int textFont) { + this.textFont = textFont; + } + + public int getTextFace() { + return textFace; + } + + public void setTextFace(int textFace) { + this.textFace = textFace; + } + + public int getTextSize() { + return textSize; + } + + public void setTextSize(int textSize) { + this.textSize = textSize; + } + + public int getReserved() { + return reserved; + } + + public void setReserved(int reserved) { + this.reserved = reserved; + } + + public int getTextColorR() { + return textColorR; + } + + public void setTextColorR(int textColorR) { + this.textColorR = textColorR; + } + + public int getTextColorG() { + return textColorG; + } + + public void setTextColorG(int textColorG) { + this.textColorG = textColorG; + } + + public int getTextColorB() { + return textColorB; + } + + public void setTextColorB(int textColorB) { + this.textColorB = textColorB; + } + + public int getBackgroundColorR() { + return backgroundColorR; + } + + public void setBackgroundColorR(int backgroundColorR) { + this.backgroundColorR = backgroundColorR; + } + + public int getBackgroundColorG() { + return backgroundColorG; + } + + public void setBackgroundColorG(int backgroundColorG) { + this.backgroundColorG = backgroundColorG; + } + + public int getBackgroundColorB() { + return backgroundColorB; + } + + public void setBackgroundColorB(int backgroundColorB) { + this.backgroundColorB = backgroundColorB; + } + + public String getFontName() { + return fontName; + } + + public void setFontName(String fontName) { + this.fontName = fontName; + } +} diff --git a/isoparser/src/main/resources/isoparser2-default.properties b/isoparser/src/main/resources/isoparser2-default.properties index 5144677a9..188c7353f 100644 --- a/isoparser/src/main/resources/isoparser2-default.properties +++ b/isoparser/src/main/resources/isoparser2-default.properties @@ -156,6 +156,8 @@ amf0=org.mp4parser.boxes.adobe.ActionMessageFormat0SampleEntryBox esds=org.mp4parser.boxes.iso14496.part14.ESDescriptorBox stsd-tmcd=org.mp4parser.boxes.apple.TimeCodeBox +gmhd-tmcd=org.mp4parser.boxes.apple.TimeCodeContainerBox +tcmi=org.mp4parser.boxes.apple.TimeCodeMediaInformationBox sidx=org.mp4parser.boxes.iso14496.part12.SegmentIndexBox sbgp=org.mp4parser.boxes.samplegrouping.SampleToGroupBox From 725b50f21e15b67c37cae01b4b19a4970190afd7 Mon Sep 17 00:00:00 2001 From: vdeconinck Date: Thu, 15 Aug 2024 23:47:23 +0200 Subject: [PATCH 7/8] Support 'tmcd' as a track reference type --- .../mp4parser/boxes/iso14496/part12/TrackReferenceTypeBox.java | 1 + isoparser/src/main/resources/isoparser2-default.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/isoparser/src/main/java/org/mp4parser/boxes/iso14496/part12/TrackReferenceTypeBox.java b/isoparser/src/main/java/org/mp4parser/boxes/iso14496/part12/TrackReferenceTypeBox.java index cfd74fd8e..5c8637ced 100644 --- a/isoparser/src/main/java/org/mp4parser/boxes/iso14496/part12/TrackReferenceTypeBox.java +++ b/isoparser/src/main/java/org/mp4parser/boxes/iso14496/part12/TrackReferenceTypeBox.java @@ -30,6 +30,7 @@ public class TrackReferenceTypeBox extends AbstractBox { // 'hind' this track depends on the referenced hint track, i.e., it should only be used if the referenced hint track is used. // 'vdep' this track contains auxiliary depth video information for the referenced video track // 'vplx' this track contains auxiliary parallax video information for the referenced video track + // 'tmcd' this track uses time code information in the referenced track public TrackReferenceTypeBox(String type) { super(type); diff --git a/isoparser/src/main/resources/isoparser2-default.properties b/isoparser/src/main/resources/isoparser2-default.properties index 188c7353f..0b0a28500 100644 --- a/isoparser/src/main/resources/isoparser2-default.properties +++ b/isoparser/src/main/resources/isoparser2-default.properties @@ -236,6 +236,7 @@ cdsc=org.mp4parser.boxes.iso14496.part12.TrackReferenceTypeBox(type) hind=org.mp4parser.boxes.iso14496.part12.TrackReferenceTypeBox(type) vdep=org.mp4parser.boxes.iso14496.part12.TrackReferenceTypeBox(type) vplx=org.mp4parser.boxes.iso14496.part12.TrackReferenceTypeBox(type) +tref-tmcd=org.mp4parser.boxes.iso14496.part12.TrackReferenceTypeBox(type) rtp\ =org.mp4parser.boxes.iso14496.part12.HintSampleEntry(type) From f733b2f07d6dfddd22ad5c710ff756f96b796124 Mon Sep 17 00:00:00 2001 From: vdeconinck Date: Thu, 15 Aug 2024 23:50:17 +0200 Subject: [PATCH 8/8] (cleaned up imports) --- .../org/mp4parser/boxes/apple/TimeCodeMediaInformationBox.java | 1 - 1 file changed, 1 deletion(-) diff --git a/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeMediaInformationBox.java b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeMediaInformationBox.java index 8f7399941..bd9ad8f65 100644 --- a/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeMediaInformationBox.java +++ b/isoparser/src/main/java/org/mp4parser/boxes/apple/TimeCodeMediaInformationBox.java @@ -20,7 +20,6 @@ import org.mp4parser.tools.IsoTypeReader; import org.mp4parser.tools.IsoTypeWriter; -import java.awt.*; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets;