Feat: more source add type filed

This commit is contained in:
zijiren233 2024-05-16 14:05:59 +08:00
parent 0cf9ce5b07
commit 5b560cd3b7
3 changed files with 109 additions and 38 deletions

View File

@ -21,6 +21,19 @@ type Movie struct {
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 {
if m.ID == "" {
m.ID = utils.SortUUID()
@ -45,19 +58,61 @@ func (m *Movie) BeforeSave(tx *gorm.DB) (err error) {
return
}
type MoreSource struct {
Name string `json:"name"`
Type string `json:"type"`
Url string `json:"url"`
}
type MovieBase struct {
Url string `gorm:"type:varchar(8192)" json:"url"`
MoreSource map[string]string `gorm:"serializer:fastjson;type:text" json:"moreSource,omitempty"`
Name string `gorm:"not null;type:varchar(256)" json:"name"`
Live bool `json:"live"`
Proxy bool `json:"proxy"`
RtmpSource bool `json:"rtmpSource"`
Type string `json:"type"`
Headers map[string]string `gorm:"serializer:fastjson;type:text" json:"headers,omitempty"`
Subtitles map[string]*Subtitle `gorm:"serializer:fastjson;type:text" json:"subtitles,omitempty"`
VendorInfo VendorInfo `gorm:"embedded;embeddedPrefix:vendor_info_" json:"vendorInfo,omitempty"`
IsFolder bool `json:"isFolder"`
ParentID EmptyNullString `gorm:"type:char(32)" json:"parentId"`
Url string `gorm:"type:varchar(8192)" json:"url"`
MoreSources []*MoreSource `gorm:"serializer:fastjson;type:text" json:"moreSources,omitempty"`
Name string `gorm:"not null;type:varchar(256)" json:"name"`
Live bool `json:"live"`
Proxy bool `json:"proxy"`
RtmpSource bool `json:"rtmpSource"`
Type string `json:"type"`
Headers map[string]string `gorm:"serializer:fastjson;type:text" json:"headers,omitempty"`
Subtitles map[string]*Subtitle `gorm:"serializer:fastjson;type:text" json:"subtitles,omitempty"`
VendorInfo VendorInfo `gorm:"embedded;embeddedPrefix:vendor_info_" json:"vendorInfo,omitempty"`
IsFolder bool `json:"isFolder"`
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 {

View File

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

View File

@ -104,22 +104,21 @@ func genMovieInfo(
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 != "" {
vendorMovie, err := genVendorMovie(ctx, user, opMovie, userAgent, userToken)
if err != nil {
return nil, err
}
movie = *vendorMovie
movie = vendorMovie
} else if movie.MovieBase.RtmpSource || movie.MovieBase.Live && movie.MovieBase.Proxy {
switch movie.MovieBase.Type {
case "m3u8":
movie.MovieBase.Url = fmt.Sprintf("/api/movie/live/hls/list/%s.m3u8?token=%s", movie.ID, userToken)
case "flv":
movie.MovieBase.Url = fmt.Sprintf("/api/movie/live/flv/%s.flv?token=%s", movie.ID, userToken)
default:
return nil, errors.New("not support live movie type")
}
movie.MovieBase.Url = fmt.Sprintf("/api/movie/live/hls/list/%s.m3u8?token=%s", movie.ID, userToken)
movie.MovieBase.Type = "m3u8"
movie.MoreSources = append(movie.MoreSources, &dbModel.MoreSource{
Name: "flv",
Url: fmt.Sprintf("/api/movie/live/flv/%s.flv?token=%s", movie.ID, userToken),
Type: "flv",
})
movie.MovieBase.Headers = nil
} else if movie.MovieBase.Proxy {
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 != "" {
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{
Id: movie.ID,
CreatedAt: movie.CreatedAt.UnixMilli(),
@ -1385,8 +1389,12 @@ func genVendorMovie(ctx context.Context, user *op.User, opMovie *op.Movie, userA
} else {
movie.MovieBase.Url = fmt.Sprintf("/api/movie/proxy/%s/%s?token=%s", movie.RoomID, movie.ID, userToken)
movie.MovieBase.Type = "mpd"
movie.MovieBase.MoreSource = map[string]string{
"hevc": fmt.Sprintf("/api/movie/proxy/%s/%s?token=%s&t=hevc", movie.RoomID, movie.ID, userToken),
movie.MovieBase.MoreSources = []*dbModel.MoreSource{
{
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())
@ -1505,10 +1513,12 @@ func genVendorMovie(ctx context.Context, user *op.User, opMovie *op.Movie, userA
}
}
for _, s := range data.Sources[1:] {
if movie.MovieBase.MoreSource == nil {
movie.MovieBase.MoreSource = make(map[string]string, len(data.Sources)-1)
}
movie.MovieBase.MoreSource[s.Name] = s.URL
movie.MovieBase.MoreSources = append(movie.MovieBase.MoreSources,
&dbModel.MoreSource{
Name: s.Name,
Url: s.URL,
},
)
for _, subt := range s.Subtitles {
if movie.MovieBase.Subtitles == nil {