(Open Source) Metadata Retriever Wrapper

Metadata Retriever Wrapper

An AI2 Extension to wrap the MetadataRetriever class.

*Requires minimum API level 10
*Requires write permission

This extension is designed to wrap the already pre-defined functions of the MetadataRetriever class.

Documentation

This extension currently wraps essentially all functions of the MetadataRetriever class, including:

Description about these blocks can be found here, by their corresponding function names.

Method return

All functions return type String. They return the absolute file path of the new extracted image stored in cache, aside from the function MetadataRetriever.ExtractMetadata , which returns metadata. Take for instance:

a8f3df33d82fec61819e81501e7c2b9d4fe43f01

This is the MetadataRetriever.ExtractMetadata (int keyCode) method, that is used in this example to extract the duration of the media in milliseconds, since according to the MetadataRetriever developer reference page, keyCode 9 (alias METADATA_KEY_DURATION,) is used to extract duration.

7a09d2bc6d640ce04c493394fa6c3a49d722d45a

This one uses the keyCode 7, which is an alias for METADATA_KEY_TITLE , and is used to extract the title of the media.

There are various of keyCodes to use, listed all in depth here.

Method Arguments - IO

The first argument , is usually the argument absoluteFilename , which is much self-explanatory. Unlike in AI2, file:/// is a redundant prefix; the extension's functions execute without interference, regardless of the occurrence of the prefix. Be that as it may, all paths returned from the functions, emphatically have to use and are returned with the file:/// prefix.

Furthermore, asset filename utilisation as the file-path argument is approved, despite if the application is running in development mode, thanks to the automatic debugging detection, which is an abstract of the AssetExtractor project, which you can visit here. Another concise illustration:

The media assigned as path can differ in file formats, since it is wrapping an Android pre-defined method, in accordance to your Android API level, explained thoroughly here for audio, and here for video.

All methods require an absolute file path of the target media, as of the MetadataRetriever.SetDataSource function, for it is necessary for relatively every method within the MetadataRetriever class to work.

Any other uncovered arguments required, are referenced in great detail inside the MediaMetadataRetriever Class Developer Reference.

Minimum API - Errors

Minimum API level for this extension is level 10. Despite this, each function prerequisites diverse API levels.

Required API level is shown on the right side of each method/constant region.

Seeing that these functions are virtual methods, granted that one of them was invoked on a device with an older platform version than mandatory, instead of returning results, the method returns an error message . The current error message is: "ERROR! Insufficient API level."

bdb465f2dbccd9fce5ea277d9bfb855260c55c21

On the occasion that the function fails, it generally returns an error message with a clause. You can handle them by checking if the string returned contains "ERROR!" , as it is widely used as a universal error message prefix all across the extension.



THIS IS DANGEROUS!!Setting a picture component as the error message, causes a crash! Ensure you scan the returned string to handle the error in your code, rather than rawly assigning the path of the image to a MetadataRetriever function. Like this:

This block sets the picture component to the frame captured using the MetadataRetriever1.GetFrameAtTime method, with the timestamp inputted in the textbox in microseconds. Yet, to not cause a crash, it checks if the method returned an error string, thus stopping the application from crashing. Adversely, provided that we were supposingly setting the picture source to a non-filepath (the error message) , the application would fail and crash.

Sample project

This is a tutorial project of what this extension could be used for.

Preview Screen1:

Code Screen1:

Preview Screen2:

Code Screen2:

Further notes

  1. MetadataRetriever.GetFrameAtIndex is the same thing with MetadataRetriever.GetImageAtIndex , except that MetadataRetriever.GetFrameAtIndex works only for video. MetadataRetriever.GetImageAtIndex could be used to extract the second cover-art image of an .mp3 file.
  2. MetadataRetriever.GetFramesAtIndex is not wrapped, since you could run MetadataRetriever.GetFrameAtIndex in a for-loop.
  3. MetadataRetriever.BitmapParams function overload versions were also not included in current release as of 7 September, 2021 . The extension converts the bitmap to a .png , therefore, there is no convincing motive to include MediaMetadataRetriever.BitmapParams .
  4. MediaMetadataRetriever.GetFrameAtTime(long timeUs, int option) , was renamed in the extension to GetFrameAtTimeOptionOverload , simply because the MIT AI2 extension builder merges overload functions (sadly does not support overloads) .
  5. All error messages can be searched in the source of the extension. 'Find "ERROR!" ' is recommended, if you are viewing the code through an editor/browser,

Comparison and contrast

At variance with other extensions, this extension:

  • Is open source.
  • Supports assets.
  • Has general media capabilities
  • Includes error messages.
  • Stable regardless of development or deployment mode.
  • Is excessively documented
  • Is Updated frequently
  • MetadataRetriever.ExtractMediatata is invoked as a virtual method, meaning that newly added keyConstants will work on the latest version of Android.

Downloads & Project Page

Github project page

(Source) Leave a star on the Github project!

Downloads page

(Releases) Includes project and extension

Changelog

V1
  • Initial release
V2
  • Refactoring to meet MITAI2 naming standards (Complying with the MITAI2 naming conventions/dismissing the old original wrapper class function names)

(Latest Changelog will always be found in the Downloads/Releases page)

Thank you!

2 Likes

Although this class was added at API10 level, keep in mind that many of these methods were added later. So not all methods will work on older android versions.

Exactly so. Precisely for this reason have I included the 'Minimum API' region in my documentation, explaining how to distinct between compatible and non-compatible methods on the spot, using the Android Developer's class documentation page. Additionally, I disclosed how to handle a minimum API error in code, in case of higher unsupported API method calls.

Can we get duration of online music by the?

Unfortunately, I have not implemented URL support. However, It is reasonably easy to do, thus, I'll forward the suggestion today.

For the meantime, if you get rather impatient, try downloading the media to an app-specific directory/any directory, and then use the Mediadata.ExtractMetadata(absoluteFilename, 9). '9' like in the documentation, is the constant METADATA_KEY_DURATION. You can read more about Mediadata.ExtractMetadata's constants on the Android API developer reference website.

Furthermore, would 'online music' convey means of media streaming?

It appears I have replied to the wrong user, thanks to my haste. I apologise for the inconvinience.

In any case, embedded online media support would be an injudicious addition to the extension. Retrieving an online file evidently requires an act or process of downloading data, which would place the extension out of topic, since its purpose serves as a class wrapper, and not as a vile and tawdry downloading media library with information extraction capabilities.

In a similar manner, I have had previously proposed a much superior alternative, that includes practices kin to:

This is a sample project to asynchronously download media, extract their data, handle errors, and avoid UI hangs (especially for larger files/users with a slower connection), all concurrently.

The sample project can be found here. Happy coding!

2 Likes