Skip to content

Add full vorbis comment support - #9864

Merged
andrewlewis merged 18 commits into
google:dev-v2from
OxygenCobalt:vorbis-comments
Jan 28, 2022
Merged

andrewlewis merged 18 commits into
google:dev-v2from
OxygenCobalt:vorbis-comments

Conversation

@OxygenCobalt

@OxygenCobalt OxygenCobalt commented Jan 16, 2022 •

Copy link
Copy Markdown
Contributor

This PR fully fleshes out the vorbis comment capabilities with the ExoPlayer metadata retrieval system.

The problem

My music player app needs to extract audio metadata at multiple points, such as with high-quality cover art or ReplayGain tags. However, I began to notice that I could only extract metadata from ID3v2 and FLAC tags, which seemed strange as OGG Vorbis tags are nearly identical to FLAC tags. Looking into this, I discovered that:

  • OggReader would parse vorbis comments and then never expose them.
  • OpusReader would just skip vorbis comments entirely.

As a result, I decided to implement parsing for both of these data structures.

What this does

This PR extends VorbisComment and PictureFrame to OGG Vorbis and OPUS streams, enabling full metadata functionality for those formats.

  • Previously internal FLAC methods responsible for building VorbisComment and PictureFrame instances have been moved to generic implementations in VorbisUtil.
    • When parsing Vorbis Comments, if a tag has the key of METADATA_BLOCK_PICTURE, then the tag is actually decoded from Base64 and then parsed as if it is a PictureFrame. This is outlined by the specification here.
    • What used to be the single FLAC method for PictureFrame parsing has been split into two blocks. FlacReader will first copy the contents of the picture frame into a ParseableByteArray on it's own, and then pass it to the utility afterwards. This is required so that vorbis comments can be transformed into picture frames as well.
  • In VorbisReader, once VorbisSetup is returned, the CommentsHeader instance is transformed into a Metadata instance using the aforementioned utilities. This instance is then provided to SetupData.format.
  • In OpusReader, after the identification header frame is parsed, the subsequent frame is checked to be a Vorbis Comment frame. If that is the case, it is parsed with the aforementioned utilities and immediately transformed into a Metadata instance that is then added to to SetupData.format.
  • To reflect the new nature of the metadata parsing, all contents of the metadata.flac module have been moved to a new module called metadata.vorbis, with the previous module being deprecated. I can change this back if desired.
  • No metadata parsing was added to the OPUS extension.

I updated the testing configuration to reflect these changes and confirmed that the test suite succeeds. I'm not fully sure what knock-on effects this might have, but hopefully this change only affects local files, like I intended to. If it's not, then I'm okay with this not being merged.

As for documentation, I don't fully know how to work with javadoc or the jekyll docs, so there's some directories that still correspond to the old flac module name. If you need me to update anything I will.

Feel free to raise any concerns with my PR.

Change how OggReader handles the CommentsHeader instance, enabling
VorbisComment tags to be parsed from it.
Move all picture and vorbis frame parsing into a new xiph module. This
commit also adds cover frame parsing from vorbis comments as well.
The vorbis tests did not expect metadata normally. Now they do.
Add metadata parsing for the Opus format.
Refactor the overall module to place the unified vorbis tags into a
single package called `vorbis`. Also re-intoduce the vorbis tags
in their original `flac` module, but deprecate them.
Slightly cleanup VorbisUtil.
Line up this branch with the dev branch instead of the release branch.
@OxygenCobalt

OxygenCobalt commented Jan 16, 2022 •

Copy link
Copy Markdown
Contributor Author

By the way: I will be signing the CLA, give me a second.

Edit: I signed the CLA.

@icbaker icbaker self-assigned this Jan 17, 2022
@icbaker

icbaker commented Jan 17, 2022

Copy link
Copy Markdown
Collaborator

Thanks for adding this! I took a look through and added some comments - let me know if it seems like i've suggested anything nonsensical :)

@OxygenCobalt

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback. I'll get to changing those.

In the old `flac` module, superclass the deprecated types under the
moved types in the `vorbis` module. This ensures backwards compat
with existing library users.
Try to eliminate some nitpicks regarding VorbisUtil.
Studio accidentally renamed some of the javadoc to reflect the new
vorbis module. Revert it to the dev javadoc, as the ExoPlayer devs
don't update the javadoc until a release.
67e1261 messed up some of the other docs. Fix that.
Simplify how the comment header is parsed and eliminate a few possible
bugs in the process, such as:
- Metadata being overwritten directly by the comments header.
- The packet being rewound to 0 if it cannot find a comment header,
which might result in the cursor being moved to a bad position.
Group up some other minor changes with the vorbis comment utils.
Collapse the two variations of `VorbisUtil.buildMetadata` into a single
method called `VorbisUtil.parseVorbisComments` that only takes a list
of vorbis strings, compared to previously where it would take strings
and picture frame instance. Any code that relied on the old signature
now either concatenates picture frames and vorbis comments or copies
vorbis comments into an existing metadata instance.
@OxygenCobalt
OxygenCobalt requested a review from icbaker January 17, 2022 17:16
Comment concatenation was accidentally not added previously, which
results in a testing failure.
Fix some more nitpicks I encountered.
Comment thread extensions/flac/proguard-rules.txt
Instead of having types in flac inherit types in vorbis, make types in
vorbis inherit types in flac. This is a bit of a hack and somewhat
messy, but it retains backwards compatibility.
Replace the flac module usage in the FLAC extension with the vorbis
module.
@OxygenCobalt
OxygenCobalt requested a review from icbaker January 18, 2022 13:32
@icbaker

icbaker commented Jan 18, 2022

Copy link
Copy Markdown
Collaborator

Thanks for all the changes - I'll work on getting this merged.

@OxygenCobalt

Copy link
Copy Markdown
Contributor Author

Any updates on when this will be merged?

@andrewlewis
andrewlewis merged commit fe7e5b8 into google:dev-v2 Jan 28, 2022
@OxygenCobalt
OxygenCobalt deleted the vorbis-comments branch January 29, 2022 15:18
@google google locked and limited conversation to collaborators Mar 30, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants