Extracting the Metadata

This tutorial describes how to extract metadata.

Purpose

The purpose of this tutorial is to show you how to use the metadata client utility to extract metadata field items synchronously and asynchronously.

Required Background

The Metadata Utility Library Overview introduces the metadata client utility.

Introduction

After initialising the parser with an input source, the client requests the parser plug-in to extract the metadata from the source. The following metadata operations are available to the client:

  • Retrieve all metadata fields in a single pass.

  • Retrieve metadata fields in multiple passes.

  • Request specific metadata fields.

  • Specify the order of fields.

The parser plug-in's main purpose is to read the metadata from the source and then fill the metadata buffer. There are two ways to extract the metadata – synchronously and asynchronously. After filling the metadata buffer, MUF returns buffer ownership to the client.

Using Metadata

The following tasks will be covered in this tutorial:

  • Extract metadata asynchronously

  • Extract metadata synchronously

Basic Procedure

The high level steps to extract metadata asynchronously are shown here:

  1. Create a new metadata utility object.

  2. Initialise a parser plug-in with an input source.

  3. Extract metadata asynchronously using one of the following overloads of CMetaDataClientUtility::MetaDataAsyncL():

    • Call MetaDataAsyncL() and set aObserver to be a reference to the MUF observer interface.

      IMPORT_C void MetaDataAsyncL (MMUFObserver& aObserver);
    • Call MetaDataAsyncL() and set the following parameters:

      Parameter Description

      aObserver

      A reference to the MUF observer interface.

      aWantedFields

      The metadata fields to be extracted.

      TRequestedFields

      The metadata field filtering option.

      Note: The default value for this option is EOnlyRequestedFields.

      IMPORT_C void MetaDataAsyncL (MMUFObserver& aObserver, RPointerArray<TInt>& aWantedFields, TRequestedFields aOrder = EOnlyRequestedFields);

    The parser plug-in parses the metadata and appends the required field items to CMetaDataFieldsArray.

  4. When the parser plug-in has finished parsing metadata, it returns the metadata buffer through the MetaDataBufferFilled() call back function. If there is more data, the parser plug-in stores the current field position and MUF returns the metadata buffer with partial data.

  5. If not all metadata is extracted in the first attempt, call MoreDataAsyncL() to retrieve the metadata in multiple calls.

  6. The parser plug-in returns the metadata buffer through the MetaDataBufferFilled() call back function.

    Steps 5 and 6 iterate until the parser plug-in has parsed all of the metadata field items.

The high level steps to extract metadata synchronously are shown here:

  1. Create a new metadata utility object.

  2. Initialise a parser plug-in with an input source.

  3. Extract metadata synchronously using one of the following overloads of CMetaDataClientUtility::MetaDataSyncL():

    • Call MetaDataSyncL() and pass the reference to MUF. If more data calls are required to receive requested metadata, the parser plug-in sets aMoreData to ETrue, else EFalse.

      IMPORT_C CMetaDataFieldsArray* MetaDataSyncL(TBool& aMoreData);
    • Call MetaDataSyncL() and set the following parameters:

      Parameter Description

      aWantedFields

      The metadata fields to be extracted.

      aMoreData

      If more data calls are required to receive requested metadata, the parser plug-in sets aMoreData to ETrue, else EFalse.

      TRequestedFields

      The metadata field filtering option.

      Note: The default value for this option is EOnlyRequestedFields.

      IMPORT_C CMetaDataFieldsArray* MetaDataSyncL(RPointerArray<TMetaDataEntryId
                                          >& aWantedFields, TBool& aMoreData, const 
                                          TRequestedFields aOrder = EOnlyRequestedFields);
      

    The parser plug-in parses the metadata and appends the required field items to CMetaDataFieldsArray.

  4. If not all metadata is extracted in the first attempt, call MoreDataSyncL() to retrieve the metadata in multiple calls.

Examples

Extracting metadata asynchronously

Read all metadata fields asynchronously:

CCclientApplication :: ReadMetaData()
{
_LIT(KTestMp3File, "c:\\mm\\muf\\testfiles\\aagaya.mp3");
const TPtrC fileName(KTestMp3File);
CMetaDataClientUtility* utility = CMetaDataClientUtility::NewL(EAllPlugIns);
CleanupStack::PushL(utility);

utility ->InitialiseParserL(fileName);
utility ->MetaDataAsyncL(*this);
:
}
CCclientApplication :: MetaDataBufferFilled(CMetaDataFieldsArray* 
                                aFieldsArray, TInt aErrorCode, TBool aMoreData)
{
if(aFieldsArray && (aErrorCode==KErrNone))
    {
    //Display or store data
    }
delete aFieldsArray;
}

Read only the client selected fields. Before reading metadata the client must pass a list of the selected fields.

TMetaDataEntryId fieldID[2]= {EMetaDataTitle, EMetaDataArtist};
CCclientApplication :: ReadMetaData()
{
_LIT(KTestMp3File, "c:\\mm\\muf\\testfiles\\aagaya.mp3");
const TPtrC fileName(KTestMp3File);
CMetaDataClientUtility* utility = CMetaDataClientUtility::NewL(loadOption);
CleanupStack::PushL(utility);
utility ->InitialiseParserL(fileName);
RPointerArray<TMetaDataEntryId> wantedFields;
for (TInt I =0; I < 2; I++)
    {
    wantedFields.Append(&fieldID[i]);
    }
utility->MetaDataAsyncL(wantedFields, *this, EOnlyRequestedFields);
:
}
CCclientApplication :: MetaDataBufferFilled(CMetaDataFieldsArray* 
                                aFieldsArray, TInt aErrorCode, TBool aMoreData)
{
if(aFieldsArray && (aErrorCode==KErrNone))
    {
    //Display or store data
    }
    delete aFieldsArray;
}

Extracting metadata synchronously

Read all the metadata fields synchronously:

CCclientApplication :: ReadMetaData()
{
_LIT(KTestMp3File, "c:\\mm\\muf\\testfiles\\aagaya.mp3");
const TPtrC fileName(KTestMp3File);
CMetaDataClientUtility* utility = CMetaDataClientUtility::NewL(loadOption);
CleanupStack::PushL(utility);

utility ->InitialiseParserL(fileName);
CMetaDataFieldsArray* fieldsArray = utility ->MetaDataSyncL();
if(aFieldsArray)
    {
    //Display or store data
    }
delete fieldsArray;
:
CleanupStack::PopAndDestroy(2);
}

Reading more data

If the metadata size is greater than the buffer limit, then the parser sends the first buffer and informs the client about the next data through the more data flag. If the client is interested to read the next data, it must reset the more data flag and call MoreDataSyncL.

CCclientApplication :: ReadMetaData()
    {
    _LIT(KTestMp3File, "c:\\mm\\muf\\testfiles\\aagaya.mp3");
    const TPtrC fileName(KTestMp3File);
    CMetaDataClientUtility* utility = CMetaDataClientUtility::NewL(loadOption);
   CleanupStack::PushL(utility);

    utility ->InitialiseParserL(fileName);
    TBool nextData;
    CMetaDataFieldsArray* fieldsArray = utility ->MetaDataSyncL(nextData);
    if(aFieldsArray)
        {
        //Display or store data
        }
    if (nextData)
        {
        nextData = EFalse;
        CMetaDataFieldsArray* fieldsArrayOne = MoreDataSyncL(nextData)
        }
    :
    
    }