Feat: more source add type filed

pull/160/head
zijiren233 10 months ago
parent 0cf9ce5b07
commit 5b560cd3b7

@ -21,6 +21,19 @@ type Movie struct {
Children []*Movie `gorm:"foreignKey:ParentID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"-"` Children []*Movie `gorm:"foreignKey:ParentID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE" json:"-"`
} }
func (m *Movie) Clone() *Movie {
return &Movie{
ID: m.ID,
CreatedAt: m.CreatedAt,
UpdatedAt: m.UpdatedAt,
Position: m.Position,
RoomID: m.RoomID,
CreatorID: m.CreatorID,
MovieBase: *m.MovieBase.Clone(),
Children: m.Children,
}
}
func (m *Movie) BeforeCreate(tx *gorm.DB) error { func (m *Movie) BeforeCreate(tx *gorm.DB) error {
if m.ID == "" { if m.ID == "" {
m.ID = utils.SortUUID() m.ID = utils.SortUUID()
@ -45,19 +58,61 @@ func (m *Movie) BeforeSave(tx *gorm.DB) (err error) {
return return
} }
type MoreSource struct {
Name string `json:"name"`
Type string `json:"type"`
Url string `json:"url"`
}
type MovieBase struct { type MovieBase struct {
Url string `gorm:"type:varchar(8192)" json:"url"` Url string `gorm:"type:varchar(8192)" json:"url"`
MoreSource map[string]string `gorm:"serializer:fastjson;type:text" json:"moreSource,omitempty"` MoreSources []*MoreSource `gorm:"serializer:fastjson;type:text" json:"moreSources,omitempty"`
Name string `gorm:"not null;type:varchar(256)" json:"name"` Name string `gorm:"not null;type:varchar(256)" json:"name"`
Live bool `json:"live"` Live bool `json:"live"`
Proxy bool `json:"proxy"` Proxy bool `json:"proxy"`
RtmpSource bool `json:"rtmpSource"` RtmpSource bool `json:"rtmpSource"`
Type string `json:"type"` Type string `json:"type"`
Headers map[string]string `gorm:"serializer:fastjson;type:text" json:"headers,omitempty"` Headers map[string]string `gorm:"serializer:fastjson;type:text" json:"headers,omitempty"`
Subtitles map[string]*Subtitle `gorm:"serializer:fastjson;type:text" json:"subtitles,omitempty"` Subtitles map[string]*Subtitle `gorm:"serializer:fastjson;type:text" json:"subtitles,omitempty"`
VendorInfo VendorInfo `gorm:"embedded;embeddedPrefix:vendor_info_" json:"vendorInfo,omitempty"` VendorInfo VendorInfo `gorm:"embedded;embeddedPrefix:vendor_info_" json:"vendorInfo,omitempty"`
IsFolder bool `json:"isFolder"` IsFolder bool `json:"isFolder"`
ParentID EmptyNullString `gorm:"type:char(32)" json:"parentId"` ParentID EmptyNullString `gorm:"type:char(32)" json:"parentId"`
}
func (m *MovieBase) Clone() *MovieBase {
mss := make([]*MoreSource, len(m.MoreSources))
for i, ms := range m.MoreSources {
mss[i] = &MoreSource{
Name: ms.Name,
Type: ms.Type,
Url: ms.Url,
}
}
hds := make(map[string]string, len(m.Headers))
for k, v := range m.Headers {
hds[k] = v
}
sbs := make(map[string]*Subtitle, len(m.Subtitles))
for k, v := range m.Subtitles {
sbs[k] = &Subtitle{
URL: v.URL,
Type: v.Type,
}
}
return &MovieBase{
Url: m.Url,
MoreSources: mss,
Name: m.Name,
Live: m.Live,
Proxy: m.Proxy,
RtmpSource: m.RtmpSource,
Type: m.Type,
Headers: hds,
Subtitles: sbs,
VendorInfo: m.VendorInfo,
IsFolder: m.IsFolder,
ParentID: m.ParentID,
}
} }
func (m *MovieBase) IsDynamicFolder() bool { func (m *MovieBase) IsDynamicFolder() bool {

@ -5,16 +5,17 @@ import (
"errors" "errors"
"fmt" "fmt"
"hash/crc32" "hash/crc32"
"net/http"
"net/url" "net/url"
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/go-resty/resty/v2"
"github.com/synctv-org/synctv/internal/cache" "github.com/synctv-org/synctv/internal/cache"
"github.com/synctv-org/synctv/internal/conf" "github.com/synctv-org/synctv/internal/conf"
"github.com/synctv-org/synctv/internal/model" "github.com/synctv-org/synctv/internal/model"
"github.com/synctv-org/synctv/internal/settings" "github.com/synctv-org/synctv/internal/settings"
"github.com/synctv-org/synctv/utils" "github.com/synctv-org/synctv/utils"
"github.com/zijiren233/go-uhc"
"github.com/zijiren233/livelib/av" "github.com/zijiren233/livelib/av"
"github.com/zijiren233/livelib/container/flv" "github.com/zijiren233/livelib/container/flv"
"github.com/zijiren233/livelib/protocol/hls" "github.com/zijiren233/livelib/protocol/hls"
@ -174,7 +175,6 @@ func (m *Movie) initChannel() error {
} }
cli := core.NewConnClient() cli := core.NewConnClient()
if err = cli.Start(m.Movie.MovieBase.Url, av.PLAY); err != nil { if err = cli.Start(m.Movie.MovieBase.Url, av.PLAY); err != nil {
cli.Close()
time.Sleep(time.Second) time.Sleep(time.Second)
continue continue
} }
@ -195,20 +195,26 @@ func (m *Movie) initChannel() error {
if c.Closed() { if c.Closed() {
return return
} }
r := resty.New().R() req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, m.Movie.MovieBase.Url, nil)
if err != nil {
time.Sleep(time.Second)
continue
}
for k, v := range m.Movie.MovieBase.Headers { for k, v := range m.Movie.MovieBase.Headers {
r.SetHeader(k, v) req.Header.Set(k, v)
}
if req.Header.Get("User-Agent") == "" {
req.Header.Set("User-Agent", utils.UA)
} }
// r.SetHeader("User-Agent", UserAgent) resp, err := uhc.Do(req)
resp, err := r.Get(m.Movie.MovieBase.Url)
if err != nil { if err != nil {
time.Sleep(time.Second) time.Sleep(time.Second)
continue continue
} }
if err := c.PushStart(flv.NewReader(resp.RawBody())); err != nil { if err := c.PushStart(flv.NewReader(resp.Body)); err != nil {
time.Sleep(time.Second) time.Sleep(time.Second)
} }
resp.RawBody().Close() resp.Body.Close()
} }
}() }()
default: default:

@ -104,22 +104,21 @@ func genMovieInfo(
return nil, errors.New("movie is static folder, can't get movie info") return nil, errors.New("movie is static folder, can't get movie info")
} }
} }
var movie = *opMovie.Movie var movie = opMovie.Movie.Clone()
if movie.MovieBase.VendorInfo.Vendor != "" { if movie.MovieBase.VendorInfo.Vendor != "" {
vendorMovie, err := genVendorMovie(ctx, user, opMovie, userAgent, userToken) vendorMovie, err := genVendorMovie(ctx, user, opMovie, userAgent, userToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }
movie = *vendorMovie movie = vendorMovie
} else if movie.MovieBase.RtmpSource || movie.MovieBase.Live && movie.MovieBase.Proxy { } else if movie.MovieBase.RtmpSource || movie.MovieBase.Live && movie.MovieBase.Proxy {
switch movie.MovieBase.Type { movie.MovieBase.Url = fmt.Sprintf("/api/movie/live/hls/list/%s.m3u8?token=%s", movie.ID, userToken)
case "m3u8": movie.MovieBase.Type = "m3u8"
movie.MovieBase.Url = fmt.Sprintf("/api/movie/live/hls/list/%s.m3u8?token=%s", movie.ID, userToken) movie.MoreSources = append(movie.MoreSources, &dbModel.MoreSource{
case "flv": Name: "flv",
movie.MovieBase.Url = fmt.Sprintf("/api/movie/live/flv/%s.flv?token=%s", movie.ID, userToken) Url: fmt.Sprintf("/api/movie/live/flv/%s.flv?token=%s", movie.ID, userToken),
default: Type: "flv",
return nil, errors.New("not support live movie type") })
}
movie.MovieBase.Headers = nil movie.MovieBase.Headers = nil
} else if movie.MovieBase.Proxy { } else if movie.MovieBase.Proxy {
movie.MovieBase.Url = fmt.Sprintf("/api/movie/proxy/%s/%s?token=%s", movie.RoomID, movie.ID, userToken) movie.MovieBase.Url = fmt.Sprintf("/api/movie/proxy/%s/%s?token=%s", movie.RoomID, movie.ID, userToken)
@ -128,6 +127,11 @@ func genMovieInfo(
if movie.MovieBase.Type == "" && movie.MovieBase.Url != "" { if movie.MovieBase.Type == "" && movie.MovieBase.Url != "" {
movie.MovieBase.Type = utils.GetUrlExtension(movie.MovieBase.Url) movie.MovieBase.Type = utils.GetUrlExtension(movie.MovieBase.Url)
} }
for _, v := range movie.MoreSources {
if v.Type == "" {
v.Type = utils.GetUrlExtension(v.Url)
}
}
resp := &model.Movie{ resp := &model.Movie{
Id: movie.ID, Id: movie.ID,
CreatedAt: movie.CreatedAt.UnixMilli(), CreatedAt: movie.CreatedAt.UnixMilli(),
@ -1385,8 +1389,12 @@ func genVendorMovie(ctx context.Context, user *op.User, opMovie *op.Movie, userA
} else { } else {
movie.MovieBase.Url = fmt.Sprintf("/api/movie/proxy/%s/%s?token=%s", movie.RoomID, movie.ID, userToken) movie.MovieBase.Url = fmt.Sprintf("/api/movie/proxy/%s/%s?token=%s", movie.RoomID, movie.ID, userToken)
movie.MovieBase.Type = "mpd" movie.MovieBase.Type = "mpd"
movie.MovieBase.MoreSource = map[string]string{ movie.MovieBase.MoreSources = []*dbModel.MoreSource{
"hevc": fmt.Sprintf("/api/movie/proxy/%s/%s?token=%s&t=hevc", movie.RoomID, movie.ID, userToken), {
Name: "hevc",
Type: "mpd",
Url: fmt.Sprintf("/api/movie/proxy/%s/%s?token=%s&t=hevc", movie.RoomID, movie.ID, userToken),
},
} }
} }
srt, err := bmc.Subtitle.Get(ctx, user.BilibiliCache()) srt, err := bmc.Subtitle.Get(ctx, user.BilibiliCache())
@ -1505,10 +1513,12 @@ func genVendorMovie(ctx context.Context, user *op.User, opMovie *op.Movie, userA
} }
} }
for _, s := range data.Sources[1:] { for _, s := range data.Sources[1:] {
if movie.MovieBase.MoreSource == nil { movie.MovieBase.MoreSources = append(movie.MovieBase.MoreSources,
movie.MovieBase.MoreSource = make(map[string]string, len(data.Sources)-1) &dbModel.MoreSource{
} Name: s.Name,
movie.MovieBase.MoreSource[s.Name] = s.URL Url: s.URL,
},
)
for _, subt := range s.Subtitles { for _, subt := range s.Subtitles {
if movie.MovieBase.Subtitles == nil { if movie.MovieBase.Subtitles == nil {

Loading…
Cancel
Save