github.com/boki/go-xmp@v1.0.1/models/riff/model.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 riff implements metadata for AVI and WAV files as defined by XMP Specification Part 3. 16 package riff 17 18 import ( 19 "fmt" 20 "trimmer.io/go-xmp/models/dc" 21 "trimmer.io/go-xmp/models/xmp_base" 22 "trimmer.io/go-xmp/models/xmp_dm" 23 "trimmer.io/go-xmp/xmp" 24 ) 25 26 var ( 27 NsRiff = xmp.NewNamespace("riffinfo", "http://ns.adobe.com/riff/info", NewModel) 28 ) 29 30 func init() { 31 xmp.Register(NsRiff, xmp.SoundMetadata) 32 } 33 34 func NewModel(name string) xmp.Model { 35 return &RiffInfo{} 36 } 37 38 func MakeModel(d *xmp.Document) (*RiffInfo, error) { 39 m, err := d.MakeModel(NsRiff) 40 if err != nil { 41 return nil, err 42 } 43 x, _ := m.(*RiffInfo) 44 return x, nil 45 } 46 47 func FindModel(d *xmp.Document) *RiffInfo { 48 if m := d.FindModel(NsRiff); m != nil { 49 return m.(*RiffInfo) 50 } 51 return nil 52 } 53 54 type RiffInfo struct { 55 ArchiveLocation string `riffinfo:"IARL" xmp:"riffinfo:archivalLocation"` 56 Artist string `riffinfo:"IART" xmp:"xmpDM:artist"` 57 CommissionedBy StringArray `riffinfo:"ICMS" xmp:"riffinfo:commissioned"` // list: semicolon+blank separated 58 Comments string `riffinfo:"ICMT" xmp:"xmpDM:logComment"` 59 Copyright AltString `riffinfo:"ICOP" xmp:"dc:rights"` // list: semicolon+blank separated 60 CreateDate xmp.Date `riffinfo:"ICRD" xmp:"xmp:CreateDate"` // YYYY-MM-DD 61 Engineeer string `riffinfo:"IENG" xmp:"xmpDM:engineer"` // list: semicolon+blank separated 62 Genre string `riffinfo:"IGNR" xmp:"xmpDM:genre"` 63 Keywords StringArray `riffinfo:"IKEY" xmp:"dc:subject"` // list: semicolon+blank separated 64 SourceMedium string `riffinfo:"IMED" xmp:"dc:source"` 65 Title AltString `riffinfo:"INAM" xmp:"riffinfo:name"` 66 Product string `riffinfo:"IPRD" xmp:"riffinfo:product"` 67 Description AltString `riffinfo:"ISBJ" xmp:"dc:description"` 68 Software xmp.AgentName `riffinfo:"ISFT" xmp:"xmp:CreatorTool"` 69 SourceCredit string `riffinfo:"ISRC" xmp:"riffinfo:source"` 70 SourceType StringArray `riffinfo:"ISRF" xmp:"dc:type"` 71 Technician string `riffinfo:"ITCH" xmp:"riffinfo:technician"` 72 73 // other tags found in the wild 74 Rated string `riffinfo:"AGES" xmp:"riffinfo:Rated"` 75 Comment string `riffinfo:"CMNT" xmp:"riffinfo:Comment"` 76 EncodedBy string `riffinfo:"CODE" xmp:"riffinfo:EncodedBy"` 77 Comments2 string `riffinfo:"COMM" xmp:"riffinfo:Comments"` 78 Directory string `riffinfo:"DIRC" xmp:"riffinfo:Directory"` 79 SoundSchemeTitle string `riffinfo:"DISP" xmp:"riffinfo:SoundSchemeTitle"` 80 DateTimeOriginal string `riffinfo:"DTIM" xmp:"riffinfo:DateTimeOriginal"` 81 Genre2 string `riffinfo:"GENR" xmp:"riffinfo:Genre"` 82 ArchivalLocation string `riffinfo:"IARL" xmp:"riffinfo:ArchivalLocation"` 83 FirstLanguage string `riffinfo:"IAS1" xmp:"riffinfo:FirstLanguage"` 84 SecondLanguage string `riffinfo:"IAS2" xmp:"riffinfo:SecondLanguage"` 85 ThirdLanguage string `riffinfo:"IAS3" xmp:"riffinfo:ThirdLanguage"` 86 FourthLanguage string `riffinfo:"IAS4" xmp:"riffinfo:FourthLanguage"` 87 FifthLanguage string `riffinfo:"IAS5" xmp:"riffinfo:FifthLanguage"` 88 SixthLanguage string `riffinfo:"IAS6" xmp:"riffinfo:SixthLanguage"` 89 SeventhLanguage string `riffinfo:"IAS7" xmp:"riffinfo:SeventhLanguage"` 90 EighthLanguage string `riffinfo:"IAS8" xmp:"riffinfo:EighthLanguage"` 91 NinthLanguage string `riffinfo:"IAS9" xmp:"riffinfo:NinthLanguage"` 92 BaseURL string `riffinfo:"IBSU" xmp:"riffinfo:BaseURL"` 93 DefaultAudioStream string `riffinfo:"ICAS" xmp:"riffinfo:DefaultAudioStream"` 94 CostumeDesigner string `riffinfo:"ICDS" xmp:"riffinfo:CostumeDesigner"` 95 Commissioned string `riffinfo:"ICMS" xmp:"riffinfo:Commissioned"` 96 Cinematographer string `riffinfo:"ICNM" xmp:"riffinfo:Cinematographer"` 97 Country string `riffinfo:"ICNT" xmp:"riffinfo:Country"` 98 Cropped string `riffinfo:"ICRP" xmp:"riffinfo:Cropped"` 99 Dimensions string `riffinfo:"IDIM" xmp:"riffinfo:Dimensions"` 100 DateTimeOriginal2 string `riffinfo:"IDIT" xmp:"-"` 101 DotsPerInch string `riffinfo:"IDPI" xmp:"riffinfo:DotsPerInch"` 102 DistributedBy string `riffinfo:"IDST" xmp:"riffinfo:DistributedBy"` 103 EditedBy string `riffinfo:"IEDT" xmp:"riffinfo:EditedBy"` 104 EncodedBy2 string `riffinfo:"IENC" xmp:"-"` 105 Lightness string `riffinfo:"ILGT" xmp:"riffinfo:Lightness"` 106 LogoURL string `riffinfo:"ILGU" xmp:"riffinfo:LogoURL"` 107 LogoIconURL string `riffinfo:"ILIU" xmp:"riffinfo:LogoIconURL"` 108 Language string `riffinfo:"ILNG" xmp:"riffinfo:Language"` 109 MoreInfoBannerImage string `riffinfo:"IMBI" xmp:"riffinfo:MoreInfoBannerImage"` 110 MoreInfoBannerURL string `riffinfo:"IMBU" xmp:"riffinfo:MoreInfoBannerURL"` 111 MoreInfoText string `riffinfo:"IMIT" xmp:"riffinfo:MoreInfoText"` 112 MoreInfoURL string `riffinfo:"IMIU" xmp:"riffinfo:MoreInfoURL"` 113 MusicBy string `riffinfo:"IMUS" xmp:"riffinfo:MusicBy"` 114 ProductionDesigner string `riffinfo:"IPDS" xmp:"riffinfo:ProductionDesigner"` 115 NumColors string `riffinfo:"IPLT" xmp:"riffinfo:NumColors"` 116 ProducedBy string `riffinfo:"IPRO" xmp:"riffinfo:ProducedBy"` 117 RippedBy string `riffinfo:"IRIP" xmp:"riffinfo:RippedBy"` 118 Rating string `riffinfo:"IRTD" xmp:"riffinfo:Rating"` 119 SecondaryGenre string `riffinfo:"ISGN" xmp:"riffinfo:SecondaryGenre"` 120 Sharpness string `riffinfo:"ISHP" xmp:"riffinfo:Sharpness"` 121 TimeCode string `riffinfo:"ISMP" xmp:"riffinfo:TimeCode"` 122 ProductionStudio string `riffinfo:"ISTD" xmp:"riffinfo:ProductionStudio"` 123 Starring string `riffinfo:"ISTR" xmp:"riffinfo:Starring"` 124 WatermarkURL string `riffinfo:"IWMU" xmp:"riffinfo:WatermarkURL"` 125 WrittenBy string `riffinfo:"IWRI" xmp:"riffinfo:WrittenBy"` 126 Language2 string `riffinfo:"LANG" xmp:"riffinfo:Language2"` 127 Location string `riffinfo:"LOCA" xmp:"riffinfo:Location"` 128 Part string `riffinfo:"PRT1" xmp:"riffinfo:Part"` 129 NumberOfParts string `riffinfo:"PRT2" xmp:"riffinfo:NumberOfParts"` 130 Rate string `riffinfo:"RATE" xmp:"riffinfo:Rate"` 131 Starring2 string `riffinfo:"STAR" xmp:"-"` 132 Statistics string `riffinfo:"STAT" xmp:"riffinfo:Statistics"` 133 TapeName string `riffinfo:"TAPE" xmp:"riffinfo:TapeName"` 134 EndTimecode string `riffinfo:"TCDO" xmp:"riffinfo:EndTimecode"` 135 StartTimecode string `riffinfo:"TCOD" xmp:"riffinfo:StartTimecode"` 136 Title2 string `riffinfo:"TITL" xmp:"riffinfo:Title"` 137 Length string `riffinfo:"TLEN" xmp:"riffinfo:Length"` 138 Organization string `riffinfo:"TORG" xmp:"riffinfo:Organization"` 139 TrackNumber string `riffinfo:"TRCK" xmp:"riffinfo:TrackNumber"` 140 URL string `riffinfo:"TURL" xmp:"riffinfo:URL"` 141 Version string `riffinfo:"TVER" xmp:"riffinfo:Version"` 142 VegasVersionMajor string `riffinfo:"VMAJ" xmp:"riffinfo:VegasVersionMajor"` 143 VegasVersionMinor string `riffinfo:"VMIN" xmp:"riffinfo:VegasVersionMinor"` 144 Year string `riffinfo:"YEAR" xmp:"riffinfo:Year"` 145 } 146 147 func (m *RiffInfo) Namespaces() xmp.NamespaceList { 148 return xmp.NamespaceList{NsRiff} 149 } 150 151 func (m *RiffInfo) Can(nsName string) bool { 152 return nsName == NsRiff.GetName() 153 } 154 155 func (x *RiffInfo) SyncModel(d *xmp.Document) error { 156 return nil 157 } 158 159 func (x *RiffInfo) SyncFromXMP(d *xmp.Document) error { 160 if m := dc.FindModel(d); m != nil { 161 if len(m.Rights) > 0 { 162 x.Copyright = AltString(m.Rights) 163 } 164 if len(m.Subject) > 0 { 165 x.Keywords = StringArray(m.Subject) 166 } 167 if len(m.Type) > 0 { 168 x.SourceType = StringArray(m.Type) 169 } 170 if len(m.Description) > 0 { 171 x.Description = AltString(m.Description) 172 } 173 if len(m.Title) > 0 { 174 x.Title = AltString(m.Title) 175 } 176 x.SourceMedium = m.Source 177 } 178 if base := xmpbase.FindModel(d); base != nil { 179 if !base.CreateDate.IsZero() { 180 x.CreateDate = base.CreateDate 181 } 182 x.Software = base.CreatorTool 183 } 184 if dm := xmpdm.FindModel(d); dm != nil { 185 if dm.Artist != "" { 186 x.Artist = dm.Artist 187 } 188 if dm.LogComment != "" { 189 x.Comments = dm.LogComment 190 } 191 if dm.Genre != "" { 192 x.Genre = dm.Genre 193 } 194 if dm.Engineer != "" { 195 x.Engineeer = dm.Engineer 196 } 197 } 198 return nil 199 } 200 201 func (x *RiffInfo) SyncToXMP(d *xmp.Document) error { 202 if x.DateTimeOriginal2 != "" && x.DateTimeOriginal == "" { 203 x.DateTimeOriginal = x.DateTimeOriginal2 204 } 205 if x.EncodedBy2 != "" && x.EncodedBy == "" { 206 x.EncodedBy = x.EncodedBy2 207 } 208 if x.Starring2 != "" && x.Starring == "" { 209 x.Starring = x.Starring2 210 } 211 // manually add INAM to dc:title["x-default"] if no title exists 212 m, err := dc.MakeModel(d) 213 if err != nil { 214 return err 215 } 216 if len(m.Title) == 0 { 217 m.Title = xmp.AltString(x.Title) 218 } 219 return nil 220 } 221 222 func (x *RiffInfo) CanTag(tag string) bool { 223 _, err := xmp.GetNativeField(x, tag) 224 return err == nil 225 } 226 227 func (x *RiffInfo) GetTag(tag string) (string, error) { 228 if v, err := xmp.GetNativeField(x, tag); err != nil { 229 return "", fmt.Errorf("%s: %v", NsRiff.GetName(), err) 230 } else { 231 return v, nil 232 } 233 } 234 235 func (x *RiffInfo) SetTag(tag, value string) error { 236 if err := xmp.SetNativeField(x, tag, value); err != nil { 237 return fmt.Errorf("%s: %v", NsRiff.GetName(), err) 238 } 239 return nil 240 } 241 242 // Lists all non-empty tags. 243 func (x *RiffInfo) ListTags() (xmp.TagList, error) { 244 if l, err := xmp.ListNativeFields(x); err != nil { 245 return nil, fmt.Errorf("%s: %v", NsRiff.GetName(), err) 246 } else { 247 return l, nil 248 } 249 }