Files
seanime-docker/seanime-2.9.10/internal/onlinestream/sources/streamsb.go
2025-09-20 14:08:38 +01:00

112 lines
3.0 KiB
Go

package onlinestream_sources
import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"seanime/internal/util"
"strings"
hibikeonlinestream "seanime/internal/extension/hibike/onlinestream"
)
type StreamSB struct {
Host string
Host2 string
UserAgent string
}
func NewStreamSB() *StreamSB {
return &StreamSB{
Host: "https://streamsss.net/sources50",
Host2: "https://watchsb.com/sources50",
UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36",
}
}
func (s *StreamSB) Payload(hex string) string {
return "566d337678566f743674494a7c7c" + hex + "7c7c346b6767586d6934774855537c7c73747265616d7362/6565417268755339773461447c7c346133383438333436313335376136323337373433383634376337633465366534393338373136643732373736343735373237613763376334363733353737303533366236333463353333363534366137633763373337343732363536313664373336327c7c6b586c3163614468645a47617c7c73747265616d7362"
}
func (s *StreamSB) Extract(uri string) (vs []*hibikeonlinestream.VideoSource, err error) {
defer util.HandlePanicInModuleThen("onlinestream/sources/streamsb/Extract", func() {
err = ErrVideoSourceExtraction
})
var ret []*hibikeonlinestream.VideoSource
id := strings.Split(uri, "/e/")[1]
if strings.Contains(id, "html") {
id = strings.Split(id, ".html")[0]
}
if id == "" {
return nil, errors.New("cannot find ID")
}
client := &http.Client{}
req, _ := http.NewRequest("GET", fmt.Sprintf("%s/%s", s.Host, s.Payload(hex.EncodeToString([]byte(id)))), nil)
req.Header.Add("watchsb", "sbstream")
req.Header.Add("User-Agent", s.UserAgent)
req.Header.Add("Referer", uri)
res, err := client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
var jsonResponse map[string]interface{}
err = json.Unmarshal(body, &jsonResponse)
if err != nil {
return nil, err
}
streamData, ok := jsonResponse["stream_data"].(map[string]interface{})
if !ok {
return nil, ErrNoVideoSourceFound
}
m3u8Urls, err := client.Get(streamData["file"].(string))
if err != nil {
return nil, err
}
defer m3u8Urls.Body.Close()
m3u8Body, err := io.ReadAll(m3u8Urls.Body)
if err != nil {
return nil, err
}
videoList := strings.Split(string(m3u8Body), "#EXT-X-STREAM-INF:")
for _, video := range videoList {
if !strings.Contains(video, "m3u8") {
continue
}
url := strings.Split(video, "\n")[1]
quality := strings.Split(strings.Split(video, "RESOLUTION=")[1], ",")[0]
quality = strings.Split(quality, "x")[1]
ret = append(ret, &hibikeonlinestream.VideoSource{
URL: url,
Quality: quality + "p",
Type: hibikeonlinestream.VideoSourceM3U8,
})
}
ret = append(ret, &hibikeonlinestream.VideoSource{
URL: streamData["file"].(string),
Quality: "auto",
Type: map[bool]hibikeonlinestream.VideoSourceType{true: hibikeonlinestream.VideoSourceM3U8, false: hibikeonlinestream.VideoSourceMP4}[strings.Contains(streamData["file"].(string), ".m3u8")],
})
return ret, nil
}