1package dlna 2 3import ( 4 "fmt" 5 "strings" 6 "time" 7) 8 9const ( 10 TimeSeekRangeDomain = "TimeSeekRange.dlna.org" 11 ContentFeaturesDomain = "contentFeatures.dlna.org" 12 TransferModeDomain = "transferMode.dlna.org" 13) 14 15type ContentFeatures struct { 16 ProfileName string 17 SupportTimeSeek bool 18 SupportRange bool 19 // Play speeds, DLNA.ORG_PS would go here if supported. 20 Transcoded bool 21} 22 23func BinaryInt(b bool) uint { 24 if b { 25 return 1 26 } else { 27 return 0 28 } 29} 30 31// flags are in hex. trailing 24 zeroes, 26 are after the space 32// "DLNA.ORG_OP=" time-seek-range-supp bytes-range-header-supp 33func (cf ContentFeatures) String() (ret string) { 34 //DLNA.ORG_PN=[a-zA-Z0-9_]* 35 params := make([]string, 0, 2) 36 if cf.ProfileName != "" { 37 params = append(params, "DLNA.ORG_PN="+cf.ProfileName) 38 } 39 params = append(params, fmt.Sprintf( 40 "DLNA.ORG_OP=%b%b;DLNA.ORG_CI=%b", 41 BinaryInt(cf.SupportTimeSeek), 42 BinaryInt(cf.SupportRange), 43 BinaryInt(cf.Transcoded))) 44 return strings.Join(params, ";") 45} 46 47func ParseNPTTime(s string) (time.Duration, error) { 48 var h, m, sec, ms time.Duration 49 n, err := fmt.Sscanf(s, "%d:%2d:%2d.%3d", &h, &m, &sec, &ms) 50 if err != nil { 51 return -1, err 52 } 53 if n < 3 { 54 return -1, fmt.Errorf("invalid npt time: %s", s) 55 } 56 ret := time.Duration(h) * time.Hour 57 ret += time.Duration(m) * time.Minute 58 ret += sec * time.Second 59 ret += ms * time.Millisecond 60 return ret, nil 61} 62 63func FormatNPTTime(npt time.Duration) string { 64 npt /= time.Millisecond 65 ms := npt % 1000 66 npt /= 1000 67 s := npt % 60 68 npt /= 60 69 m := npt % 60 70 npt /= 60 71 h := npt 72 return fmt.Sprintf("%02d:%02d:%02d.%03d", h, m, s, ms) 73} 74 75type NPTRange struct { 76 Start, End time.Duration 77} 78 79func ParseNPTRange(s string) (ret NPTRange, err error) { 80 ss := strings.SplitN(s, "-", 2) 81 if ss[0] != "" { 82 ret.Start, err = ParseNPTTime(ss[0]) 83 if err != nil { 84 return 85 } 86 } 87 if ss[1] != "" { 88 ret.End, err = ParseNPTTime(ss[1]) 89 if err != nil { 90 return 91 } 92 } 93 return 94} 95 96func (me NPTRange) String() (ret string) { 97 ret = me.Start.String() + "-" 98 if me.End >= 0 { 99 ret += me.End.String() 100 } 101 return 102} 103