diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt index 9135f9430..12f098cbf 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/channel/calls/DebugHandler.kt @@ -41,8 +41,11 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import org.beyka.tiffbitmapfactory.TiffBitmapFactory import org.mp4parser.IsoFile +import org.mp4parser.PropertyBoxParserImpl +import org.mp4parser.boxes.iso14496.part12.MediaDataBox +import org.mp4parser.boxes.iso14496.part12.SampleTableBox +import java.io.FileInputStream import java.io.IOException -import java.nio.channels.Channels class DebugHandler(private val context: Context) : MethodCallHandler { private val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) @@ -335,10 +338,19 @@ class DebugHandler(private val context: Context) : MethodCallHandler { val sb = StringBuilder() if (mimeType == MimeTypes.MP4) { try { - StorageUtils.openInputStream(context, uri)?.use { input -> - Channels.newChannel(input).use { channel -> - IsoFile(channel).use { isoFile -> - isoFile.dumpBoxes(sb) + // we can skip uninteresting boxes with a seekable data source + val pfd = StorageUtils.openInputFileDescriptor(context, uri) ?: throw Exception("failed to open file descriptor for uri=$uri") + pfd.use { + FileInputStream(it.fileDescriptor).use { stream -> + stream.channel.use { channel -> + val boxParser = PropertyBoxParserImpl().apply { + // parsing `MediaDataBox` can take a long time + // parsing `SampleTableBox` may yield OOM + skippingBoxes(MediaDataBox.TYPE, SampleTableBox.TYPE) + } + IsoFile(channel, boxParser).use { isoFile -> + isoFile.dumpBoxes(sb) + } } } } diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Mp4ParserHelper.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Mp4ParserHelper.kt index d9cd24c6e..c479e8b4c 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Mp4ParserHelper.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/Mp4ParserHelper.kt @@ -22,6 +22,8 @@ object Mp4ParserHelper { FileInputStream(it.fileDescriptor).use { stream -> stream.channel.use { channel -> val boxParser = PropertyBoxParserImpl().apply { + // parsing `MediaDataBox` can take a long time + // do not skip anything inside `MovieBox` as it will be parsed and rewritten for editing skippingBoxes(MediaDataBox.TYPE) } // creating `IsoFile` with a `File` or a `File.inputStream()` yields `No such device` diff --git a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt index 55596ed03..4eeab81f4 100644 --- a/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt +++ b/android/app/src/main/kotlin/deckers/thibault/aves/metadata/XMP.kt @@ -23,6 +23,7 @@ import org.mp4parser.IsoFile import org.mp4parser.PropertyBoxParserImpl import org.mp4parser.boxes.UserBox import org.mp4parser.boxes.iso14496.part12.MediaDataBox +import org.mp4parser.boxes.iso14496.part12.SampleTableBox import java.io.FileInputStream import java.util.* @@ -142,7 +143,9 @@ object XMP { FileInputStream(it.fileDescriptor).use { stream -> stream.channel.use { channel -> val boxParser = PropertyBoxParserImpl().apply { - skippingBoxes(MediaDataBox.TYPE) + // parsing `MediaDataBox` can take a long time + // parsing `SampleTableBox` may yield OOM + skippingBoxes(MediaDataBox.TYPE, SampleTableBox.TYPE) } // creating `IsoFile` with a `File` or a `File.inputStream()` yields `No such device` IsoFile(channel, boxParser).use { isoFile ->