|
|
|
|
@ -17,6 +17,7 @@ import (
|
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"github.com/sirupsen/logrus"
|
|
|
|
|
"github.com/synctv-org/synctv/internal/conf"
|
|
|
|
|
dbModel "github.com/synctv-org/synctv/internal/model"
|
|
|
|
|
"github.com/synctv-org/synctv/internal/op"
|
|
|
|
|
@ -42,23 +43,26 @@ func GetPageItems[T any](ctx *gin.Context, items []T) ([]T, error) {
|
|
|
|
|
func MovieList(ctx *gin.Context) {
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
user := ctx.MustGet("user").(*op.UserEntry).Value()
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
page, max, err := utils.GetPageAndMax(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("get page and max error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
currentResp, err := genCurrentResp(ctx, user, room)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("gen current resp error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m := room.GetMoviesWithPage(page, max)
|
|
|
|
|
mresp := make([]model.MoviesResp, len(m))
|
|
|
|
|
mresp := make([]model.MovieResp, len(m))
|
|
|
|
|
for i, v := range m {
|
|
|
|
|
mresp[i] = model.MoviesResp{
|
|
|
|
|
mresp[i] = model.MovieResp{
|
|
|
|
|
Id: v.Movie.ID,
|
|
|
|
|
Base: v.Movie.Base,
|
|
|
|
|
Creator: op.GetUserName(v.Movie.CreatorID),
|
|
|
|
|
@ -81,13 +85,9 @@ func genCurrentResp(ctx context.Context, user *op.User, room *op.Room) (*model.C
|
|
|
|
|
return genCurrentRespWithCurrent(ctx, user, room, room.Current())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func genCurrentRespWithCurrent(ctx context.Context, user *op.User, room *op.Room, current *op.Current) (*model.CurrentMovieResp, error) {
|
|
|
|
|
if current.Movie.ID == "" {
|
|
|
|
|
return &model.CurrentMovieResp{}, nil
|
|
|
|
|
}
|
|
|
|
|
opMovie, err := room.GetMovieByID(current.Movie.ID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("get current movie error: %w", err)
|
|
|
|
|
func genCurrentMovieInfo(ctx context.Context, user *op.User, room *op.Room, opMovie *op.Movie) (*model.MovieResp, error) {
|
|
|
|
|
if opMovie == nil || opMovie.ID == "" {
|
|
|
|
|
return &model.MovieResp{}, nil
|
|
|
|
|
}
|
|
|
|
|
var movie = opMovie.Movie
|
|
|
|
|
if movie.Base.VendorInfo.Vendor != "" {
|
|
|
|
|
@ -113,15 +113,33 @@ func genCurrentRespWithCurrent(ctx context.Context, user *op.User, room *op.Room
|
|
|
|
|
if movie.Base.Type == "" && movie.Base.Url != "" {
|
|
|
|
|
movie.Base.Type = utils.GetUrlExtension(movie.Base.Url)
|
|
|
|
|
}
|
|
|
|
|
resp := &model.MovieResp{
|
|
|
|
|
Id: movie.ID,
|
|
|
|
|
CreatedAt: movie.CreatedAt.UnixMilli(),
|
|
|
|
|
Base: movie.Base,
|
|
|
|
|
Creator: op.GetUserName(movie.CreatorID),
|
|
|
|
|
CreatorId: movie.CreatorID,
|
|
|
|
|
}
|
|
|
|
|
return resp, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func genCurrentRespWithCurrent(ctx context.Context, user *op.User, room *op.Room, current *op.Current) (*model.CurrentMovieResp, error) {
|
|
|
|
|
if current.Movie.ID == "" {
|
|
|
|
|
return &model.CurrentMovieResp{
|
|
|
|
|
Movie: &model.MovieResp{},
|
|
|
|
|
}, nil
|
|
|
|
|
}
|
|
|
|
|
opMovie, err := room.GetMovieByID(current.Movie.ID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("get current movie error: %w", err)
|
|
|
|
|
}
|
|
|
|
|
mr, err := genCurrentMovieInfo(ctx, user, room, opMovie)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, fmt.Errorf("gen current movie info error: %w", err)
|
|
|
|
|
}
|
|
|
|
|
resp := &model.CurrentMovieResp{
|
|
|
|
|
Status: current.UpdateStatus(),
|
|
|
|
|
Movie: model.MoviesResp{
|
|
|
|
|
Id: movie.ID,
|
|
|
|
|
CreatedAt: movie.CreatedAt.UnixMilli(),
|
|
|
|
|
Base: movie.Base,
|
|
|
|
|
Creator: op.GetUserName(movie.CreatorID),
|
|
|
|
|
CreatorId: movie.CreatorID,
|
|
|
|
|
},
|
|
|
|
|
Status: current.UpdateStatus(),
|
|
|
|
|
Movie: mr,
|
|
|
|
|
ExpireId: opMovie.ExpireId(),
|
|
|
|
|
}
|
|
|
|
|
return resp, nil
|
|
|
|
|
@ -130,9 +148,11 @@ func genCurrentRespWithCurrent(ctx context.Context, user *op.User, room *op.Room
|
|
|
|
|
func CurrentMovie(ctx *gin.Context) {
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
user := ctx.MustGet("user").(*op.UserEntry).Value()
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
currentResp, err := genCurrentResp(ctx, user, room)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("gen current resp error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -143,18 +163,20 @@ func CurrentMovie(ctx *gin.Context) {
|
|
|
|
|
func Movies(ctx *gin.Context) {
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
user := ctx.MustGet("user").(*op.UserEntry).Value()
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
page, max, err := utils.GetPageAndMax(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("get page and max error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m := room.GetMoviesWithPage(int(page), int(max))
|
|
|
|
|
|
|
|
|
|
mresp := make([]*model.MoviesResp, len(m))
|
|
|
|
|
mresp := make([]*model.MovieResp, len(m))
|
|
|
|
|
for i, v := range m {
|
|
|
|
|
mresp[i] = &model.MoviesResp{
|
|
|
|
|
mresp[i] = &model.MovieResp{
|
|
|
|
|
Id: v.Movie.ID,
|
|
|
|
|
Base: v.Movie.Base,
|
|
|
|
|
Creator: op.GetUserName(v.Movie.CreatorID),
|
|
|
|
|
@ -175,15 +197,18 @@ func Movies(ctx *gin.Context) {
|
|
|
|
|
func PushMovie(ctx *gin.Context) {
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
user := ctx.MustGet("user").(*op.UserEntry).Value()
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
req := model.PushMovieReq{}
|
|
|
|
|
if err := model.Decode(ctx, &req); err != nil {
|
|
|
|
|
log.Errorf("push movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := user.AddMovieToRoom(room, (*dbModel.BaseMovie)(&req))
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("push movie error: %v", err)
|
|
|
|
|
if errors.Is(err, dbModel.ErrNoPermission) {
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
@ -199,6 +224,7 @@ func PushMovie(ctx *gin.Context) {
|
|
|
|
|
Userid: user.ID,
|
|
|
|
|
},
|
|
|
|
|
}); err != nil {
|
|
|
|
|
log.Errorf("push movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -209,6 +235,7 @@ func PushMovie(ctx *gin.Context) {
|
|
|
|
|
func PushMovies(ctx *gin.Context) {
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
user := ctx.MustGet("user").(*op.UserEntry).Value()
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
req := model.PushMoviesReq{}
|
|
|
|
|
if err := model.Decode(ctx, &req); err != nil {
|
|
|
|
|
@ -225,6 +252,7 @@ func PushMovies(ctx *gin.Context) {
|
|
|
|
|
|
|
|
|
|
err := user.AddMoviesToRoom(room, ms)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("push movies error: %v", err)
|
|
|
|
|
if errors.Is(err, dbModel.ErrNoPermission) {
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
@ -240,6 +268,7 @@ func PushMovies(ctx *gin.Context) {
|
|
|
|
|
Userid: user.ID,
|
|
|
|
|
},
|
|
|
|
|
}); err != nil {
|
|
|
|
|
log.Errorf("push movies error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -248,7 +277,10 @@ func PushMovies(ctx *gin.Context) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewPublishKey(ctx *gin.Context) {
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
if !conf.Conf.Server.Rtmp.Enable {
|
|
|
|
|
log.Errorf("rtmp is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("rtmp is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -258,27 +290,32 @@ func NewPublishKey(ctx *gin.Context) {
|
|
|
|
|
|
|
|
|
|
req := model.IdReq{}
|
|
|
|
|
if err := model.Decode(ctx, &req); err != nil {
|
|
|
|
|
log.Errorf("new publish key error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
movie, err := room.GetMovieByID(req.Id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("new publish key error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if movie.Movie.CreatorID != user.ID && !user.HasRoomPermission(room, dbModel.PermissionEditUser) {
|
|
|
|
|
log.Errorf("new publish key error: %v", dbModel.ErrNoPermission)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorResp(dbModel.ErrNoPermission))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if !movie.Movie.Base.RtmpSource {
|
|
|
|
|
log.Errorf("new publish key error: %v", "only rtmp source movie can get publish key")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("only live movie can get publish key"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
token, err := rtmp.NewRtmpAuthorization(movie.Movie.ID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("new publish key error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -298,14 +335,17 @@ func NewPublishKey(ctx *gin.Context) {
|
|
|
|
|
func EditMovie(ctx *gin.Context) {
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
user := ctx.MustGet("user").(*op.UserEntry).Value()
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
req := model.EditMovieReq{}
|
|
|
|
|
if err := model.Decode(ctx, &req); err != nil {
|
|
|
|
|
log.Errorf("edit movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := user.UpdateMovie(room, req.Id, (*dbModel.BaseMovie)(&req.PushMovieReq)); err != nil {
|
|
|
|
|
log.Errorf("edit movie error: %v", err)
|
|
|
|
|
if errors.Is(err, dbModel.ErrNoPermission) {
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
@ -321,6 +361,7 @@ func EditMovie(ctx *gin.Context) {
|
|
|
|
|
Userid: user.ID,
|
|
|
|
|
},
|
|
|
|
|
}); err != nil {
|
|
|
|
|
log.Errorf("edit movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -331,15 +372,18 @@ func EditMovie(ctx *gin.Context) {
|
|
|
|
|
func DelMovie(ctx *gin.Context) {
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
user := ctx.MustGet("user").(*op.UserEntry).Value()
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
req := model.IdsReq{}
|
|
|
|
|
if err := model.Decode(ctx, &req); err != nil {
|
|
|
|
|
log.Errorf("del movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err := user.DeleteMoviesByID(room, req.Ids)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("del movie error: %v", err)
|
|
|
|
|
if errors.Is(err, dbModel.ErrNoPermission) {
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
@ -421,6 +465,7 @@ func SwapMovie(ctx *gin.Context) {
|
|
|
|
|
func ChangeCurrentMovie(ctx *gin.Context) {
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
user := ctx.MustGet("user").(*op.UserEntry).Value()
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
req := model.IdCanEmptyReq{}
|
|
|
|
|
err := model.Decode(ctx, &req)
|
|
|
|
|
@ -432,14 +477,29 @@ func ChangeCurrentMovie(ctx *gin.Context) {
|
|
|
|
|
if req.Id == "" {
|
|
|
|
|
err = user.SetCurrentMovie(room, nil, false)
|
|
|
|
|
} else {
|
|
|
|
|
err = user.SetCurrentMovieByID(room, req.Id, true)
|
|
|
|
|
var movie *op.Movie
|
|
|
|
|
movie, err = room.GetMovieByID(req.Id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("change current movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
_, err = genCurrentMovieInfo(ctx, user, room, movie)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("change current movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
err = user.SetCurrentMovie(room, &movie.Movie, true)
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("change current movie error: %v", err)
|
|
|
|
|
if errors.Is(err, dbModel.ErrNoPermission) {
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := room.Broadcast(&pb.ElementMessage{
|
|
|
|
|
@ -449,6 +509,7 @@ func ChangeCurrentMovie(ctx *gin.Context) {
|
|
|
|
|
Userid: user.ID,
|
|
|
|
|
},
|
|
|
|
|
}); err != nil {
|
|
|
|
|
log.Errorf("change current movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -457,24 +518,30 @@ func ChangeCurrentMovie(ctx *gin.Context) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ProxyMovie(ctx *gin.Context) {
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
if !settings.MovieProxy.Get() {
|
|
|
|
|
log.Errorf("movie proxy is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("movie proxy is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
roomId := ctx.Param("roomId")
|
|
|
|
|
if roomId == "" {
|
|
|
|
|
log.Errorf("room id is empty")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("roomId is empty"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
room, err := op.LoadOrInitRoomByID(roomId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("load or init room by id error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m, err := room.Value().GetMovieByID(ctx.Param("movieId"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("get movie by id error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -496,7 +563,7 @@ func ProxyMovie(ctx *gin.Context) {
|
|
|
|
|
default:
|
|
|
|
|
err = proxyURL(ctx, m.Movie.Base.Url, m.Movie.Base.Headers)
|
|
|
|
|
if err != nil {
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
log.Errorf("proxy movie error: %v", err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@ -588,23 +655,29 @@ func (e FormatErrNotSupportFileType) Error() string {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func JoinLive(ctx *gin.Context) {
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
ctx.Header("Cache-Control", "no-store")
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
movieId := strings.Trim(ctx.Param("movieId"), "/")
|
|
|
|
|
m, err := room.GetMovieByID(movieId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if m.Movie.Base.RtmpSource && !conf.Conf.Server.Rtmp.Enable {
|
|
|
|
|
log.Errorf("join live error: %v", "rtmp is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("rtmp is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
} else if m.Movie.Base.Live && !settings.LiveProxy.Get() {
|
|
|
|
|
log.Errorf("join live error: %v", "live proxy is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("live proxy is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
channel, err := m.Channel()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -619,6 +692,7 @@ func JoinLive(ctx *gin.Context) {
|
|
|
|
|
defer w.Close()
|
|
|
|
|
err = channel.AddPlayer(w)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -632,34 +706,42 @@ func JoinLive(ctx *gin.Context) {
|
|
|
|
|
return fmt.Sprintf("/api/movie/live/hls/data/%s/%s/%s.%s", room.ID, movieId, tsName, ext)
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
ctx.Data(http.StatusOK, hls.M3U8ContentType, b)
|
|
|
|
|
default:
|
|
|
|
|
log.Errorf("join live error: %v", FormatErrNotSupportFileType(joinType))
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp(fmt.Sprintf("not support join type: %s", joinType)))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func JoinFlvLive(ctx *gin.Context) {
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
ctx.Header("Cache-Control", "no-store")
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
movieId := strings.TrimSuffix(strings.Trim(ctx.Param("movieId"), "/"), ".flv")
|
|
|
|
|
m, err := room.GetMovieByID(movieId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join flv live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if m.Movie.Base.RtmpSource && !conf.Conf.Server.Rtmp.Enable {
|
|
|
|
|
log.Errorf("join flv live error: %v", "rtmp is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("rtmp is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
} else if m.Movie.Base.Live && !settings.LiveProxy.Get() {
|
|
|
|
|
log.Errorf("join flv live error: %v", "live proxy is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("live proxy is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
channel, err := m.Channel()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join flv live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -668,6 +750,7 @@ func JoinFlvLive(ctx *gin.Context) {
|
|
|
|
|
defer w.Close()
|
|
|
|
|
err = channel.AddPlayer(w)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join flv live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -675,23 +758,29 @@ func JoinFlvLive(ctx *gin.Context) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func JoinHlsLive(ctx *gin.Context) {
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
ctx.Header("Cache-Control", "no-store")
|
|
|
|
|
room := ctx.MustGet("room").(*op.RoomEntry).Value()
|
|
|
|
|
movieId := strings.TrimSuffix(strings.Trim(ctx.Param("movieId"), "/"), ".m3u8")
|
|
|
|
|
m, err := room.GetMovieByID(movieId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join hls live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if m.Movie.Base.RtmpSource && !conf.Conf.Server.Rtmp.Enable {
|
|
|
|
|
log.Errorf("join hls live error: %v", "rtmp is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("rtmp is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
} else if m.Movie.Base.Live && !settings.LiveProxy.Get() {
|
|
|
|
|
log.Errorf("join hls live error: %v", "live proxy is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("live proxy is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
channel, err := m.Channel()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join hls live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -704,6 +793,7 @@ func JoinHlsLive(ctx *gin.Context) {
|
|
|
|
|
return fmt.Sprintf("/api/movie/live/hls/data/%s/%s/%s.%s", room.ID, movieId, tsName, ext)
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("join hls live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -711,10 +801,13 @@ func JoinHlsLive(ctx *gin.Context) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ServeHlsLive(ctx *gin.Context) {
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
ctx.Header("Cache-Control", "no-store")
|
|
|
|
|
roomId := ctx.Param("roomId")
|
|
|
|
|
roomE, err := op.LoadOrInitRoomByID(roomId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("serve hls live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -722,18 +815,22 @@ func ServeHlsLive(ctx *gin.Context) {
|
|
|
|
|
movieId := ctx.Param("movieId")
|
|
|
|
|
m, err := room.GetMovieByID(movieId)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("serve hls live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if m.Movie.Base.RtmpSource && !conf.Conf.Server.Rtmp.Enable {
|
|
|
|
|
log.Errorf("serve hls live error: %v", "rtmp is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("rtmp is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
} else if m.Movie.Base.Live && !settings.LiveProxy.Get() {
|
|
|
|
|
log.Errorf("serve hls live error: %v", "live proxy is not enabled")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusForbidden, model.NewApiErrorStringResp("live proxy is not enabled"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
channel, err := m.Channel()
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("serve hls live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -742,11 +839,13 @@ func ServeHlsLive(ctx *gin.Context) {
|
|
|
|
|
switch fileExt := filepath.Ext(dataId); fileExt {
|
|
|
|
|
case ".ts":
|
|
|
|
|
if settings.TsDisguisedAsPng.Get() {
|
|
|
|
|
log.Errorf("serve hls live error: %v", FormatErrNotSupportFileType(fileExt))
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(FormatErrNotSupportFileType(fileExt)))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
b, err := channel.GetTsFile(strings.TrimSuffix(dataId, fileExt))
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("serve hls live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -754,11 +853,13 @@ func ServeHlsLive(ctx *gin.Context) {
|
|
|
|
|
ctx.Data(http.StatusOK, hls.TSContentType, b)
|
|
|
|
|
case ".png":
|
|
|
|
|
if !settings.TsDisguisedAsPng.Get() {
|
|
|
|
|
log.Errorf("serve hls live error: %v", FormatErrNotSupportFileType(fileExt))
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(FormatErrNotSupportFileType(fileExt)))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
b, err := channel.GetTsFile(strings.TrimSuffix(dataId, fileExt))
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("serve hls live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -768,33 +869,40 @@ func ServeHlsLive(ctx *gin.Context) {
|
|
|
|
|
cache := bytes.NewBuffer(make([]byte, 0, 71))
|
|
|
|
|
err = png.Encode(cache, img)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("serve hls live error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
ctx.Data(http.StatusOK, "image/png", append(cache.Bytes(), b...))
|
|
|
|
|
default:
|
|
|
|
|
ctx.Header("Cache-Control", "no-store")
|
|
|
|
|
log.Errorf("serve hls live error: %v", FormatErrNotSupportFileType(fileExt))
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(FormatErrNotSupportFileType(fileExt)))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func proxyVendorMovie(ctx *gin.Context, movie *op.Movie) {
|
|
|
|
|
log := ctx.MustGet("log").(*logrus.Entry)
|
|
|
|
|
|
|
|
|
|
switch movie.Movie.Base.VendorInfo.Vendor {
|
|
|
|
|
case dbModel.VendorBilibili:
|
|
|
|
|
t := ctx.Query("t")
|
|
|
|
|
switch t {
|
|
|
|
|
case "", "hevc":
|
|
|
|
|
if !movie.Movie.Base.Proxy {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "not support movie proxy")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support movie proxy"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
u, err := op.LoadOrInitUserByID(movie.Movie.CreatorID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
mpdC, err := movie.BilibiliCache().SharedMpd.Get(ctx, u.Value().BilibiliCache())
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -808,10 +916,12 @@ func proxyVendorMovie(ctx *gin.Context, movie *op.Movie) {
|
|
|
|
|
} else {
|
|
|
|
|
streamId, err := strconv.Atoi(id)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if streamId >= len(mpdC.Urls) {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "stream id out of range")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("stream id out of range"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -825,34 +935,42 @@ func proxyVendorMovie(ctx *gin.Context, movie *op.Movie) {
|
|
|
|
|
headers["Referer"] = "https://www.bilibili.com"
|
|
|
|
|
headers["User-Agent"] = utils.UA
|
|
|
|
|
}
|
|
|
|
|
proxyURL(ctx, mpdC.Urls[streamId], headers)
|
|
|
|
|
err = proxyURL(ctx, mpdC.Urls[streamId], headers)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
case "subtitle":
|
|
|
|
|
id := ctx.Query("n")
|
|
|
|
|
if id == "" {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "n is empty")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("n is empty"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
u, err := op.LoadOrInitUserByID(movie.Movie.CreatorID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
srtI, err := movie.BilibiliCache().Subtitle.Get(ctx, u.Value().BilibiliCache())
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if s, ok := srtI[id]; ok {
|
|
|
|
|
srtData, err := s.Srt.Get(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
ctx.Data(http.StatusOK, "text/plain; charset=utf-8", srtData)
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "subtitle not found")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusNotFound, model.NewApiErrorStringResp("subtitle not found"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -861,11 +979,13 @@ func proxyVendorMovie(ctx *gin.Context, movie *op.Movie) {
|
|
|
|
|
case dbModel.VendorAlist:
|
|
|
|
|
u, err := op.LoadOrInitUserByID(movie.Movie.CreatorID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
alistC, err := movie.AlistCache().Get(ctx, u.Value().AlistCache())
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -878,30 +998,38 @@ func proxyVendorMovie(ctx *gin.Context, movie *op.Movie) {
|
|
|
|
|
case "subtitle":
|
|
|
|
|
idS := ctx.Query("id")
|
|
|
|
|
if idS == "" {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "id is empty")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("id is empty"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
id, err := strconv.Atoi(idS)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if id >= len(alistC.Ali.Subtitles) {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "id out of range")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("id out of range"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := alistC.Ali.Subtitles[id].Cache.Get(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
ctx.Data(http.StatusOK, "text/plain; charset=utf-8", data)
|
|
|
|
|
}
|
|
|
|
|
} else if !movie.Movie.Base.Proxy {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "not support movie proxy")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support movie proxy"))
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
proxyURL(ctx, alistC.URL, nil)
|
|
|
|
|
err = proxyURL(ctx, alistC.URL, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
@ -911,71 +1039,88 @@ func proxyVendorMovie(ctx *gin.Context, movie *op.Movie) {
|
|
|
|
|
switch t {
|
|
|
|
|
case "":
|
|
|
|
|
if !movie.Movie.Base.Proxy {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "not support movie proxy")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("not support movie proxy"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
u, err := op.LoadOrInitUserByID(movie.Movie.CreatorID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
embyC, err := movie.EmbyCache().Get(ctx, u.Value().EmbyCache())
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
source, err := strconv.Atoi(ctx.Query("source"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if source >= len(embyC.Sources) {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "source out of range")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("source out of range"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
id, err := strconv.Atoi(ctx.Query("id"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if id >= len(embyC.Sources[source].URLs) {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "id out of range")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("id out of range"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
proxyURL(ctx, embyC.Sources[source].URLs[id].URL, nil)
|
|
|
|
|
err = proxyURL(ctx, embyC.Sources[source].URLs[id].URL, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
case "subtitle":
|
|
|
|
|
u, err := op.LoadOrInitUserByID(movie.Movie.CreatorID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
embyC, err := movie.EmbyCache().Get(ctx, u.Value().EmbyCache())
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
source, err := strconv.Atoi(ctx.Query("source"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if source >= len(embyC.Sources) {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "source out of range")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("source out of range"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
id, err := strconv.Atoi(ctx.Query("id"))
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if id >= len(embyC.Sources[source].Subtitles) {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "id out of range")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("id out of range"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
data, err := embyC.Sources[source].Subtitles[id].Cache.Get(ctx)
|
|
|
|
|
if err != nil {
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", err)
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
@ -984,6 +1129,7 @@ func proxyVendorMovie(ctx *gin.Context, movie *op.Movie) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
log.Errorf("proxy vendor movie error: %v", "vendor not support proxy")
|
|
|
|
|
ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorStringResp("vendor not support proxy"))
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|