Copying Windows Explorer 'Rating' and 'Tags'

Started by marwatk, February 22, 2015, 10:45:03 PM

Previous topic - Next topic

marwatk

I can't figure out how to get the windows rating and tags to copy over to other files when using -tagsFromFile. Running -v on exif tool I can see them in there (sort of), but can't figure out how to get it to copy.

Basically I'm doing this:

ffmpeg -i src.mp4 dest.mp4
exiftools -tagsFromFile src.mp4 dest.mp4


Below is the output of a file rated as 5 stars in explorer with the tags "mytag1" and "mytag2".


[root@bigguy moviestest]# exiftool -v src.mp4
  ExifToolVersion = 9.76
  FileName = src.mp4
  Directory = .
  FileSize = 811085
  FileModifyDate = 1424662366
  FileAccessDate = 1424659526
  FileInodeChangeDate = 1424662366
  FilePermissions = 33252
  FileType = MP4
  MIMEType = video/mp4
  FileType (SubDirectory) -->
  + [BinaryData directory, 16 bytes]
  | MajorBrand = isom
  | MinorVersion =
  | CompatibleBrands = isom3gp4
  MovieDataSize = 809434
  MovieDataOffset = 40
  MovieData = ...e.@w.0.....,.~<....&"..`!T........  ... .\LC...A.".. .E...@..t.y..qM.=[snip]
  Movie (SubDirectory) -->
  + [Movie directory]
  | MovieHeader (SubDirectory) -->
  | + [BinaryData directory, 100 bytes]
  | | MovieHeaderVersion = 0
  | | CreateDate = 3461148262
  | | ModifyDate = 3461148262
  | | TimeScale = 1000
  | | Duration = 683
  | | PreferredRate = 65536
  | | PreferredVolume = 256
  | | MatrixStructure = 1 0 0 0 1 0 0 0 16384
  | | PreviewTime = 0
  | | PreviewDuration = 0
  | | PosterTime = 0
  | | SelectionTime = 0
  | | SelectionDuration = 0
  | | CurrentTime = 0
  | | NextTrackID = 3
  | UserData (SubDirectory) -->
  | + [UserData directory]
  | | GPSCoordinates = ...+39.9440-105.0732/
  | | Meta (SubDirectory) -->
  | | + [Meta directory]
  | | | Handler (SubDirectory) -->
  | | | + [BinaryData directory, 24 bytes]
  | | | | HandlerClass =
  | | | | HandlerType = mdir
  | | | | HandlerVendorID =
  | | | ItemList (SubDirectory) -->
  | | MicrosoftXtra (SubDirectory) -->
  | | + [Xtra directory, 108 bytes]
  | | | Microsoft_Xtra_WM/SharedUserRating = 99
  | | | Category = mytag1
  | Track (SubDirectory) -->
  | + [Track directory]
  | | TrackHeader (SubDirectory) -->
  | | + [BinaryData directory, 84 bytes]
  | | | TrackHeaderVersion = 0
  | | | TrackCreateDate = 3461148262
  | | | TrackModifyDate = 3461148262
  | | | TrackID = 1
  | | | TrackDuration = 533
  | | | TrackLayer = 0
  | | | TrackVolume = 0
  | | | MatrixStructure = 1 0 0 0 1 0 0 0 16384
  | | | ImageWidth = 83886080
  | | | ImageHeight = 47185920
  | | Media (SubDirectory) -->
  | | + [Media directory]
  | | | MediaHeader (SubDirectory) -->
  | | | + [BinaryData directory, 24 bytes]
  | | | | MediaHeaderVersion = 0
  | | | | MediaCreateDate = 3461148262
  | | | | MediaModifyDate = 3461148262
  | | | | MediaTimeScale = 90000
  | | | | MediaDuration = 47987
  | | | | MediaLanguageCode = 0
  | | | Handler (SubDirectory) -->
  | | | + [BinaryData directory, 36 bytes]
  | | | | HandlerClass =
  | | | | HandlerType = vide
  | | | | HandlerVendorID =
  | | | | HandlerDescription = VideoHandle
  | | | MediaInfo (SubDirectory) -->
  | | | + [MediaInfo directory]
  | | | | VideoHeader (SubDirectory) -->
  | | | | + [BinaryData directory, 12 bytes]
  | | | | | GraphicsMode = 0
  | | | | | OpColor = 0 0 0
  | | | | DataInfo (SubDirectory) -->
  | | | | + [DataInfo directory]
  | | | | | DataRef (SubDirectory) -->
  | | | | | + [DataRef directory]
  | | | | | | URL = .
  | | | | SampleTable (SubDirectory) -->
  | | | | + [SampleTable directory]
  | | | | | VideoSampleDesc (SubDirectory) -->
  | | | | | + [BinaryData directory, 94 bytes]
  | | | | | | CompressorID = avc1
  | | | | | | VendorID =
  | | | | | | SourceImageWidth = 1280
  | | | | | | SourceImageHeight = 720
  | | | | | | XResolution = 72
  | | | | | | YResolution = 72
  | | | | | | CompressorName =                                 
  | | | | | | BitDepth = 24
  | | | | | + [VideoSampleDesc directory]
  | | | | | | Unknown_avcC = .B.....gB.....r..h...
  | | | | | | PixelAspectRatio = ..
  | | | | | VideoFrameRate = ..............................................
  | | | | | SyncSampleTable = ..
  | | | | | SampleSizes = ......A..Tt%.g....n.....(.....X..
  | | | | | SampleToChunk = ....
  | | | | | ChunkOffset64 = .(
  | Track (SubDirectory) -->
  | + [Track directory]
  | | TrackHeader (SubDirectory) -->
  | | + [BinaryData directory, 84 bytes]
  | | | TrackHeaderVersion = 0
  | | | TrackCreateDate = 3461148262
  | | | TrackModifyDate = 3461148262
  | | | TrackID = 2
  | | | TrackDuration = 683
  | | | TrackLayer = 0
  | | | TrackVolume = 256
  | | | MatrixStructure = 1 0 0 0 1 0 0 0 16384
  | | | ImageWidth = 0
  | | | ImageHeight = 0
  | | Media (SubDirectory) -->
  | | + [Media directory]
  | | | MediaHeader (SubDirectory) -->
  | | | + [BinaryData directory, 24 bytes]
  | | | | MediaHeaderVersion = 0
  | | | | MediaCreateDate = 3461148262
  | | | | MediaModifyDate = 3461148262
  | | | | MediaTimeScale = 48000
  | | | | MediaDuration = 32769
  | | | | MediaLanguageCode = 0
  | | | Handler (SubDirectory) -->
  | | | + [BinaryData directory, 36 bytes]
  | | | | HandlerClass =
  | | | | HandlerType = soun
  | | | | HandlerVendorID =
  | | | | HandlerDescription = SoundHandle
  | | | MediaInfo (SubDirectory) -->
  | | | + [MediaInfo directory]
  | | | | AudioHeader (SubDirectory) -->
  | | | | + [BinaryData directory, 8 bytes]
  | | | | | Balance = 0
  | | | | DataInfo (SubDirectory) -->
  | | | | + [DataInfo directory]
  | | | | | DataRef (SubDirectory) -->
  | | | | | + [DataRef directory]
  | | | | | | URL = .
  | | | | SampleTable (SubDirectory) -->
  | | | | + [SampleTable directory]
  | | | | | AudioSampleDesc (SubDirectory) -->
  | | | | | + [BinaryData directory, 44 bytes]
  | | | | | | AudioFormat = mp4a
  | | | | | | AudioVendorID =
  | | | | | | AudioChannels = 2
  | | | | | | AudioBitsPerSample = 16
  | | | | | | AudioSampleRate = 48000
  | | | | | + [AudioSampleDesc directory]
  | | | | | | Unknown_esds = ....@...w.w.......
  | | | | | TimeToSampleTable = ..........
  | | | | | SampleSizes =  .U.U.V.U.U.V.U.U.V.U.U.V.U.U...............q.k.m.^.W.Y.P.N.9.;.8
  | | | | | SampleToChunk = .. .
  | | | | | ChunkOffset64 = ..-.


After ffmpeg and -tagsFromFile:


[root@bigguy moviestest]# exiftool -v dest.mp4
  ExifToolVersion = 9.76
  FileName = dest.mp4
  Directory = .
  FileSize = 814878
  FileModifyDate = 1424662824
  FileAccessDate = 1424662824
  FileInodeChangeDate = 1424662824
  FilePermissions = 33188
  FileType = MP4
  MIMEType = video/mp4
  FileType (SubDirectory) -->
  + [BinaryData directory, 24 bytes]
  | MajorBrand = isom
  | MinorVersion = .
  | CompatibleBrands = isomiso2avc1mp41
  Free =
  MovieDataSize = 809434
  MovieDataOffset = 48
  MovieData = ...e.@w.0.....,.~<....&"..`!T........  ... .\LC...A.".. .E...@..t.y..qM.=[snip]
  Movie (SubDirectory) -->
  + [Movie directory]
  | MovieHeader (SubDirectory) -->
  | + [BinaryData directory, 100 bytes]
  | | MovieHeaderVersion = 0
  | | CreateDate = 3461148262
  | | ModifyDate = 3461148262
  | | TimeScale = 1000
  | | Duration = 683
  | | PreferredRate = 65536
  | | PreferredVolume = 256
  | | MatrixStructure = 1 0 0 0 1 0 0 0 16384
  | | PreviewTime = 0
  | | PreviewDuration = 0
  | | PosterTime = 0
  | | SelectionTime = 0
  | | SelectionDuration = 0
  | | CurrentTime = 0
  | | NextTrackID = 3
  | Track (SubDirectory) -->
  | + [Track directory]
  | | TrackHeader (SubDirectory) -->
  | | + [BinaryData directory, 84 bytes]
  | | | TrackHeaderVersion = 0
  | | | TrackCreateDate = 3461148262
  | | | TrackModifyDate = 3461148262
  | | | TrackID = 1
  | | | TrackDuration = 536
  | | | TrackLayer = 0
  | | | TrackVolume = 0
  | | | MatrixStructure = 1 0 0 0 1 0 0 0 16384
  | | | ImageWidth = 83886080
  | | | ImageHeight = 47185920
  | | Media (SubDirectory) -->
  | | + [Media directory]
  | | | MediaHeader (SubDirectory) -->
  | | | + [BinaryData directory, 24 bytes]
  | | | | MediaHeaderVersion = 0
  | | | | MediaCreateDate = 3461148262
  | | | | MediaModifyDate = 3461148262
  | | | | MediaTimeScale = 90000
  | | | | MediaDuration = 48239
  | | | | MediaLanguageCode = 5575
  | | | Handler (SubDirectory) -->
  | | | + [BinaryData directory, 37 bytes]
  | | | | HandlerClass =
  | | | | HandlerType = vide
  | | | | HandlerVendorID =
  | | | | HandlerDescription = .VideoHandler
  | | | MediaInfo (SubDirectory) -->
  | | | + [MediaInfo directory]
  | | | | VideoHeader (SubDirectory) -->
  | | | | + [BinaryData directory, 12 bytes]
  | | | | | GraphicsMode = 0
  | | | | | OpColor = 0 0 0
  | | | | DataInfo (SubDirectory) -->
  | | | | + [DataInfo directory]
  | | | | | DataRef (SubDirectory) -->
  | | | | | + [DataRef directory]
  | | | | | | URL = .
  | | | | SampleTable (SubDirectory) -->
  | | | | + [SampleTable directory]
  | | | | | VideoSampleDesc (SubDirectory) -->
  | | | | | + [BinaryData directory, 94 bytes]
  | | | | | | CompressorID = avc1
  | | | | | | VendorID =
  | | | | | | SourceImageWidth = 1280
  | | | | | | SourceImageHeight = 720
  | | | | | | XResolution = 72
  | | | | | | YResolution = 72
  | | | | | | CompressorName =
  | | | | | | BitDepth = 24
  | | | | | + [VideoSampleDesc directory]
  | | | | | | Unknown_avcC = .B.....gB.....r..h...
  | | | | | VideoFrameRate = ..............................................
  | | | | | SyncSampleTable = ..
  | | | | | SampleToChunk = ....
  | | | | | SampleSizes = ......A..Tt%.g....n.....(.....X..
  | | | | | ChunkOffset = .0....1N.t7..6.r..".....Rc.....A..%.a......3...
  | Track (SubDirectory) -->
  | + [Track directory]
  | | TrackHeader (SubDirectory) -->
  | | + [BinaryData directory, 84 bytes]
  | | | TrackHeaderVersion = 0
  | | | TrackCreateDate = 3461148262
  | | | TrackModifyDate = 3461148262
  | | | TrackID = 2
  | | | TrackDuration = 683
  | | | TrackLayer = 0
  | | | TrackVolume = 256
  | | | MatrixStructure = 1 0 0 0 1 0 0 0 16384
  | | | ImageWidth = 0
  | | | ImageHeight = 0
  | | Media (SubDirectory) -->
  | | + [Media directory]
  | | | MediaHeader (SubDirectory) -->
  | | | + [BinaryData directory, 24 bytes]
  | | | | MediaHeaderVersion = 0
  | | | | MediaCreateDate = 3461148262
  | | | | MediaModifyDate = 3461148262
  | | | | MediaTimeScale = 48000
  | | | | MediaDuration = 32769
  | | | | MediaLanguageCode = 5575
  | | | Handler (SubDirectory) -->
  | | | + [BinaryData directory, 37 bytes]
  | | | | HandlerClass =
  | | | | HandlerType = soun
  | | | | HandlerVendorID =
  | | | | HandlerDescription = .SoundHandler
  | | | MediaInfo (SubDirectory) -->
  | | | + [MediaInfo directory]
  | | | | AudioHeader (SubDirectory) -->
  | | | | + [BinaryData directory, 8 bytes]
  | | | | | Balance = 0
  | | | | DataInfo (SubDirectory) -->
  | | | | + [DataInfo directory]
  | | | | | DataRef (SubDirectory) -->
  | | | | | + [DataRef directory]
  | | | | | | URL = .
  | | | | SampleTable (SubDirectory) -->
  | | | | + [SampleTable directory]
  | | | | | AudioSampleDesc (SubDirectory) -->
  | | | | | + [BinaryData directory, 44 bytes]
  | | | | | | AudioFormat = mp4a
  | | | | | | AudioVendorID =
  | | | | | | AudioChannels = 2
  | | | | | | AudioBitsPerSample = 16
  | | | | | | AudioSampleRate = 48000
  | | | | | + [AudioSampleDesc directory]
  | | | | | | Unknown_esds = .....@........
  | | | | | TimeToSampleTable = ........
  | | | | | SampleToChunk = ....
  | | | | | SampleSizes =  .U.U.V.U.U.V.U.U.V.U.U.V.U.U...............q.k.m.^.W.Y.P.N.9.;.8
  | | | | | ChunkOffset =  .....p..../..r........q[. ..!m..c....Q......&..u.....|.`M...[snip]
  | UserData (SubDirectory) -->
  | + [UserData directory]
  | | Meta (SubDirectory) -->
  | | + [Meta directory]
  | | | Handler (SubDirectory) -->
  | | | + [BinaryData directory, 26 bytes]
  | | | | HandlerClass =
  | | | | HandlerType = mdir
  | | | | HandlerVendorID = appl
  | | | | HandlerDescription =
  | | | ItemList (SubDirectory) -->
  | | | + [ItemList directory]
  | | | | Encoder = Lavf52.31.0
  XMP (SubDirectory) -->
  + [XMP directory, 3716 bytes]
  | XMPToolkit = Image::ExifTool 9.76
  | GPSLatitude = 39,56.640000N
  | GPSLongitude = 105,4.392000W
  | Category = mytag1
  | ImageHeight = 720
  | ImageWidth = 1280
  | XResolution = 72/1
  | YResolution = 72/1
  | CreateDate = 2013-09-04T14:04:22
  | ModifyDate = 2013-09-04T14:04:22
  | AudioSampleRate = 48000
  | VideoFrameRate = 29.851


Only the first tag (mytag1) is copied, and then only to an XMP structure that windows can't see. The rating (WM/SharedUserRating) isn't copied at all.

Is there any way to get both of those to come across in a Windows-happy way?

Thanks!

-Marcus

marwatk

In case it helps at all, here's the actual source file.

Phil Harvey

Hi Marcus,

Thanks for the sample.  ExifTool was not properly decoding these Microsoft tags.  I will fix this, and ExifTool 9.87 will be able to extract these tags.

But that is only half of your problem.  You also want to be able to write these tags.  Unfortunately, ExifTool only has limited write ability in MP4 files.  Other than a few date/time tags, it only writes XMP in these files (see the QuickTime tags documentation for details).  So if you want to copy these tags into XMP, then you will be able to use ExifTool 9.87, otherwise you'll have to find something else to do this.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

marwatk

Thanks for the quick reply, Phil!

Any plans to allow tag addition for quicktime? Poking around in WriteQuickTime.pl it looks like it would be a lot of work (need to rebuild the atoms all the way up?), so I totally understand if not.  Do you know of a one-off tool that can write them?

-Marcus


Phil Harvey

Hi Marcus,

It is not in my near-term plans to expand the write support for video files.

To other major impediments are:

1) Video formats are insanely inconsistent about where they store metadata.  ExifTool will read a tag from wherever it is found, but it wouldn't be easy to decide where (or if) it should be written.

2) I lack the utilities necessary to properly test the compatibility of the edited video files.

At one time, mp4v2 could write these Microsoft tags, but it seems as if this code has been removed due to some problem.  It is possible that AtomicParsley may be able to write these, but wouldn't get my hopes up too much.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

marwatk

That makes sense. Thanks for the pointers, I'll check them out.

-Marcus