@@ -15,7 +15,7 @@ type Channel struct {
1515 ChannelID string `json:"channelID"` // 频道ID
1616 ChannelName string `json:"channelName"` // 频道名称
1717 UserChannelID string `json:"userChannelID"` // 频道号
18- ChannelURL * url.URL `json:"channelURL "` // 频道URL
18+ ChannelURLs [] url.URL `json:"channelURLs "` // 频道URL列表
1919 TimeShift string `json:"timeShift"` // 时移类型
2020 TimeShiftLength time.Duration `json:"timeShiftLength"` // 支持的时移长度
2121 TimeShiftURL * url.URL `json:"timeShiftURL"` // 时移地址(回放地址)
@@ -24,40 +24,36 @@ type Channel struct {
2424}
2525
2626// ToM3UFormat 转换为M3U格式内容
27- func ToM3UFormat (channels []Channel , udpxyURL , catchupSource string ) (string , error ) {
27+ func ToM3UFormat (channels []Channel , udpxyURL , catchupSource string , multicastFirst bool ) (string , error ) {
2828 if len (channels ) == 0 {
2929 return "" , errors .New ("no channels found" )
3030 }
3131
3232 var sb strings.Builder
3333 sb .WriteString ("#EXTM3U\n " )
3434 for _ , channel := range channels {
35- var err error
36- var channelURL string
37- if udpxyURL != "" && channel .ChannelURL .Scheme == SCHEME_IGMP {
38- channelURL , err = url .JoinPath (udpxyURL , fmt .Sprintf ("/rtp/%s" , channel .ChannelURL .Host ))
39- if err != nil {
40- return "" , err
41- }
42- } else {
43- channelURL = channel .ChannelURL .String ()
35+ // 根据指定条件,获取频道URL地址
36+ channelURLStr , err := getChannelURLStr (channel .ChannelURLs , udpxyURL , multicastFirst )
37+ if err != nil {
38+ return "" , err
4439 }
40+
4541 var m3uLine string
4642 if channel .TimeShift == "1" && channel .TimeShiftLength > 0 {
4743 m3uLine = fmt .Sprintf ("#EXTINF:-1 tvg-id=\" %s\" tvg-chno=\" %s\" catchup=\" %s\" catchup-source=\" %s\" catchup-days=\" %d\" group-title=\" %s\" ,%s\n %s\n " ,
4844 channel .ChannelID , channel .UserChannelID , "default" , channel .TimeShiftURL .String ()+ catchupSource ,
49- int64 (channel .TimeShiftLength .Hours ()/ 24 ), channel .GroupName , channel .ChannelName , channelURL )
45+ int64 (channel .TimeShiftLength .Hours ()/ 24 ), channel .GroupName , channel .ChannelName , channelURLStr )
5046 } else {
5147 m3uLine = fmt .Sprintf ("#EXTINF:-1 tvg-id=\" %s\" tvg-chno=\" %s\" group-title=\" %s\" ,%s\n %s\n " ,
52- channel .ChannelID , channel .UserChannelID , channel .GroupName , channel .ChannelName , channelURL )
48+ channel .ChannelID , channel .UserChannelID , channel .GroupName , channel .ChannelName , channelURLStr )
5349 }
5450 sb .WriteString (m3uLine )
5551 }
5652 return sb .String (), nil
5753}
5854
5955// ToTxtFormat 转换为txt格式内容
60- func ToTxtFormat (channels []Channel , udpxyURL string ) (string , error ) {
56+ func ToTxtFormat (channels []Channel , udpxyURL string , multicastFirst bool ) (string , error ) {
6157 if len (channels ) == 0 {
6258 return "" , errors .New ("no channels found" )
6359 }
@@ -88,21 +84,41 @@ func ToTxtFormat(channels []Channel, udpxyURL string) (string, error) {
8884
8985 // 输出频道信息
9086 for _ , channel := range groupChannels {
91- var err error
92- var channelURL string
93- if udpxyURL != "" && channel .ChannelURL .Scheme == SCHEME_IGMP {
94- channelURL , err = url .JoinPath (udpxyURL , fmt .Sprintf ("/rtp/%s" , channel .ChannelURL .Host ))
95- if err != nil {
96- return "" , err
97- }
98- } else {
99- channelURL = channel .ChannelURL .String ()
87+ // 根据指定条件,获取频道URL地址
88+ channelURLStr , err := getChannelURLStr (channel .ChannelURLs , udpxyURL , multicastFirst )
89+ if err != nil {
90+ return "" , err
10091 }
10192
10293 txtLine := fmt .Sprintf ("%s,%s\n " ,
103- channel .ChannelName , channelURL )
94+ channel .ChannelName , channelURLStr )
10495 sb .WriteString (txtLine )
10596 }
10697 }
10798 return sb .String (), nil
10899}
100+
101+ // getChannelURLStr 根据指定条件,获取频道URL地址
102+ func getChannelURLStr (channelURLs []url.URL , udpxyURL string , multicastFirst bool ) (string , error ) {
103+ if len (channelURLs ) == 0 {
104+ return "" , errors .New ("no channel urls found" )
105+ }
106+
107+ var channelURL url.URL
108+ if len (channelURLs ) == 1 {
109+ channelURL = channelURLs [0 ]
110+ } else {
111+ for _ , channelURL = range channelURLs {
112+ if (multicastFirst && channelURL .Scheme == SCHEME_IGMP ) ||
113+ (! multicastFirst && channelURL .Scheme != SCHEME_IGMP ) {
114+ break
115+ }
116+ }
117+ }
118+
119+ if udpxyURL != "" && channelURL .Scheme == SCHEME_IGMP {
120+ return url .JoinPath (udpxyURL , fmt .Sprintf ("/rtp/%s" , channelURL .Host ))
121+ } else {
122+ return channelURL .String (), nil
123+ }
124+ }
0 commit comments