B4J Code Snippet Check an mp4 file is structurally complete - courtesy of Claude code

B4X:
'************************************************************************************
'
'This procedure checks an mp4 file is structurally complete - courtesy of Claude code
'
'Input parameters are:
'
'       Directory = directory holding mp4 file
'       Filename = name of mp4 file
'
'Returns:
'
'       True if a moov box is present, False otherwise - top level boxes are also
'       checked to see if they tile file exactly, but that is currently reported
'       rather than enforced (see notes)
'
'Notes on this procedure:
'
'       o An mp4 is a chain of top level boxes, each of form:
'             4 bytes big endian box size (includes this 8 byte header)
'             4 bytes box type, e.g. ftyp, free, mdat, moov
'         a box size of 1 means real size is a 64 bit value following box type, a
'         box size of 0 means box runs to end of file (only legal for last box)
'
'       o A truncated mp4 is caught because its last box (typically mdat, which
'         holds video data and is by far largest) claims a size that overruns end
'         of file - ffmpeg output typically carries moov last, so a truncated file
'         also loses moov and is unplayable
'
'       o Tiling test is deliberately not enforced - it is stricter than moov test
'         and a valid file carrying trailing padding after its last box would fail
'         it - any shortfall is logged instead, so Run log can be checked over
'         time before deciding to enforce it
'
'       o Box size is read a byte at a time and accumulated into a Long because it
'         is an unsigned 32 bit value - ReadInt would return it signed and mdat
'         exceeds 2GB on long videos
'
'       o jRandomAccessFile must be available to project
'
'************************************************************************************
Private Sub Is_Complete_MP4(Directory As String, Filename As String) As Boolean

    'If file has gone missing...
    If Not(File.Exists(Directory, Filename)) Then Return False

    Private wrk_size As Long = File.Size(Directory, Filename)

    'If too small to hold even one box header...
    If wrk_size < 8 Then Return False

    Private wrk_raf As RandomAccessFile
    Private wrk_type(4) As Byte
    Private wrk_pos As Long
    Private wrk_boxsize As Long
    Private wrk_moov As Boolean
    Private wrk_tiles As Boolean

    Try

        'Open read only - default byte order is big endian, which is what mp4 uses
        wrk_raf.Initialize(Directory, Filename, True)

        'Walk top level boxes while a full box header remains...
        Do While wrk_pos + 8 <= wrk_size

            'Get box size
            wrk_boxsize = wrk_raf.ReadUnsignedByte(wrk_pos)
            wrk_boxsize = wrk_boxsize * 256 + wrk_raf.ReadUnsignedByte(wrk_pos + 1)
            wrk_boxsize = wrk_boxsize * 256 + wrk_raf.ReadUnsignedByte(wrk_pos + 2)
            wrk_boxsize = wrk_boxsize * 256 + wrk_raf.ReadUnsignedByte(wrk_pos + 3)

            'Get box type
            wrk_raf.ReadBytes(wrk_type, 0, 4, wrk_pos + 4)

            'If box size is 1, real size is 64 bit value following box type...
            If wrk_boxsize = 1 Then

                'If that 64 bit size is not all there then file is truncated
                If wrk_pos + 16 > wrk_size Then Exit

                wrk_boxsize = wrk_raf.ReadLong(wrk_pos + 8)

            'Otherwise, if box size is 0, box runs to end of file...
            Else If wrk_boxsize = 0 Then

                wrk_boxsize = wrk_size - wrk_pos

            End If

            'If box is impossibly small or overruns end of file then file is
            'truncated or corrupt...
            If wrk_boxsize < 8 Or wrk_pos + wrk_boxsize > wrk_size Then Exit

            'Note moov - without it file is unplayable
            If BytesToString(wrk_type, 0, 4, "ISO-8859-1") = "moov" Then wrk_moov = True

            'Step to next box
            wrk_pos = wrk_pos + wrk_boxsize

        Loop

        'Boxes should tile file exactly - reported rather than enforced, see notes
        wrk_tiles = (wrk_pos = wrk_size)

        wrk_raf.Close

    Catch

        Log(LastException)

        Try
            wrk_raf.Close
        Catch
            Log(LastException)
        End Try

        Return False

    End Try

    'Log any tiling shortfall so it can be seen whether test is safe to enforce
    If wrk_moov And Not(wrk_tiles) Then
        Log("mp4 " & Filename & " accepted with moov but top level boxes stop at " & wrk_pos & " of " & wrk_size & " bytes")
    End If

    'Complete if moov was present - to also enforce tiling, change this to
    '[Return wrk_tiles And wrk_moov]
    Return wrk_moov

End Sub

My use case was checking a mp4 survived an FTP upload.
 
Last edited:
Top