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
In case it helps at all, here's the actual source file.
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 (https://exiftool.org/TagNames/QuickTime.html) 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
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
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
That makes sense. Thanks for the pointers, I'll check them out.
-Marcus