Deciding on how to track media format information

The time has come to make a decision on how to manage media format and compatibility information, because I am now actively working on a project that needs to present large amounts of this information to users.

One option is just to code tables onto MDN and let it go at at that.

However, the other option may be a better one: to devise schema to use JSON files.

There are a few things we have to track information about when providing compatibility information for media. We probably want to have the container and codec information in the mdn-data repository, then the browser compatibility for them in BCD.

Some thoughts on the data we would need:

Containers (File types): MediaContainerInfo.json

  • What types are supported by each browser (MPEG, MP4, AVI, MOV, etc)?
  • For each type, need to specify its full name and optional short name (MPEG 4 vs MP4) mimetype(s), extension(s), allowed codecs (per specification), spec URL, container features (VBR, VFR, captions, metadata, streaming, etc) and potentially any notes about the file type
  • Also for each type, whether it’s patent encumbered and potentially who owns it

Codecs (Content formats): MediaCodecInfo.json

  • For each type of media (audio or video), list of the known codecs and data about them, including: codec full name and optional short name (MPEG 1 Layer III vs MP3), spec URL, notes, codec features (VBR, VFR, captions, streaming, etc) per the codec spec
  • Whether the codec is patent encumbered and if so who owns it
  • For each browser, which codecs does it permit in which container types? Which of the codec features does it support and perhaps optional notes about the support level
  • Notes about the codec overall

Browser compatibility (Containers): MediContainers.json

  • For each container listed in MediaContainerInfo.json, a list of records for each browser. Each record identifies the browser, whether or not the container is supported, and then a list of the supported container features, as well as potentially some notes etc

Browser compatibility (Codecs): MediaCodecs.json

  • For each codec in MediaCodecInfo.json, a list of records for each browser. Each record indicates whether the browser supports the codec, which codec features are supported, and so on.

A setup structured roughly like that makes it possible to look at the container list, see that a browser supports a given container, and from there also get a list of the codecs permitted by that browser in that container. Then we can look up the information about those codecs in the codec database, pulling out the browser-specific details so we can build a table that lists the video codecs down one axis, the video container types across the other, and in each table cell whether or not a given browser supports that pair of codec and container and any added info of note about that pairing.

But we have the flexibility to do a lot of different things, like offer a tool to let people isolate all the combinations available to them that can be used on a given selection of browsers.

Worth noting the existence of https://github.com/mdn/browser-compat-data/pull/2359, which is where this conversation first kicked off. There’s useful info there.

1 Like

So the last two would be regular BCD compat files, whereas the first two would contain expanded information on the codecs and containers?

This sounds like a reasonable attempt. I wonder if this could be a bit overcomplicated and repetitious, since it sounds like you are saying each of the first two will contain information on what browser supports certain combinations:

  1. For the first one, what codecs are allowed inside each listed container, and what browsers support each combination?
  2. For the second one, what containers can contain each listed codec, and what browsers support each combination?

Would it not perhaps be better to still have the two metadata type JSON structures, but simplified to remove all of that support type information, and then in the BCD itself have a folder called media, which contains a separate file for each container, and then in each file you have an entry for the basic container support, and then an entry for each codec’s support inside that container?

So something like

  • media/
    • MP4.json
      • H.264
        • firefox support
        • chrome support
        • etc.
      • AAC
        • firefox support
        • chrome support
        • etc.
      • MP3
        • …

If I’ve misunderstood you, then apologies :wink: Some diagrams and further info on how we’d use these would be appreciated.

Also, that about image formats?

1 Like

Right; the first two would go in the mdn-data repo, presumably, and would be general information about the codecs and containers.

Actually, no. The first two would only talk about what the specifications say the containers and codecs can do, not what any browsers are capable of. They would exist entirely outside the notion of browser support for their features. So when the codec list says that the codec supports VBR, 16-bit integer, 24-bit integer, and floating-point samples, stereo and multi-channel surround sound, etc., that means only that. The codec can handle it. Whether or not a given browser’s implementation is able to deal with each of those features would be covered in the BCD data for the codec.

This is useful because each container and each codec has a set of features it is technically capable of supporting. This is useful information to track and be able to present. Then, additionally and separately, for each browser, it’s useful to know which containers and which codecs they support, and for each of those, which features it is able to handle.

