mirror of
https://github.com/OpenListTeam/OpenList.git
synced 2025-07-18 17:38:07 +08:00
feat(quark): add transcoding link api (#470)
This commit is contained in:
@ -48,35 +48,18 @@ func (d *QuarkOrUC) List(ctx context.Context, dir model.Obj, args model.ListArgs
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return utils.SliceConvert(files, func(src File) (model.Obj, error) {
|
||||
return fileToObj(src), nil
|
||||
})
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func (d *QuarkOrUC) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) {
|
||||
data := base.Json{
|
||||
"fids": []string{file.GetID()},
|
||||
}
|
||||
var resp DownResp
|
||||
ua := d.conf.ua
|
||||
_, err := d.request("/file/download", http.MethodPost, func(req *resty.Request) {
|
||||
req.SetHeader("User-Agent", ua).
|
||||
SetBody(data)
|
||||
}, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
f := file.(*File)
|
||||
|
||||
if d.UseTransCodingAddress && d.config.Name == "Quark" && f.Category == 1 && f.Size > 0 {
|
||||
return d.getTranscodingLink(file)
|
||||
}
|
||||
|
||||
return &model.Link{
|
||||
URL: resp.Data[0].DownloadUrl,
|
||||
Header: http.Header{
|
||||
"Cookie": []string{d.Cookie},
|
||||
"Referer": []string{d.conf.referer},
|
||||
"User-Agent": []string{ua},
|
||||
},
|
||||
Concurrency: 3,
|
||||
PartSize: 10 * utils.MB,
|
||||
}, nil
|
||||
return d.getDownloadLink(file)
|
||||
}
|
||||
|
||||
func (d *QuarkOrUC) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||
|
@ -8,8 +8,10 @@ import (
|
||||
type Addition struct {
|
||||
Cookie string `json:"cookie" required:"true"`
|
||||
driver.RootID
|
||||
OrderBy string `json:"order_by" type:"select" options:"none,file_type,file_name,updated_at" default:"none"`
|
||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
|
||||
OrderBy string `json:"order_by" type:"select" options:"none,file_type,file_name,updated_at" default:"none"`
|
||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" default:"asc"`
|
||||
UseTransCodingAddress bool `json:"use_transcoding_address" help:"You can watch the transcoded video and support 302 redirection" required:"true" default:"false"`
|
||||
OnlyListVideoFile bool `json:"only_list_video_file" default:"false"`
|
||||
}
|
||||
|
||||
type Conf struct {
|
||||
@ -24,7 +26,7 @@ func init() {
|
||||
return &QuarkOrUC{
|
||||
config: driver.Config{
|
||||
Name: "Quark",
|
||||
OnlyLocal: true,
|
||||
OnlyLocal: false,
|
||||
DefaultRoot: "0",
|
||||
NoOverwriteUpload: true,
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
package quark
|
||||
|
||||
import (
|
||||
"github.com/OpenListTeam/OpenList/pkg/utils"
|
||||
"time"
|
||||
|
||||
"github.com/OpenListTeam/OpenList/internal/model"
|
||||
@ -14,17 +15,19 @@ type Resp struct {
|
||||
//Timestamp int `json:"timestamp"`
|
||||
}
|
||||
|
||||
var _ model.Obj = (*File)(nil)
|
||||
|
||||
type File struct {
|
||||
Fid string `json:"fid"`
|
||||
FileName string `json:"file_name"`
|
||||
//PdirFid string `json:"pdir_fid"`
|
||||
//Category int `json:"category"`
|
||||
Category int `json:"category"`
|
||||
//FileType int `json:"file_type"`
|
||||
Size int64 `json:"size"`
|
||||
//FormatType string `json:"format_type"`
|
||||
//Status int `json:"status"`
|
||||
//Tags string `json:"tags,omitempty"`
|
||||
//LCreatedAt int64 `json:"l_created_at"`
|
||||
LCreatedAt int64 `json:"l_created_at"`
|
||||
LUpdatedAt int64 `json:"l_updated_at"`
|
||||
//NameSpace int `json:"name_space"`
|
||||
//IncludeItems int `json:"include_items,omitempty"`
|
||||
@ -32,8 +35,8 @@ type File struct {
|
||||
//BackupSign int `json:"backup_sign"`
|
||||
//Duration int `json:"duration"`
|
||||
//FileSource string `json:"file_source"`
|
||||
File bool `json:"file"`
|
||||
//CreatedAt int64 `json:"created_at"`
|
||||
File bool `json:"file"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
//PrivateExtra struct {} `json:"_private_extra"`
|
||||
//ObjCategory string `json:"obj_category,omitempty"`
|
||||
@ -46,10 +49,43 @@ func fileToObj(f File) *model.Object {
|
||||
Name: f.FileName,
|
||||
Size: f.Size,
|
||||
Modified: time.UnixMilli(f.UpdatedAt),
|
||||
Ctime: time.UnixMilli(f.CreatedAt),
|
||||
IsFolder: !f.File,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *File) GetSize() int64 {
|
||||
return f.Size
|
||||
}
|
||||
|
||||
func (f *File) GetName() string {
|
||||
return f.FileName
|
||||
}
|
||||
|
||||
func (f *File) ModTime() time.Time {
|
||||
return time.UnixMilli(f.UpdatedAt)
|
||||
}
|
||||
|
||||
func (f *File) CreateTime() time.Time {
|
||||
return time.UnixMilli(f.CreatedAt)
|
||||
}
|
||||
|
||||
func (f *File) IsDir() bool {
|
||||
return !f.File
|
||||
}
|
||||
|
||||
func (f *File) GetHash() utils.HashInfo {
|
||||
return utils.HashInfo{}
|
||||
}
|
||||
|
||||
func (f *File) GetID() string {
|
||||
return f.Fid
|
||||
}
|
||||
|
||||
func (f *File) GetPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type SortResp struct {
|
||||
Resp
|
||||
Data struct {
|
||||
@ -100,6 +136,82 @@ type DownResp struct {
|
||||
//} `json:"metadata"`
|
||||
}
|
||||
|
||||
type TranscodingResp struct {
|
||||
Resp
|
||||
Data struct {
|
||||
DefaultResolution string `json:"default_resolution"`
|
||||
OriginDefaultResolution string `json:"origin_default_resolution"`
|
||||
VideoList []struct {
|
||||
Resolution string `json:"resolution"`
|
||||
VideoInfo struct {
|
||||
Duration int `json:"duration"`
|
||||
Size int64 `json:"size"`
|
||||
Format string `json:"format"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
Bitrate float64 `json:"bitrate"`
|
||||
Codec string `json:"codec"`
|
||||
Fps float64 `json:"fps"`
|
||||
Rotate int `json:"rotate"`
|
||||
Audio struct {
|
||||
Duration int `json:"duration"`
|
||||
Bitrate float64 `json:"bitrate"`
|
||||
Codec string `json:"codec"`
|
||||
Channels int `json:"channels"`
|
||||
} `json:"audio"`
|
||||
UpdateTime int `json:"update_time"`
|
||||
URL string `json:"url"`
|
||||
Resolution string `json:"resolution"`
|
||||
HlsType string `json:"hls_type"`
|
||||
Finish bool `json:"finish"`
|
||||
Resoultion string `json:"resoultion"`
|
||||
Success bool `json:"success"`
|
||||
} `json:"video_info,omitempty"`
|
||||
//Right string `json:"right"`
|
||||
//MemberRight string `json:"member_right"`
|
||||
//TransStatus string `json:"trans_status"`
|
||||
//Accessable bool `json:"accessable"`
|
||||
//SupportsFormat string `json:"supports_format"`
|
||||
//VideoFuncType string `json:"video_func_type,omitempty"`
|
||||
} `json:"video_list"`
|
||||
//AudioList []interface{} `json:"audio_list"`
|
||||
FileName string `json:"file_name"`
|
||||
NameSpace int `json:"name_space"`
|
||||
Size int64 `json:"size"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
//LastPlayInfo struct {
|
||||
// Time int `json:"time"`
|
||||
//} `json:"last_play_info"`
|
||||
//SeekPreviewData struct {
|
||||
// TotalFrameCount int `json:"total_frame_count"`
|
||||
// TotalSpriteCount int `json:"total_sprite_count"`
|
||||
// FrameWidth int `json:"frame_width"`
|
||||
// FrameHeight int `json:"frame_height"`
|
||||
// SpriteRow int `json:"sprite_row"`
|
||||
// SpriteColumn int `json:"sprite_column"`
|
||||
// PreviewSpriteInfos []struct {
|
||||
// URL string `json:"url"`
|
||||
// FrameCount int `json:"frame_count"`
|
||||
// Times []int `json:"times"`
|
||||
// } `json:"preview_sprite_infos"`
|
||||
//} `json:"seek_preview_data"`
|
||||
//ObjKey string `json:"obj_key"`
|
||||
//Meta struct {
|
||||
// Duration int `json:"duration"`
|
||||
// Size int64 `json:"size"`
|
||||
// Format string `json:"format"`
|
||||
// Width int `json:"width"`
|
||||
// Height int `json:"height"`
|
||||
// Bitrate float64 `json:"bitrate"`
|
||||
// Codec string `json:"codec"`
|
||||
// Fps float64 `json:"fps"`
|
||||
// Rotate int `json:"rotate"`
|
||||
//} `json:"meta"`
|
||||
//PreloadLevel int `json:"preload_level"`
|
||||
//HasSeekPreviewData bool `json:"has_seek_preview_data"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
type UpPreResp struct {
|
||||
Resp
|
||||
Data struct {
|
||||
|
@ -50,14 +50,23 @@ func (d *QuarkOrUC) request(pathname string, method string, callback base.ReqCal
|
||||
d.Cookie = cookie.SetStr(d.Cookie, "__puus", __puus.Value)
|
||||
op.MustSaveDriverStorage(d)
|
||||
}
|
||||
|
||||
if d.UseTransCodingAddress && d.config.Name == "Quark" {
|
||||
__pus := cookie.GetCookie(res.Cookies(), "__pus")
|
||||
if __pus != nil {
|
||||
d.Cookie = cookie.SetStr(d.Cookie, "__pus", __pus.Value)
|
||||
op.MustSaveDriverStorage(d)
|
||||
}
|
||||
}
|
||||
|
||||
if e.Status >= 400 || e.Code != 0 {
|
||||
return nil, errors.New(e.Message)
|
||||
}
|
||||
return res.Body(), nil
|
||||
}
|
||||
|
||||
func (d *QuarkOrUC) GetFiles(parent string) ([]File, error) {
|
||||
files := make([]File, 0)
|
||||
func (d *QuarkOrUC) GetFiles(parent string) ([]model.Obj, error) {
|
||||
files := make([]model.Obj, 0)
|
||||
page := 1
|
||||
size := 100
|
||||
query := map[string]string{
|
||||
@ -77,15 +86,72 @@ func (d *QuarkOrUC) GetFiles(parent string) ([]File, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files = append(files, resp.Data.List...)
|
||||
for _, file := range resp.Data.List {
|
||||
if d.OnlyListVideoFile {
|
||||
// 开启后 只列出视频文件和文件夹
|
||||
if file.IsDir() || file.Category == 1 {
|
||||
files = append(files, &file)
|
||||
}
|
||||
} else {
|
||||
files = append(files, &file)
|
||||
}
|
||||
}
|
||||
|
||||
if page*size >= resp.Metadata.Total {
|
||||
break
|
||||
}
|
||||
page++
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func (d *QuarkOrUC) getDownloadLink(file model.Obj) (*model.Link, error) {
|
||||
data := base.Json{
|
||||
"fids": []string{file.GetID()},
|
||||
}
|
||||
var resp DownResp
|
||||
ua := d.conf.ua
|
||||
_, err := d.request("/file/download", http.MethodPost, func(req *resty.Request) {
|
||||
req.SetHeader("User-Agent", ua).
|
||||
SetBody(data)
|
||||
}, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &model.Link{
|
||||
URL: resp.Data[0].DownloadUrl,
|
||||
Header: http.Header{
|
||||
"Cookie": []string{d.Cookie},
|
||||
"Referer": []string{d.conf.referer},
|
||||
"User-Agent": []string{ua},
|
||||
},
|
||||
Concurrency: 3,
|
||||
PartSize: 10 * utils.MB,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *QuarkOrUC) getTranscodingLink(file model.Obj) (*model.Link, error) {
|
||||
data := base.Json{
|
||||
"fid": file.GetID(),
|
||||
"resolutions": "low,normal,high,super,2k,4k",
|
||||
"supports": "fmp4_av,m3u8,dolby_vision",
|
||||
}
|
||||
var resp TranscodingResp
|
||||
ua := d.conf.ua
|
||||
|
||||
_, err := d.request("/file/v2/play/project", http.MethodPost, func(req *resty.Request) {
|
||||
req.SetHeader("User-Agent", ua).
|
||||
SetBody(data)
|
||||
}, &resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &model.Link{URL: resp.Data.VideoList[0].VideoInfo.URL}, nil
|
||||
}
|
||||
|
||||
func (d *QuarkOrUC) upPre(file model.FileStreamer, parentId string) (UpPreResp, error) {
|
||||
now := time.Now()
|
||||
data := base.Json{
|
||||
|
Reference in New Issue
Block a user