Metadata Extractor: Extracting Metadata from an Input Media File
This tutorial demonstrates how you can extract metadata from media files.
Warm-up
Become familiar with the Metadata Extractor API basics by learning about:
-
Initializing the Metadata Extractor
Initialize the metadata extractor for use.
-
Retrieving Metadata
Create a metadata extractor handle, bind the handle with a media file, and retrieve the metadata, artwork, lyrics, and frames.
Note |
---|
You can use the metadata extractor only with audio and video files. The metadata editor does not support image files. |
Initializing the Metadata Extractor
To initialize the metadata extractor for use:
-
To use the functions and data types of the Metadata Extractor API (in mobile and wearable applications), include the <metadata_extractor.h> header file in your application:
#include <metadata_extractor.h>
To ensure that a Metadata Extractor function has been executed properly, make sure that the return value is equal to METADATA_EXTRACTOR_ERROR_NONE.
-
To work with the Metadata Extractor API, define a handle variable for the metadata extractor:
static metadata_extractor_h g_metadata_h = NULL;
This tutorial uses a global variable for the handle.
-
Make sure you have access to the files whose metadata you want to extract, and make sure the files contain metadata, since the Metadata Extractor API only works on files with metadata.
This tutorial uses 2 files: an MP3 audio file and an MP4 video file, which are accessed through their file paths. The following example code uses an internal storage, so you must include the storage.h header file for the code to work.
int internal_storage_id; char *internal_music_storage_path; char *internal_video_storage_path; char *music_file_name = "test_music.mp3"; char *video_file_name = "test_video.mp4"; char *music_test_path; char *video_test_path; static bool storage_cb(int storage_id, storage_type_e type, storage_state_e state, const char *path, void *user_data) { if (type == STORAGE_TYPE_INTERNAL) { internal_storage_id = storage_id; return false; } return true; } void _get_internal_storage_path() { int error; char *path = NULL; error = storage_foreach_device_supported(storage_cb, NULL); error = storage_get_directory(internal_storage_id, STORAGE_DIRECTORY_MUSIC, &path); if (error != STORAGE_ERROR_NONE) { internal_music_storage_path = strdup(path); free(path); } error = storage_get_directory(internal_storage_id, STORAGE_DIRECTORY_VIDEOS, &path); if (error != STORAGE_ERROR_NONE) { internal_video_storage_path = strdup(path); free(path); } } void _make_test_path() { int path_len = 0; path_len = strlen(internal_music_storage_path) + strlen(music_file_name) + 1; music_test_path = malloc(path_len); memset(music_test_path, 0x0, path_len); strncat(music_test_path, internal_music_storage_path, strlen(internal_music_storage_path)); strncat(music_test_path, music_file_name, strlen(music_file_name)); path_len = strlen(internal_video_storage_path) + strlen(video_file_name) + 1; video_test_path = malloc(path_len); memset(video_test_path, 0x0, path_len); strncat(video_test_path, internal_video_storage_path, strlen(internal_video_storage_path)); strncat(video_test_path, video_file_name, strlen(video_file_name)); }
Note |
---|
The Metadata Extractor functions can use both common content in the device storage (internal or external) and private content in your application data. |
Retrieving Metadata
To retrieve metadata from the file:
-
Create the metadata extractor handle using the metadata_extractor_create() function:
ret = metadata_extractor_create(&g_metadata_h);
-
Set the path to the file whose metadata you want to retrieve using the metadata_extractor_set_path() function:
ret = metadata_extractor_set_path(g_metadata_h, video_test_path); // Or ret = metadata_extractor_set_path(g_metadata_h, music_test_path);
The function binds the metadata extractor handle (first parameter) with the file specified in the path variable (second parameter).
-
Retrieve the metadata from the file using the metadata_extractor_get_metadata() function. Retrieve each piece of metadata (each metadata attribute) individually.
As parameters, define the metadata extractor handle, the attribute you want to retrieve, and a pointer to the char variable in which you want to store the attribute value. The possible attributes are defined in the metadata_extractor_attr_e enumeration (in mobile and wearable applications).
The following example code retrieves the duration and prints it on the screen. You can retrieve other attributes by defining a different attribute enumerator as the second parameter.
char *value = NULL; ret = metadata_extractor_get_metadata(g_metadata_h, METADATA_DURATION, &value); dlog_print(DLOG_DEBUG, LOG_TAG, "METADATA_DURATION: %s\n", value); if (value != NULL) { free(value); value = NULL; }
To avoid memory leaks, release the value variable using the free() function when you no longer need the variable.
-
In case of an audio file, retrieve the artwork from the file using the metadata_extractor_get_artwork() function.
The retrieved artwork information is available in the 3 out parameters, which define the artwork image, image size, and MIME type.
The following example code retrieves the artwork and prints the image size and MIME type on the screen:
int artwork_size = 0; void *artwork = NULL; char *artwork_mime = NULL; ret = metadata_extractor_get_artwork(g_metadata_h, &artwork, &artwork_size, &artwork_mime); dlog_print(DLOG_DEBUG, LOG_TAG, "Artwork: size: %d, mime type: %s\n", artwork_size, artwork_mime); if (artwork != NULL) { free(artwork); artwork = NULL; } if (artwork_mime != NULL) { free(artwork_mime); artwork_mime = NULL; }
To avoid memory leaks, release the artwork and artwork_mime variables using the free() function when you no longer need the variables.
-
In case of an audio file, retrieve the synchronized lyrics from the file using the metadata_extractor_get_synclyrics() function.
The following example code retrieves the synchronized lyrics from index number 1 and prints the time information and lyrics on the screen:
unsigned long time_info = 0; char *lyrics = NULL; ret = metadata_extractor_get_synclyrics(g_metadata_h, 1, &time_info, &lyrics); if (lyrics != NULL) { dlog_print(DLOG_DEBUG, LOG_TAG, "Synclyrics: time_info: %d, lyrics: %s\n", time_info, lyrics); free(lyrics); lyrics = NULL; }
To retrieve the synchronized lyrics index number, use the metadata_extractor_get_metadata() function with the METADATA_SYNCLYRICS_NUM attribute.
To avoid memory leaks, release the lyrics variable using the free() function when you no longer need the variable.
-
In case of a video file, retrieve frames from the file in one of the following ways:
To retrieve a frame without specifying the time when the frame appears, use the metadata_extractor_get_frame() function.
To retrieve a frame at a specified time, use the metadata_extractor_get_frame_at_time() function.
The following example code first retrieves a frame at an unspecified time and prints the frame size, and then retrieves another frame at a specified time and prints its size:
// Use metadata_extractor_get_frame() int frame_size = 0; void *frame = NULL; ret = metadata_extractor_get_frame(g_metadata_h, &frame, &frame_size); dlog_print(DLOG_DEBUG, LOG_TAG, "Frame: size: %d\n", frame_size); if (frame != NULL) { free(frame); frame = NULL; } // Use metadata_extractor_get_frame_at_time() unsigned long timestamp = 500; ret = metadata_extractor_get_frame_at_time(g_metadata_h, timestamp, true, &frame, &frame_size); dlog_print(DLOG_DEBUG, LOG_TAG, "Frame at %d: size: %d\n", timestamp, frame_size); if (frame != NULL) { free(frame); frame = NULL; }
To avoid memory leaks, release the frame variable using the free() function when you no longer need the variable.
-
When no longer needed, destroy the metadata extractor handle using the metadata_extractor_destroy() function:
metadata_extractor_destroy(g_metadata_h);