There are several reasons I like the approach I’m suggesting:

  • The more files involved the more performance will take a hit while trying to accumulate needed data. Having separate folders and files for each codec, etc, seems like trouble to me.
  • The ability to separate the descriptions of the formats from the browser information means we can more easily, for instance, update the capabilities of a codec if the spec is revised.
  • Maybe H.265 gets a new HASA (hyperacoustic supersonic audio mode, and yes, that’s something I just made up as an example) added to it. All we have to do is add a tidbit to the MediaCodecInfo.json file under the h265 object that adds to its list of supported features an entry for hasa. Since none of the browsers in BCD’s MediaCodecs.json file have an entry for HASA, it’s understood that they don’t support it, even though the spec for H.265 does.
  • This information can then easily be used to build a feature table that lists HASA but that no browsers support it yet, for instance. Not to mention tables showing the capabilities of each codec at a fundamental level. Wonderfulness!

OK, I’m starting to get this now! Yes, this sounds like a good idea. I’d still like to see some sample JSON in action.

Yes, I’m going to be working on some sample JSON today.

It just occurred to me that there’s a set of fundamental questions we haven’t answered yet, which is something that should be handled before we go too far into this:

  1. How much detail should the data file describing containers go into, beyond simply providing their names and which codecs they support for audio and/or video?
  2. How much detail should the codec info file go into describing the capabilities of each codec? Should they simply be a short name mapped to a full name and other basic info, or should they cover a set of capabilities, such as maximum bitrates and whether they support things like VBR and such?
  3. How much detail do we want to get into when describing what each browser is able to do? Should the browser data just list which containers it supports and which codecs it can use within each container, or should it go over which detailed features (assuming the previous answers were "go into detail) the browser can handle?

Until these are answered, seriously considering data formats (let alone the proper presentation on the site) is not feasible.

I’d appreciate any feedback or thoughts at all.

So based on my understanding, the first two files would go into mdn‑data, and the last two would go into browser‑compat‑data.

One thing to bear in mind is that the data set is fairly small, so we can add more data in the future if desired. I wouldn’t stall on not having the perfect data set up front (perfect being the enemy of good, etc.)

My immediate thoughts are:

Containers:

  • File extensions
  • MIME types
  • Open/Proprietary
  • Common/recommended uses
  • Best codec combination for maximum interoperability

Codecs:

  • Open/proprietary
  • Lossless/lossy
  • max bitrate
  • Some kind of relative size measure (e.g. mb or gb per minute)

Browsers:

  • I’m not sure exactly what to show for each browser’s support. I’d say you eventually need to go into more details, but an MVP for this could just be general display/playback support for that codec/container.
1 Like

I agree that we don’t have to have all the information for starters. I mostly want to make sure we cover the basics and leave ourselves room to expand to cover more details over time, instead of locking in a format that can’t be expanded without rewriting a lot of code too.

1 Like

OK, I’ve got a rough pass done at JSON structure for the data. Here’s what I have. Feedback is appreciated. The next step will probably be to actually create the files in the repos and start putting data in to see how it goes.

As before, there are four files, two in mdn/data and two in mdn/browser-compat-data. Those files are:

  • mdn/data
    • MediaContainers.json: List of media container formats that are or may be available on the web
    • MediaCodecs.json: List of media codecs that are or may be available
  • mdn/browser-compat-data
    • ContainerSupport.json: For each browser, information on which container formats they support
    • CodecSupport.json: For each browser, information about codecs they support and the containers that they’re allowed in

In all cases, these formats are set up to be expandable so we can add more details about each format as we feel the need to do so.

Container format info: MediaContainers.json

The file MediaContainers.json provides information about the set of container formats (file types) that may be supported by browsers. The JSON looks like this:

{
  "container-id": {
    "short_name": string,
    "full_name": string,
    "specs": url or array of urls,
    "license": {
      "id": spdx license identifier,
      [optional] "notes": string or array of strings
    },
    "audio": {
      "mimetypes": array of strings,
      "extensions": array of strings,
      "codecs": {
        {
          "codec-id1": boolean or {
            [optional] "mimetypes": array of strings,
            [optional] "extensions": array of strings
          },
          ...
          "codec-idN": {
            ...
          }
        }
      }
    
    },
    "video": {
    },
    [optional] "preferred_codecs": preferred-codecs-descriptor,
    [optional] "notes": string or array of strings
  },
  ... more containers until all described
}
  • The license.id is an ID from the SPDX license list at https://spdx.org/licenses/
  • Each container has two parts, audio and video, to provide any details for each of these, including the codecs permitted by the spec for each. There is room to add more details here over time.
  • The codecs lists contain one entry for each codec supported by the spec; if a codec isn’t supported, it should not be in the list. Each entry’s key is the ID of a codec from the MediaCodecs.json file, and the value is either a boolean which should be true (a value of false should not be used) or an object providing additional details about the codec’s capabilities when used with that codec.
  • Each container has a list of MIME types and filename extensions. Each codec can also have these, optionally, to override the container’s default lists when that codec is used. For example, the normal MIME type for an MPEG audio file is audio/mpeg, but if the codec is MPEG-1 Audio Layer III, the MIME type becomes audio/mp3 and the extension becomes mp3.
  • The video block is structurally identical to the audio one, at least for now. If we start adding more details like whether or not VBR is allowed, or whether the container supports HDR, then they’ll start to diverge.

preferred-codecs-descriptor

A container definition can, optionally, include a preferred_codecs object that specifies the best, most common, or ideal codecs to use inside that container. That object’s value, a preferred-codecs-descriptor, is an object like this:

{
  "audio_only": string,
  "audio_video": {
    "audio": string,
    "video": string
  }
}
  • audio_only: The codec-id of a a codec that’s preferred for audio-only media inside this container
  • audio_video: An object specifying the preferred audio and video codecs for this container; applies to both video-only and audio-video media.

The idea here is that some containers have codecs that are most commonly used, or are generally considered the best choice. This block would let those codecs be identified (by their codec ID string) for both audio-only and audio/video files.

Codec info: MediaCodecs.json

The MediaCodecs.json file provides lists of the audio and video codecs that may be available on the web. The file has two lists: one of audio codecs and one of video codecs; each codec object has as its key a unique identifying string.

The records use a few secondary objects which will be described after the primary objects:

  • compression-descriptor: An object providing basic information about the codec’s compression
  • best-for-value: A string or array of strings indicating types of content the codec is good for; see the list farther down for what these values can be
  • license-id: A license ID string taken from the SPDX license list at https://spdx.org/licenses/
  • spec-descriptor: An object providing information about a specification

Main content

{
  "audio": {
    "codec-id1": {
      "short_name": string,
      "long_name": string,
      "compression": compression-descriptor,
      [optional] "best_for": one or more of best-for-value,
      "max_bitrate": number,
      "min_channels": integer,
      "max_channels": integer,
      "license": {
        "id": spdx license ID string,
        [optional] "notes": string or array of strings
      },
      "specs": array of spec-descriptor,
      [optional] "notes": string or array of strings
    },
    "codec-id2": ...
  },
  "video": {
    "codec-id1": {
      "short_name": string,
      "long_name": string,
      "compression": compression-descriptor,
      [optional] "max_width": integer,
      [optional] "max_height": integer,
      "max_bitrate": number,
      "[optional] framerates": array of number,
         -- OR --
      "[optional] min_framerate": number,
      "[optional] max_framerate": number,
      "license": {
        "id": spdx license ID string,
        [optional] "notes": string or array of strings
      },
      "specs": array of spec-descriptor,
      [optional] "notes": string or array of strings
    },
    "codec-id2": ...
  }
}
  • The audio object lists all of the audio codecs available to the docs; the video version does the same for videol
  • The codec-id values are strings based on the codec’s short name, with no punctuation and all lower case. A codec named H.265 would be given the ID h265, for instance.
  • A codec’s short_name is an abbreviation with appropriate capitalization and punctuation, suitable for human reading, such as “MP3” or “H.265” or the like. The long_name would be the full name, such as “MPEG-1 Audio Layer III” for MP3.
  • max_bitrate is the maximum bitrate of media using the codec in bits/sec.
  • max_channels and min_channels indicate the largest and smallest number of audio channels supported by an audio codec.
  • Video codecs may include information about supported frame rates either as an array of specific frame rates that are permitted called framerates or a maximum and minimum frame rate in FPS.
  • To indicate that a codec has no restriction for a given property, set its value to false. For example, if a codec specifies no maximum width, specify a value of max_width of false.

compression-descriptor

An object providing information about the compression used by a codec.

{
  "lossy": boolean,
  [optional] "ratio_min": number,
  [optional] "ratio_typical": number,
  [optional] "ratio_max": number,
  [optional] "notes": string or strings
}

The only required value is lossy, which is true if the codec’s compression is lossy. The ratio_* values are used to provide hints as to how much the codec typically compresses data. These values are only estimates of the minimum, typical, and maximum compression ratios.

Need to define how the ratios are calculated

best-for-value

A string or array of strings identifying the type or types of content that the codec is best for. Possible values:

  • Audio-only values
    • voice
    • music
  • Video-only values
    • animation
    • action
    • bright
    • dark
  • Allowed for both audio and video
    • general

spec-descriptor

Describes a single specification. Many containers and/or codecs are defined in part across multiple specifications, so the specs property is an array of spec-descriptor objects.

{
  "name": string
  "url": url of specification
}

Containers supported by each browser: ContainerSupport.json

This file—contained in BCD—contains a group of objects, one for each browser as identified by the same string we use in BCD’s existing data.

{
  "browser-name1": {
    "audio": {
      "container-id1": boolean or {
        optional "notes": string or strings,
        // Details about supported container features
        // could go here eventually
      },
      ...
      "container-idN": {
        optional "notes": string or strings,
        // Details about supported container features
        // could go here eventually
      }
    },
    "video": {
      "container-id1": boolean or {
        optional "notes": string or strings,
        // Details about supported container features
        // could go here eventually
      },
      ...
      "container-idN": boolean or {
        optional "notes": string or strings,
        // Details about supported container features
        // could go here eventually
      }
    }
  },
  "browser-name2": ...
}
  • For each browser, we separately list the containers supported for audio and video files. Each container support object that’s present indicates that the browser supports that container; each container is identified by the same container ID used in the MediaContainers.json file.
  • If the value given for a given container is a boolean, it simply indicates whether or not the container is known by the browser. This is the minimum information that can be given.
  • Eventually, though, a container ID’s value could be an object with additional information, with fields for things like notes and which of a container’s features are supported along with any restrictions or compatibility issues.

Codecs supported by each browser: CodecSupport.json

This file lists, for each browser, the audio and video codecs they support and, for each codec, the containers that the codec is allowed to be used in.

{
  "browser-name1": {
    "audio": {
      "codec-id1": boolean or {
        "containers": array of container-ids,
        [optional] "notes": string or array of strings,
        // eventually things like what features work, etc
      },
      ...
      "codec-idN": boolean or {
        "containers": array of container-ids,
        [optional] "notes": string or array of strings,
        // eventually things like what features work, etc
      }
    },
    "video": {
      "codec-id1": boolean or {
        "containers": array of container-ids,
        [optional] "notes": string or array of strings,
        // eventually things like what features work, etc
      },
      ...
      "codec-idN": boolean or {
        "containers": array of container-ids,
        [optional] "notes": string or array of strings,
        // eventually things like what features work, etc
      }
    }
  },
  "browser-name2": ...
}
  • Each browser has a sub-object, audio, listing the audio codecs, and another, video, listing video codecs. Currently the formats of these are the same but that will change as details like features supported and the like are added.
  • The codecs are identified by the same ID string used elsewhere. Those names are used as the keys for objects providing information about the browser’s support for each codec.
  • Each codec record has a containers object which is an array of the container IDs for the containers the browser is able to use the codec in. For instance, if a browser supports MPEG-1 Audio Layer III in MPEG/MPEG2 files, MP4 files, and ubermovie[^1] formats:
        "containers": [ "mpeg", "mp4", "uber" ]

[^1]: That’s not a real movie format.

1 Like

General comment — I’m assuming the JSON files in both data/ and browser-compat-data/ would go inside a subdirectory called media or similar?

MediaContainers.json

  • Wouldn’t container-id.license.notes be optional?
  • I’m a little confused by the codecs/mimetypes/extensions situation, so just to clarify for my own sanity:
  • audio.mimetypes and audio.extensions list the mimetypes/extensions used for the container when it contains only audio.
  • video.mimetypes and video.extensions list the mimetypes/extensions used for the container when it contains video (and optionally audio as well).
  • the mimetypes/extensions optionally inside each codec list any it may have that override the container defaults?
  • If a codec does not additional mimetypes/extensions, it is just given the value of true, which means it is supported. If it is not supported, we just don’t list it at all.

I like the preferred codecs idea - I think this is useful information for developers to know.

MediaCodecs.json

  • “as its key a string specifying a unique identifying string” -> “as its key a unique identifying string” ?
  • “The codec-id values are strings based on the codec’s short name, with no punctuation and all upper-case. A codec named H.265 would be given the ID h265, for instance.” -> given this ruling, wouldn’t it be “H265”?
  • I like the compression_descriptor objects, and the fact that you are providing ratio information to give the devs and idea of that level of compression available.

ContainerSupport.json/CodecSupport.json

  • I don’t see any reason not to use standard BCD format JSON for these.
  • Since CodecSupport.json contains support for all container/codec/browser support combinations, why do we need both files? I could imagine a standard JSON file with a structure along the lines of

media.audio.container.codec.xxx
media.video.container.codec.xxx

etc.

If the file got too big, we could manage it by breaking it up into separate files for each container.

I’m sorry, I know we’ve been through this before, but on seeing this I realize that I still don’t get it. This probably needs input from someone else :wink:

1 Like

I’m sorry if I’m late to this, but the mdn/browser-compat-data repo won’t accept other data schemas.

Also, is there a large benefit that justifies us designing a complex data model for media formats now? Is there a specific need that a larger MDN user base has voiced? Are other stakeholders involved that have interest in us having this data offering? Who will, going forward, own and maintain this data?
The mdn/data repo partially failed and isn’t great to work with (licenses, insufficient schemas, not enough linting/testing), because the above questions weren’t answered at the start and so we just have some data lingering around.

I can comment on the data model in more details and invest my review time, but I would like these fundamental questions answered first.

1 Like

Yes.

MediaContainers.json

Yes. Fixed in my local draft and I will update it here after I finish updating it based on the feedback so far.

All correct!

Fortunately easy enough to just slide it in there (or out again, if we decide later we don’t want it). I’ll move it into the main format.

MediaCodecs.json

Fixed.

That was a typo; meant to say “all lower-case.” Fixed in my local draft; will update the post here shortly.

ContainerSupport.json/CodecSupport.json

Is the intent to provide version information as well as just “yes” and “no”? I had not gotten that impression that this was a goal, but if it is, then using a variation on the standard BCD format would make sense.

One thing we do lose by doing that is the ability to quickly look up what codecs a browser supports regardless of container. Instead of just having a list of them, you would have to go through every container and see what codecs it supports, and assemble a complete list that way. Not sure how often that would be needed though, so probably not a huge loss.

I will try to figure out a way to make the codec and container info fit into the BCD schema, but it feels non-trivial.

1 Like

Oh! Well, that certainly changes things. I was not aware of this, since there are already a couple of schemas in BCD, though I guess the browsers-schema is probably a very particular case.

I’ll see if I can figure out how to wrangle the stuff into the BCD format.

So, there are a few things to say in response to these questions:

  1. This format lets us more easily alter the form in which we present this information as we learn what people want to know and how they want to consume it.
  2. By separating the data into codecs and their supported features on one hand and containers, their supported features, and the codecs that can be used in them on the other hand, updating Firefox’s support for Ubercodec gets reflected on any page that provides data about Ubercodec, across all of the container types. It also becomes easier to quickly add and change the supported codecs per container without having to re-enter a lot of data.
  3. We can define the minimum needed format for now and add the other details later. This is the plan I’m following; the initial versions of these files would likely only provide basic compatibility information. Details about feature support and the like can be added easily later.
  4. We have gotten positive feedback from PAB members at Google and Microsoft about this, and we have several people from various orgs working on collecting data to use when initially building these files. Once we get going, responsibility for oversight would typically fall on the PAB members for each browser, as is usually more or less the case.

Hm, I hadn’t thought of it as “partially failed” before. That’s interesting. The data could certainly be put somewhere else if that seems appropriate. Certainly we should be able to establish appropriate linting and testing.

Not sure if my answers are as fully satisfactory as you’d like, so please let me know what else you need!

2 Likes

@fscholz and @chrisdavidmills: I’ve got a proposed version of this where the BCD content is now done using the existing schema. Each media container format has its own file under /media named containerid.json, such as mp4.json or mov.json.

Here’s a much-truncated example of what it might look like for the MP4 container. In addition to indicating that the container is supported on Firefox as of Firefox 48, it also indicates that the Firefox implementation of the container added support for variable bitrate (VBR) to the container in Firefox 59.

It also then lists codecs and that their compatibility with Firefox; other browsers could be added easily enough, as usual for BCD.

This file doesn’t incorporate all the information that the mdn/data files do, although I suppose it could be made to. I’m not sure that’s the right course of action though.

{
  "container": {
    "mp4": {
      "__compat": {
        "mdn_url": "https://developer.mozilla.org/docs/Web/Media/Formats/Containers/MP4",
        "support": {
          "firefox": {
            "version_added": "48"
          }
        },
        "status": {
          "experimental": false,
          "standard_track": true,
          "deprecated": false
        }
      },
      "features": {
        "vbr": {
          "__compat": {
            "support": {
              "firefox": {
                "version_added": "59"
              }
            },
            "status": {
              "experimental": false,
              "standard_track": true,
              "deprecated": false
            }
          }
        }
      },
      "audio_codecs": {
        "aac": {
          "__compat": {
            "support": {
              "firefox": {
                "version_added": "59"
              }
            },
            "status": {
              "experimental": false,
              "standard_track": true,
              "deprecated": false
            }
          }
        },
        "alac": {
          "__compat": {
            "support": {
              "firefox": {
                "version_added": false
              }
            },
            "status": {
              "experimental": false,
              "standard_track": true,
              "deprecated": false
            }
          }
        }
      },
      "video_codecs": {
        "h264": {
          "__compat": {
            "support": {
              "firefox": {
                "version_added": "59"
              }
            },
            "status": {
              "experimental": false,
              "standard_track": true,
              "deprecated": false
            }
          }
        },
        "dirac": {
          "__compat": {
            "support": {
              "firefox": {
                "version_added": "54"
              }
            },
            "status": {
              "experimental": false,
              "standard_track": true,
              "deprecated": false
            }
          }
        }
      }
    }
  }
}

More feedback is welcome!

1 Like

Maybe keep codecs separate from containers, but that might depend on feature imports, which are currently shelved based on @fscholz’s decision:

Thanks for your answers and thanks for making the compat data fit the BCD schema that everything else uses as well. The browsers-schema is special as it complementary data to the main compat data and used for validation of the main compat data, but all the 10769 features use the same compat schema and we have worked with that format for a while now and so coming up with a new format would mean new complexity, new reviewer training, new validation/linting tooling. I don’t think it is worth it.

This sounds good to me. Let’s create a simple but potentially extendable data model for this and make it more rich if/when we notice the need.

I think we should think about data validation and ownership early on whenever we have new data structures. With “failed” I also mean things like groupdata which has no owner and no validation and we see how broken and problematic it has been over the years. So, I would encourage you to think about the data ownership and tooling strategy here.

Thanks, very helpful! :slight_smile:

1 Like

To be fair, the situation with GroupData is in the process of being resolved at last, thanks to @wbamberg’s work to write a schema and tests. Though this may get a revisit during the work on the sidebar integration into the platform; if sidebar content comes from a data store of some kind, would that be GroupData, another data store separate from GroupData, or would we replace GroupData with a combined sidebar/API group data store? But that’s a separate topic from this discussion.

So I agree that we do need to be sure we have an ownership and maintenance plan in place for the mdn/media data store for codecs and containers, but I’m confident that such a thing is needed. We have to be able to describe codecs and containers (what they are and what they can do) separately from compatibility information.

I would like to see if anyone has thoughts on the structure I proposed for the BCD-ified version of the media container/codec compatibility data, too.

1 Like

Hi, Sheppy!

In browsers, medias formats are not supported in a binary way:
everywhere or nowhere.

For example, the set of codecs supported for WebRTC is not the same as
those accepted in .

How do you plan to represent such differences?

Cheers,