media.Tags gives the common fields of an MP4, M4A or MOV file (title, artist, album, comment, description, copyright, date, encoder) whichever tag system the file uses, and media.Metadata.NativeTags lists every tag exactly as stored. The input is the Sintel trailer, 4.4 MB, from the Blender Foundation (CC BY 3.0).
dotnet new console -o Mp4Tags && cd Mp4Tags dotnet add package RecursiveAI.OneMedia --version 0.1.0-preview.1 curl -L -o sintel.mp4 https://download.blender.org/durian/trailer/sintel_trailer-480p.mp4
Put this in Program.cs and run dotnet run:
using RecursiveAI.OneMedia; using RecursiveAI.OneMedia.Tags; using MediaFile media = Media.Open("sintel.mp4"); // The common view: the same fields for iTunes, QuickTime, 3GPP, XMP and Matroska tags. CommonTags tags = media.Tags; Console.WriteLine($"Title: {tags.Title}"); Console.WriteLine($"Artist: {tags.Artist}"); Console.WriteLine($"Description: {tags.Description}"); Console.WriteLine($"Copyright: {tags.Copyright}"); Console.WriteLine($"Encoder: {tags.Encoder}"); // Every native tag: its system, its key and its value as stored. Console.WriteLine(); foreach (NativeTag tag in media.Metadata.NativeTags) Console.WriteLine($"{tag.System,-5} {tag.Key,-5} {tag.Text}"); // One native tag by system and key. Console.WriteLine(); Console.WriteLine(media.Native["ilst", "©cpy"]?.Text);
Title: Sintel Trailer Artist: Durian Open Movie Team Description: Trailer for the Sintel open movie project Copyright: Encoder: Lavf52.62.0 ilst ©nam Sintel Trailer ilst ©ART Durian Open Movie Team ilst ©too Lavf52.62.0 ilst ©cpy (c) copyright Blender Foundation | durian.blender.org ilst desc Trailer for the Sintel open movie project (c) copyright Blender Foundation | durian.blender.org
Copyright is empty although the file has a copyright: this file stores it as ©cpy in the iTunes list, and the 0.1 mapping takes copyright from cprt there (©cpy only from QuickTime user data). The native lookup at the end reads it whatever the mapping says.
The common view is computed from the native tags each time you ask, through a fixed mapping table: ©nam in an iTunes list, com.apple.quicktime.title in QuickTime keys, titl in a 3GPP file and TITLE in Matroska all become Title. When several native tags map to one field, the property is the first and tags.Values(CommonField.Title) lists them all.
The native systems are ilst (iTunes items, what ffmpeg and most tools write to MP4), udta (QuickTime user data), mdta (QuickTime keys, what phones write), 3gpp, xmp, and mkv and mkv-info for Matroska. Text values are decoded when the file is opened; pictures and long binary values are read only when you ask, with tag.ReadValue().
Check it with ffprobe
ffprobe -v error -show_entries format_tags -of default=nw=1 sintel.mp4TAG:major_brand=isom TAG:minor_version=512 TAG:compatible_brands=isomiso2avc1mp41 TAG:creation_time=1970-01-01T00:00:00.000000Z TAG:title=Sintel Trailer TAG:artist=Durian Open Movie Team TAG:encoder=Lavf52.62.0 TAG:copyright=(c) copyright Blender Foundation | durian.blender.org TAG:description=Trailer for the Sintel open movie project
ffprobe lists the file type brands and the movie header’s creation time with the tags. In OneMedia the creation time is a candidate of media.CaptureTime (here the 1970 date the muxer wrote; see When and where a video was recorded).
Limits
- Reading only. OneMedia 0.1 doesn’t write or edit tags. Tag editing is not in this release.
- Chapters. Nero
chplchapter lists are read (media.Metadata.Chapters); QuickTime text chapter tracks and MatroskaChaptersare not read yet. - Mapping gaps. A tag the mapping table doesn’t list, such as
©cpyin an iTunes list, stays on the native list only. - Values that disagree. Where a file has the same field in several systems, OneMedia picks by a fixed order and keeps the rest. ExifTool and MediaInfo sometimes pick a different one; Tags and capture facts lists every known difference.
- Bad text. Invalid UTF-8 or UTF-16 is replaced with U+FFFD and reported in
media.Metadata.Defects, not thrown.
The same calls work on MKV and WebM: Read MKV and WebM file info.