github.com/boki/go-xmp@v1.0.1/models/itunes/types.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 // iTunes-style metadata as found in .mp4, .m4a, .m4p, .m4v, .m4b files 16 package itunes 17 18 import ( 19 "bytes" 20 "fmt" 21 "strconv" 22 "strings" 23 ) 24 25 // https://sourceforge.net/p/mediainfo/feature-requests/398/ 26 // https://forums.mp3tag.de/index.php?showtopic=12640 27 type SMPB struct { 28 EncoderDelay int64 `xmp:"iTunes:EncoderDelay,attr"` 29 EndPadding int64 `xmp:"iTunes:EndPadding,attr"` 30 OriginalSampleCount int64 `xmp:"iTunes:OriginalSampleCount,attr"` 31 EndOffset int64 `xmp:"iTunes:EndOffset,attr"` 32 } 33 34 // Gapless Playback info 35 // iTunSMPB 00000000 00000840 000001CA 00000000003F31F6 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 36 // Delay Padding SampleCount EndOffset 37 func (x *SMPB) UnmarshalText(data []byte) error { 38 var err error 39 sm := SMPB{} 40 for i, v := range bytes.Fields(data) { 41 switch i { 42 case 1: 43 if sm.EncoderDelay, err = strconv.ParseInt(string(v), 16, 32); err != nil { 44 return fmt.Errorf("iTunes: cannot parse SMPB '%s': %v", string(data), err) 45 } 46 case 2: 47 if sm.EndPadding, err = strconv.ParseInt(string(v), 16, 32); err != nil { 48 return fmt.Errorf("iTunes: cannot parse SMPB '%s': %v", string(data), err) 49 } 50 case 3: 51 if sm.OriginalSampleCount, err = strconv.ParseInt(string(v), 16, 64); err != nil { 52 return fmt.Errorf("iTunes: cannot parse SMPB '%s': %v", string(data), err) 53 } 54 case 5: 55 if sm.EndOffset, err = strconv.ParseInt(string(v), 16, 64); err != nil { 56 return fmt.Errorf("iTunes: cannot parse SMPB '%s': %v", string(data), err) 57 } 58 } 59 } 60 *x = sm 61 return nil 62 } 63 64 type Bool int // 0 no, 1 yes 65 66 func (b Bool) Value() bool { 67 return b == 1 68 } 69 70 type ContentRating struct { 71 Standard string `xmp:"iTunes:Standard,attr"` 72 Rating string `xmp:"iTunes:Rating,attr"` 73 Score string `xmp:"iTunes:Score,attr"` 74 Reasons string `xmp:"iTunes:Reasons,attr"` 75 } 76 77 func (x ContentRating) IsZero() bool { 78 return x.Standard == "" && x.Rating == "" 79 } 80 81 func (x ContentRating) String() string { 82 buf := bytes.Buffer{} 83 buf.WriteByte('(') 84 buf.WriteString(x.Standard) 85 buf.WriteByte('|') 86 buf.WriteString(x.Rating) 87 buf.WriteByte('|') 88 buf.WriteString(x.Score) 89 buf.WriteByte('|') 90 buf.WriteString(x.Reasons) 91 return buf.String() 92 } 93 94 func (x *ContentRating) UnmarshalText(data []byte) error { 95 cr := ContentRating{} 96 v := string(data) 97 v = strings.TrimSpace(v) 98 v = strings.TrimPrefix(v, "(") 99 v = strings.TrimSuffix(v, ")") 100 for i, s := range strings.Split(v, "|") { 101 switch i { 102 case 1: 103 cr.Standard = s 104 case 2: 105 cr.Rating = s 106 case 3: 107 cr.Score = s 108 case 4: 109 cr.Reasons = s 110 } 111 } 112 *x = cr 113 return nil 114 } 115 116 func (x ContentRating) MarshalText() ([]byte, error) { 117 if x.IsZero() { 118 return nil, nil 119 } 120 return []byte(x.String()), nil 121 }