c ++ - Læsning/skrivning af forskellige lydfilmetadata i Windows

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at ændre metadata for nogle lydfiler i C ++, og jeg kom på tværs af [[hvad jeg troede var]] en mulig måde ved hjælp af Windows Media Foundation. Så jeg forsøgte at sammensætte en simpel løsning:


#include <atlbase.h>
#include <mfapi.h>
#include <mfidl.h>
#include <Windows.h>

#pragma comment(lib, "Mf.lib")
#pragma comment(lib, "Mfplat.lib")


int main() {
    HRESULT hr;

    CComPtr<IMFSourceResolver> source\_resolver(nullptr);
    if (FAILED(hr = MFCreateSourceResolver(&source\_resolver))) {
        // Handle errors...
    }

    MF\_OBJECT\_TYPE object\_type = MF\_OBJECT\_INVALID;
    CComPtr<IUnknown> source\_object(nullptr);
    if (FAILED(hr = source\_resolver->CreateObjectFromURL(L"audio\_file\_here", MF\_RESOLUTION\_MEDIASOURCE | MF\_RESOLUTION\_READ | MF\_RESOLUTION\_CONTENT\_DOES\_NOT\_HAVE\_TO\_MATCH\_EXTENSION\_OR\_MIME\_TYPE, NULL, &object\_type, &source\_object))) {
        // Handle errors...
    }

    CComPtr<IMFMediaSource> source(nullptr);
    if (FAILED(hr = source\_object->QueryInterface(IID\_PPV\_ARGS(&source)))) {
        // Handle errors...
    }

    CComPtr<IMFPresentationDescriptor> presentation\_descriptor(nullptr);
    if (FAILED(hr = source->CreatePresentationDescriptor(&presentation\_descriptor))) {
        // Handle errors...
    }

    CComPtr<IMFMetadataProvider> metadata\_prov(nullptr);
    if (FAILED(hr = MFGetService(source, MF\_METADATA\_PROVIDER\_SERVICE, IID\_PPV\_ARGS(&metadata\_prov)))) {
        // Handle errors...
    }

    CComPtr<IMFMetadata> metadata(nullptr);
    if (FAILED(hr = metadata\_prov->GetMFMetadata(presentation\_descriptor, 0, NULL, &metadata))) {
        // Handle errors...
    }

    /* Use metadata, etc etc */
}


Det virker fint for en standard MP3 (.mp3) fil, men det svigter altid på AAC (.m4a fra iTunes) lydfiler. Specifikt svigter funktionen MFGetService() med en returværdi givet af Visual Studio som "The object does not support the specified service.".


Jeg forstår ikke, hvorfor det her er tilfældet. Her står det Media Foundation støtter AAC, og Windows støtter det helt sikkert på en eller anden måde , fordi jeg kan spille mine AAC-filer helt fint via den indbyggede Groove Music afspiller.

Desuden er filen metadata også læsbar af Windows på en eller anden måde , fordi jeg kan se egenskaberne for filen i Explorer, som den lister titlen, kunstneren, albumet, osv. Lige fint. [7]


Så hvordan kan jeg læse og skrive metadata fra MP3 og AAC lydfiler? Er det muligt via Media Foundation, eller har jeg brug for et andet værktøj fra Windows API'erne? (Jeg har set referencer her til en metode, der involverer en 'Windows Shell-grænseflade', er det den vej at gå?) [8]

Bedste reference


Først og fremmest er dit spørgsmål ikke rent faktisk relateret til AAC. Du laver ikke AAC-filer her, og din fil er en MPEG-4-fil (typisk .MP4, men din .M4A er bare en variant/alias af .MP4).



  • Hvad er forskellen mellem M4A og AAC lydfiler?



Så spørgsmålet er, om du kan få adgang til metadata af MPEG-4-fil ved hjælp af MF\_METADATA\_PROVIDER\_SERVICE eller på anden måde med Media Foundation.


Bemærk, at 'support for AAC eller MPEG-4' ikke nødvendigvis betyder metadatastyring, da metadatastyring er en hjælpekapacitet.


Det ser ud til, at Microsoft afviklet metadatatjenesteudbyderen og ikke længere tilbyder den til nye mediekilder. Selv om support til MF\_METADATA\_PROVIDER\_SERVICE stadig er tilgængelig for .MP3-filer, er den ikke længere tilbudt til .MP4. I stedet foreslår Microsoft brug af Shell Property Handlers, som for MP4-filer anvender Media Foundation internt.


Se MF\_METADATA\_PROVIDER\_SERVICE for MP4-fil: [10]



  For at få metadata fra MP4-kilden, skal du faktisk få IPropertyStore-grænsefladen fra tjenesten MF\_PROPERTY\_HANDLER\_SERVICE. MSDN opdateres for at dokumentere denne nye metode for at hente metadata ...

  
  Til info er standard Shell-nøgleordene dokumenteret her: Windows Egenskaber. [11]



Shell og explorer bruger nøjagtigt denne metode til at hente metadataene.


Du kan også bruge FilePropertyStore værktøj derfra for hurtigt at liste egenskaber tilgængelige via Shell Property Handler API: [12] [13]


Indtast billedbeskrivelse her [14]