Issue with incorrect integer values

Issue #606 closed
Nolaine Crusher created an issue

Hi. I’m creating a file using a very simplified library I’m creating for reading and writing metadata (much less comprehensive that Mp42Foundation) and it appears my conversion from integer to data and back isn’t playing nicely with Subler.

This is what I see when I view the file in MediaInfo:

Season is 12, Episode is 17, BPM is 99, Movement Count is 13 and Movement Index is 11. All of which are correct. I also see the correct results when viewing in Yate, FFProbe, Atomic Parsley, and Fission. (Kid3 doesn’t show anything, or shows weird characters for some of them, but then I’ve found Kid3 to be iffy with those values when written by Subler as well.)

AtomicParsley /Users/nolainecrusher/Desktop/TestOutput/integer_test.m4a -t
Atom "akID" contains: 123456
Atom "atID" contains: 345678
Atom "tmpo" contains: 99
Atom "cpil" contains: true
Atom "cmID" contains: 567890
Atom "cnID" contains: 789012
Atom "pgap" contains: 1
Atom "geID" contains: 901234
Atom "stik" contains: Audiobook
Atom "©mvc" contains: 13
Atom "©mvi" contains: 11
Atom "plID" contains: 234567
Atom "pcst" contains: true
Atom "rtng" contains: Clean Content
Atom "shwm" contains: 1
Atom "tves" contains: 17
Atom "tvsn" contains: 12

This is what I see when I view it with Subler:

I’m not sure which part of this is my code, which part is Subler’s, which part is Mp4v2, and which part is AVFoundation, but clearly there’s a breakdown somewhere in here.

Comments (7)

  1. Adam

    You mentioned that you are using multiple apps to input data to the file? Can you do a clean conversion where you can compare multiple files so it can be more clear on what is going on?

  2. Nolaine Crusher reporter

    No, I’m not using multiple apps to create the file. Just my own library to write the metadata.

    I’ve viewed the resulting file in multiple apps, and Subler is the only one that shows strange values for some of the integers. But since Subler uses AVFoundation and Mp42Foundation for handling atoms, it’s possible the problem lies there rather than in Subler, directly.

  3. Nolaine Crusher reporter

    Hi, sorry for the delay. I had a family thing.

    Here is a sample file.

    Here’s what MediaInfo reports for BPM, TV Episode Number and TV Season, playlist ID, movement index and movement count:

    Season : 6
    Part : 7
    BPM : 99
    mvc : 9
    mvi : 8
    PlayListID : 678901

    And here is what Yate shows for BPM, movement count and movement index:

    BPM: 99
    Movement Number: 8
    Movement Count: 9

    It could totally be the way I’m doing things that is the problem, but that begs the question of why most other apps would recognize the way I’m handling those values as valid while Subler doesn’t?

    I look forward to solving this with you!

  4. Nolaine Crusher reporter

    Upon further experimentation, I think the problem is a combination of the way I was doing things, and a certain inflexibility in what Subler allows for these values. Subler will only read tmpo, ©mvi, and ©mvc correctly if they’re handled as 16-bit integers , which I suspect is due to the way AVFoundation handles them. plID has to be handled as a 64-bit integer (also in keeping with AVFoundation). However, interestingly, Subler expects some of the boolean integers that AVFoundation says should be 64-bit (nonsensically, imo) to be 8-bit instead.

    So basically, this is how I got Subler reading the output from my library correctly:

        private static func integerHandling(forIdentifier name: String) -> Int {
            switch name {
                case "rtng", "cpil", "pcst", "stik", "pgap", "shwm":
                    return 8
                case "tmpo", "\u{00A9}mvi", "\u{00A9}mvc":
                    return 16
                case "geID", "tves", "tvsn":
                    return 32
                case "plID":
                    return 64
                default:
                    return 32
            }
        }
    
    // then in the initializer for the data atom...
    
            let handling = DataAtom.integerHandling(forIdentifier: name)
            if handling == 8 {
                // handle as 8 bit
            } else if handling == 16 {
                // handle as 16 bit
            } else if handling == 32 {
                // handle as 32 bit
            } else {
                // handle as 64 bit
            }
    

    It appears the reason other apps would read these correctly is that they’re just more flexible in how they permit these values to be encoded. So that may or may not be something you wish to address.

  5. Damiano Galassi repo owner

    Those tags are supposed to have a fixed size, and the value is store in big endian. So if you store less bytes, mp4v2 will convert from big endian to little endian and flip the bytes, and you get those big values.

  6. Log in to comment