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  }