github.com/boki/go-xmp@v1.0.1/models/qt/qt_metadata.go (about) 1 // Copyright (c) 2017-2018 Alexander Eichhorn 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 package qt 16 17 import ( 18 "fmt" 19 "strconv" 20 "strings" 21 22 "trimmer.io/go-xmp/models/tiff" 23 "trimmer.io/go-xmp/xmp" 24 ) 25 26 // QuickTime Metadata Keys written by the "mdta" handler using Reverse DNS names. 27 // - "com.apple.quicktime." for Apple Quicktime default keys 28 // - "com.apple.proapps." for Apple Professional apps keys 29 // - "com.arri.camera" for Arri Camera metadata 30 // - "com.panasonic.professionalplugin" for Panasonic cameras 31 // - "com.panasonic.p2.metadata.bmp": "BMf*", 32 // - "com.panasonic.p2.metadata.xml": <xml> 33 // 34 35 // General Quicktime Metadata keys (from MacOS CoreMedia Framework headers and libs) 36 // 37 // VideoOrientation: like TIFF/EXIF Orientation property 38 // AffineTransform: used in place of a track display matrix, 3x3 float matrix in row major order 39 // Direction: degree offset from magnetic north 40 // 41 type QtMetadata struct { 42 // official metadata keys as defined in MacOS 10.11 SDK 43 Album string `qt:"com.apple.quicktime.album" qt:"©alb" xmp:"qt:Album"` 44 Arranger string `qt:"com.apple.quicktime.arranger" qt:"©arg" xmp:"qt:Arranger"` 45 Artist string `qt:"com.apple.quicktime.artist" qt:"albr" xmp:"qt:Artist"` 46 Artwork string `qt:"com.apple.quicktime.artwork" qt:"covr" xmp:"qt:Artwork"` 47 Author string `qt:"com.apple.quicktime.author" qt:"©aut" xmp:"qt:Author"` 48 CameraFrameReadoutTime string `qt:"com.apple.quicktime.camera.framereadouttimeinmicroseconds" qt:"-" xmp:"qt:CameraFrameReadoutTime"` 49 CameraIdentifier string `qt:"com.apple.quicktime.camera.identifier" qt:"cmid" xmp:"qt:CameraIdentifier"` 50 CollectionUser string `qt:"com.apple.quicktime.collection.user" qt:"coll" xmp:"qt:CollectionUser"` 51 Comment string `qt:"com.apple.quicktime.comment" qt:"©cmt" xmp:"qt:Comment"` 52 Composer string `qt:"com.apple.quicktime.composer" qt:"©wrt" xmp:"qt:Composer"` 53 ContentIdentifier string `qt:"com.apple.quicktime.content.identifier" qt:"cnID" xmp:"qt:ContentIdentifier"` 54 Copyright string `qt:"com.apple.quicktime.copyright" qt:"cprt" xmp:"qt:Copyright"` 55 CreationDate xmp.Date `qt:"com.apple.quicktime.creationdate" qt:"date" xmp:"qt:CreationDate"` 56 Credits string `qt:"com.apple.quicktime.credits" qt:"©src" xmp:"qt:Credits"` 57 Description string `qt:"com.apple.quicktime.description" qt:"©des" xmp:"qt:Description"` 58 DirectionFacing float64 `qt:"com.apple.quicktime.direction.facing" qt:"-" xmp:"qt:DirectionFacing"` 59 DirectionMotion float64 `qt:"com.apple.quicktime.direction.motion" qt:"-" xmp:"qt:DirectionMotion"` 60 Director string `qt:"com.apple.quicktime.director" qt:"©dir" xmp:"qt:Director"` 61 DisplayName string `qt:"com.apple.quicktime.displayname" qt:"name" xmp:"qt:DisplayName"` 62 EncodedBy string `qt:"com.apple.quicktime.encodedby" qt:"©enc" xmp:"qt:EncodedBy"` 63 Genre string `qt:"com.apple.quicktime.genre" qt:"©gen" xmp:"qt:Genre"` 64 Information string `qt:"com.apple.quicktime.information" qt:"©inf" xmp:"qt:Information"` 65 Keywords xmp.StringList `qt:"com.apple.quicktime.keywords" qt:"©key" xmp:"qt:Keywords"` 66 LocationBody string `qt:"com.apple.quicktime.location.body" qt:"-" xmp:"-"` 67 LocationDate xmp.Date `qt:"com.apple.quicktime.location.date" qt:"-" xmp:"-"` 68 LocationISO6709 string `qt:"com.apple.quicktime.location.iso6709" qt:"©xyz" xmp:"-"` 69 LocationName string `qt:"com.apple.quicktime.location.name" qt:"-" xmp:"-"` 70 LocationNote string `qt:"com.apple.quicktime.location.note" qt:"-" xmp:"-"` 71 LocationRole LocationRole `qt:"com.apple.quicktime.location.role" qt:"-" xmp:"-"` 72 Make string `qt:"com.apple.quicktime.make" qt:"©mak" xmp:"qt:Make"` 73 Model string `qt:"com.apple.quicktime.model" qt:"©mod" xmp:"qt:Model"` 74 OriginalArtist string `qt:"com.apple.quicktime.originalartist" qt:"©ope" xmp:"qt:OriginalArtist"` 75 Performer string `qt:"com.apple.quicktime.performer" qt:"©prf" xmp:"qt:Performer"` 76 PhonogramRights string `qt:"com.apple.quicktime.phonogramrights" qt:"©phg" xmp:"qt:PhonogramRights"` 77 Producer string `qt:"com.apple.quicktime.producer" qt:"©prd" xmp:"qt:Producer"` 78 Publisher string `qt:"com.apple.quicktime.publisher" qt:"©pub" xmp:"qt:Publisher"` 79 USRating float64 `qt:"com.apple.quicktime.rating.user" qt:"rtng" xmp:"qt:USRating"` 80 Software string `qt:"com.apple.quicktime.software" qt:"©swr" xmp:"qt:Software"` 81 Title string `qt:"com.apple.quicktime.title" qt:"©nam" xmp:"qt:Title"` 82 Year int `qt:"com.apple.quicktime.year" qt:"yrrc" xmp:"qt:Year"` 83 84 // more tags not captured above 85 Version string `qt:"com.apple.quicktime.version" qt:"VERS" xmp:"qt:Version"` 86 PreferredAffineTransform string `qt:"com.apple.quicktime.preferred-affine-transform" qt:"-" xmp:"qt:PreferredAffineTransform"` 87 VideoOrientation tiff.OrientationType `qt:"com.apple.quicktime.video-orientation" qt:"-" xmp:"qt:VideoOrientation"` 88 WindowLocation Point `qt:"com.apple.quicktime.windowlocation" qt:"WLOC" xmp:"qt:WindowLocation"` 89 CoreMotion string `qt:"com.apple.quicktime.core-motion" qt:"-" xmp:"qt:CoreMotion"` 90 CameraDebugInfo string `qt:"com.apple.quicktime.camera-debug-info" qt:"-" xmp:"qt:CameraDebugInfo"` 91 IsMontage string `qt:"com.apple.quicktime.is-montage" qt:"-" xmp:"qt:IsMontage"` 92 PixelDensity string `qt:"com.apple.quicktime.pixeldensity" qt:"-" xmp:"qt:PixelDensity"` 93 DetectedFace string `qt:"com.apple.quicktime.detected-face" qt:"-" xmp:"qt:DetectedFace"` 94 HasEAN13 Bool `qt:"com.apple.quicktime.detected-machine-readable-code.EAN13" qt:"-" xmp:"qt:HasEAN13"` 95 HasEAN8 Bool `qt:"com.apple.quicktime.detected-machine-readable-code.EAN8" qt:"-" xmp:"qt:HasEAN8"` 96 HasUPCE Bool `qt:"com.apple.quicktime.detected-machine-readable-code.UPCE" qt:"-" xmp:"qt:HasUPCE"` 97 HasCode39 Bool `qt:"com.apple.quicktime.detected-machine-readable-code.Code39" qt:"-" xmp:"qt:HasCode39"` 98 HasCode39Checksum Bool `qt:"com.apple.quicktime.detected-machine-readable-code.Code39Checksum" qt:"-" xmp:"qt:HasCode39Checksum"` 99 HasCode93 Bool `qt:"com.apple.quicktime.detected-machine-readable-code.Code93" qt:"-" xmp:"qt:HasCode93"` 100 HasCode128 Bool `qt:"com.apple.quicktime.detected-machine-readable-code.Code128" qt:"-" xmp:"qt:HasCode128"` 101 HasI2of5 Bool `qt:"com.apple.quicktime.detected-machine-readable-code.I2of5" qt:"-" xmp:"qt:HasI2of5"` 102 HasITF14 Bool `qt:"com.apple.quicktime.detected-machine-readable-code.ITF14" qt:"-" xmp:"qt:HasITF14"` 103 HasDataMatrix Bool `qt:"com.apple.quicktime.detected-machine-readable-code.DataMatrix" qt:"-" xmp:"qt:HasDataMatrix"` 104 HasQR Bool `qt:"com.apple.quicktime.detected-machine-readable-code.QR" qt:"-" xmp:"qt:HasQR"` 105 HasAztec Bool `qt:"com.apple.quicktime.detected-machine-readable-code.Aztec" qt:"-" xmp:"qt:HasAztec"` 106 HasPDF417 Bool `qt:"com.apple.quicktime.detected-machine-readable-code.PDF417" qt:"-" xmp:"qt:HasPDF417"` 107 Extension xmp.TagList `qt:",any" qt:",any" xmp:"qt:extension"` 108 109 // composite structs 110 Location *Location `qt:"-" qt:"-" xmp:"qt:Location"` 111 } 112 113 func (m *QtMetadata) Namespaces() xmp.NamespaceList { 114 return xmp.NamespaceList{NsQuicktime} 115 } 116 117 func (m *QtMetadata) Can(nsName string) bool { 118 return nsName == NsQuicktime.GetName() 119 } 120 121 func (x *QtMetadata) SyncModel(d *xmp.Document) error { 122 return nil 123 } 124 125 func (x *QtMetadata) SyncFromXMP(d *xmp.Document) error { 126 if x.Location != nil { 127 x.LocationBody = x.Location.Body 128 x.LocationDate = x.Location.Date 129 x.LocationISO6709 = strings.Join([]string{ 130 string(x.Location.Latitude), 131 string(x.Location.Longitude), 132 strconv.FormatFloat(x.Location.Altitude, 'f', -1, 64), 133 }, "+") 134 x.LocationName = x.Location.Name 135 x.LocationNote = x.Location.Note 136 x.LocationRole = x.Location.Role 137 } 138 return nil 139 } 140 141 func (x *QtMetadata) SyncToXMP(d *xmp.Document) error { 142 if x.Location == nil && x.LocationISO6709 != "" && x.LocationName != "" { 143 x.Location = &Location{ 144 Body: x.LocationBody, 145 Date: x.LocationDate, 146 Name: x.LocationName, 147 Note: x.LocationNote, 148 Role: x.LocationRole, 149 } 150 // "+43.5968+005.4797+362.904/", 151 for i, v := range strings.Split(x.LocationISO6709, "+") { 152 switch i { 153 case 0: 154 x.Location.Latitude = xmp.GPSCoord(v) 155 case 1: 156 x.Location.Longitude = xmp.GPSCoord(v) 157 case 2: 158 v = strings.TrimSuffix(v, "/") 159 x.Location.Altitude, _ = strconv.ParseFloat(v, 64) 160 } 161 } 162 } 163 return nil 164 } 165 166 func (x *QtMetadata) CanTag(tag string) bool { 167 _, err := xmp.GetNativeField(x, tag) 168 return err == nil 169 } 170 171 func (x *QtMetadata) GetTag(tag string) (string, error) { 172 if v, err := xmp.GetNativeField(x, tag); err != nil { 173 return "", fmt.Errorf("%s: %v", NsQuicktime.GetName(), err) 174 } else { 175 return v, nil 176 } 177 } 178 179 func (x *QtMetadata) SetTag(tag, value string) error { 180 if err := xmp.SetNativeField(x, tag, value); err != nil { 181 return fmt.Errorf("%s: %v", NsQuicktime.GetName(), err) 182 } 183 return nil 184 }