@@ -0,0 +1,66 @@
|
||||
package mediaCenter
|
||||
|
||||
import (
|
||||
"github.com/fatih/structs"
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MediaCenterService 媒资库相关服务调用
|
||||
type MediaCenterService struct {
|
||||
url string
|
||||
proId string
|
||||
secret string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Url string
|
||||
ProId string
|
||||
Secret string
|
||||
}
|
||||
|
||||
func NewMediaCenterService(c Config) *MediaCenterService {
|
||||
return &MediaCenterService{
|
||||
url: c.Url,
|
||||
proId: c.ProId,
|
||||
secret: c.Secret,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MediaCenterService) getParams(p interface{}) (params map[string]interface{}) {
|
||||
req := structs.New(p)
|
||||
fields := req.Fields()
|
||||
params = make(map[string]interface{})
|
||||
for _, field := range fields {
|
||||
jsonTag := field.Tag("json")
|
||||
tagList := strings.Split(jsonTag, ",")
|
||||
key := field.Name()
|
||||
omitempty := ""
|
||||
if len(tagList) > 0 {
|
||||
key = tagList[0]
|
||||
}
|
||||
if len(tagList) > 1 {
|
||||
omitempty = tagList[1]
|
||||
}
|
||||
kind := reflect.TypeOf(field.Value()).Kind()
|
||||
// 如果是0值忽略或者空指针,不需要传
|
||||
if field.IsZero() && (kind == reflect.Ptr || omitempty == "omitempty") {
|
||||
continue
|
||||
}
|
||||
if kind == reflect.Ptr {
|
||||
// 通过指针取值
|
||||
params[key] = reflect.ValueOf(field.Value()).Elem().Interface()
|
||||
} else {
|
||||
params[key] = field.Value()
|
||||
}
|
||||
|
||||
}
|
||||
params["pro_id"] = m.proId
|
||||
params["sign"] = m.sign()
|
||||
return
|
||||
}
|
||||
|
||||
// TODO 暂时不需要加密
|
||||
func (m *MediaCenterService) sign() string {
|
||||
return ""
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package mediaCenter
|
||||
|
||||
import (
|
||||
"91porn-server/common"
|
||||
"91porn-server/common/httputil"
|
||||
"91porn-server/common/log"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
func (m *MediaCenterService) MediaList(p *MediaListReq) (result MediaListResp, err error) {
|
||||
var retMsg msg
|
||||
params := m.getParams(p)
|
||||
path := "/services/media/list"
|
||||
log.Info("meadia resource mediaList", log.Any("params", params), log.Any("req", p))
|
||||
code, err := httputil.DefaultClientGetWithResp(&retMsg, common.BindUrl(m.url, path), nil, params)
|
||||
if err != nil {
|
||||
log.Error("media MediaList fail", log.Any("code", code), log.E(err))
|
||||
err = errors.New("media MediaList fail")
|
||||
return
|
||||
}
|
||||
if code != 200 {
|
||||
log.Error("media MediaList fail", log.Any("code", code))
|
||||
err = errors.New("media MediaList fail")
|
||||
return
|
||||
}
|
||||
if retMsg.Code != 0 {
|
||||
log.Error("media MediaList fail", log.Any("retMsg", retMsg))
|
||||
err = errors.New("media MediaList fail")
|
||||
return
|
||||
}
|
||||
b, err := json.Marshal(retMsg.Data)
|
||||
if err != nil {
|
||||
log.Error("media MediaList fail", log.E(err))
|
||||
err = errors.New("media MediaList fail")
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(b, &result); err != nil {
|
||||
log.Error("media MediaList fail", log.E(err))
|
||||
err = errors.New("media MediaList fail")
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m *MediaCenterService) MediaContentList(p *MediaContentListReq) (result MediaContentListResp, err error) {
|
||||
var retMsg msg
|
||||
params := m.getParams(p)
|
||||
path := "/services/media/content/list"
|
||||
code, err := httputil.DefaultClientGetWithResp(&retMsg, common.BindUrl(m.url, path), nil, params)
|
||||
if err != nil {
|
||||
log.Error("media MediaContentList fail", log.E(err))
|
||||
err = errors.New("media MediaContentList fail")
|
||||
return
|
||||
}
|
||||
if code != 200 {
|
||||
log.Error("media MediaContentList fail", log.Any("code", code))
|
||||
err = errors.New("media MediaContentList fail")
|
||||
return
|
||||
}
|
||||
if retMsg.Code != 0 {
|
||||
log.Error("media MediaContentList fail", log.Any("retMsg", retMsg))
|
||||
err = errors.New("media MediaContentList fail")
|
||||
return
|
||||
}
|
||||
b, err := json.Marshal(retMsg.Data)
|
||||
if err != nil {
|
||||
log.Error("media MediaContentList fail", log.E(err))
|
||||
err = errors.New("media MediaContentList fail")
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(b, &result); err != nil {
|
||||
log.Error("media MediaContentList fail", log.E(err))
|
||||
err = errors.New("media MediaContentList fail")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (m *MediaCenterService) MediaUse(p *MediaUseReq) (err error) {
|
||||
var retMsg msg
|
||||
params := m.getParams(p)
|
||||
path := "/services/media/used"
|
||||
code, err := httputil.DefaultClientPostJsonWithResp(&retMsg, common.BindUrl(m.url, path), nil, params)
|
||||
if err != nil {
|
||||
log.Error("media MediaUse fail", log.E(err))
|
||||
err = errors.New("media MediaUse fail")
|
||||
return
|
||||
}
|
||||
if code != 200 {
|
||||
log.Error("media MediaUse fail", log.Any("code", code), log.E(err))
|
||||
err = errors.New("media MediaUse fail")
|
||||
return
|
||||
}
|
||||
if retMsg.Code != 0 {
|
||||
log.Error("media MediaUse fail", log.Any("retMsg", retMsg), log.E(err))
|
||||
err = errors.New(retMsg.Msg)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m *MediaCenterService) MediaIgnore(p *MediaIgnoreReq) (err error) {
|
||||
var retMsg msg
|
||||
params := m.getParams(p)
|
||||
path := "/services/media/ignored"
|
||||
code, err := httputil.DefaultClientPostJsonWithResp(&retMsg, common.BindUrl(m.url, path), nil, params)
|
||||
if err != nil {
|
||||
log.Error("media MediaIgnore fail", log.E(err))
|
||||
err = errors.New("media MediaIgnore fail")
|
||||
return
|
||||
}
|
||||
if code != 200 {
|
||||
log.Error("media MediaIgnore fail", log.Any("code", code), log.E(err))
|
||||
err = errors.New("media MediaIgnore fail")
|
||||
return
|
||||
}
|
||||
if retMsg.Code != 0 {
|
||||
log.Error("media MediaIgnore fail", log.Any("retMsg", retMsg), log.E(err))
|
||||
err = errors.New(retMsg.Msg)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (m *MediaCenterService) MediaSync(p *MediaSyncReq) (result MediaSyncResp, err error) {
|
||||
var retMsg msg
|
||||
params := m.getParams(p)
|
||||
path := "/services/media/sync"
|
||||
log.Info("MediaCenterService MediaSync", log.Any("params", params))
|
||||
code, err := httputil.DefaultClientGetWithResp(&retMsg, common.BindUrl(m.url, path), nil, params)
|
||||
if err != nil {
|
||||
log.Error("media MediaSync fail", log.Any("params", params), log.E(err))
|
||||
err = errors.New("media MediaSync fail")
|
||||
return
|
||||
}
|
||||
if code != 200 {
|
||||
log.Error("media MediaSync fail", log.Any("params", params), log.Any("code", code))
|
||||
err = errors.New("media MediaSync fail")
|
||||
return
|
||||
}
|
||||
if retMsg.Code == 7003 {
|
||||
result.IsDelete = true // 已经删除
|
||||
return
|
||||
}
|
||||
if retMsg.Code != 0 {
|
||||
log.Error("media MediaSync fail", log.Any("params", params), log.Any("retMsg", retMsg))
|
||||
err = errors.New("media MediaSync fail")
|
||||
return
|
||||
}
|
||||
b, err := json.Marshal(retMsg.Data)
|
||||
if err != nil {
|
||||
log.Error("media MediaSync json.Marshal fail", log.Any("params", params), log.E(err))
|
||||
err = errors.New("media MediaSync json.Marshal fail")
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(b, &result); err != nil {
|
||||
log.Error("media MediaSync json.Unmarshal fail", log.Any("params", params), log.Any("data", string(b)), log.E(err))
|
||||
err = errors.New("media MediaSync json.Unmarshal fail")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package mediaCenter
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type msg struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
type Media struct {
|
||||
ID uint `json:"id" `
|
||||
VloggerId uint `json:"vlogger_id" `
|
||||
Title string `json:"title"` // 标题
|
||||
SaleCoin uint `json:"sale_coin" ` // 整部售价
|
||||
HorizontalCover string `json:"horizontal_cover" ` // 横版封面
|
||||
VerticalCover string `json:"vertical_cover" ` // 竖版封面
|
||||
Summary string `json:"summary"` // 简介
|
||||
TotalEpisode uint `json:"total_episode" ` // 总集数
|
||||
UpdateStatus int `json:"update_status" ` // 更新状态
|
||||
MediaType int `json:"media_type" ` // 媒体类型 1-动画 2-漫画 3-文本小说 4-有声小说 5-短剧
|
||||
Anchor string `json:"anchor"` // 作者
|
||||
TagsText string `json:"tags_text" ` // 标签文字
|
||||
DataVersion int8 `json:"data_version"` // 数据版本
|
||||
TerminalCdo string `json:"terminal_cdo"` // 上传者
|
||||
CreateTime int64 `json:"create_time"`
|
||||
UpdateTime int64 `json:"update_time"`
|
||||
}
|
||||
|
||||
type Pagination struct {
|
||||
IsLastPage bool `json:"is_last_page"`
|
||||
Page uint `json:"page"`
|
||||
Size uint `json:"size"`
|
||||
Count uint `json:"count"`
|
||||
}
|
||||
|
||||
type MediaListReq struct {
|
||||
MediaType int `json:"media_type" form:"media_type"` // 1-动画 2-漫画 3-小说
|
||||
Id *uint `json:"id" form:"id"`
|
||||
VloggerId *uint `json:"vlogger_id,omitempty" form:"vlogger_id"` // up主id
|
||||
IsUp *int `json:"is_up,omitempty" form:"is_up"` // 是否是up主 0-不是 1-是 不传则是所有
|
||||
Title *string `json:"title,omitempty" form:"title"` // 标题
|
||||
Tag *string `json:"tag,omitempty" form:"tag"` // 标签
|
||||
TerminalCdo *string `json:"terminal_cdo,omitempty" form:"terminal_cdo"` // 上传者
|
||||
SyncType int `json:"sync_type" form:"sync_type"` // 同步类型 1-全量同步 2-增量同步
|
||||
Page uint `json:"page" form:"page"`
|
||||
Size uint `json:"size" form:"size"`
|
||||
}
|
||||
|
||||
type MediaListResp struct {
|
||||
Data []*Media `json:"data"`
|
||||
Pagination Pagination `json:"pagination"`
|
||||
}
|
||||
|
||||
// MediaContent acg资源内容表
|
||||
type MediaContent struct {
|
||||
ID uint `json:"id" `
|
||||
SaleCoin uint `json:"sale_coin"`
|
||||
VloggerId uint `json:"vlogger_id"`
|
||||
Cover string `json:"cover"` // 封面
|
||||
MediaId uint `json:"video_id"` // 媒体资源ID
|
||||
MediaType int `json:"media_type"` // 媒体类型
|
||||
EpisodeNumber int `json:"episode_number"` // 第几集
|
||||
Title string `json:"title"` // 章节名
|
||||
Text string `json:"text"` // 内容(小说专用)
|
||||
Urls string `json:"urls"` // 地址集(多个资源地址用 例如漫画,逗号分隔)
|
||||
Height uint `json:"height"` // 高
|
||||
Width uint `json:"width"` // 宽
|
||||
Ratio float64 `json:"ratio"` // 宽高比
|
||||
MediaSize uint `json:"media_size"` // 资源大小
|
||||
PlayTime uint `json:"play_time"` // 影片长度
|
||||
M3u8Url string `json:"m3u8_url"` // 视频资源地址
|
||||
H265Url string `json:"h265_url"` // H.265 视频资源地址
|
||||
AudioUrl string `json:"audio_url"` // 有升小说资源地址
|
||||
FsResourceId string `json:"fs_resource_id"`
|
||||
FsResourceStatus string `json:"fs_resource_status"`
|
||||
HashId string `json:"hash_id"`
|
||||
DataVersion int8 `json:"data_version"` // 数据版本
|
||||
TerminalCdo string `json:"terminal_cdo"` // 上传者
|
||||
CreateTime int64 `json:"create_time"`
|
||||
UpdateTime int64 `json:"update_time"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON accepts both media-center field names used by existing
|
||||
// deployments. The app-facing and Mongo fields remain h265Url.
|
||||
func (m *MediaContent) UnmarshalJSON(data []byte) error {
|
||||
type mediaContentAlias MediaContent
|
||||
aux := struct {
|
||||
*mediaContentAlias
|
||||
HevcM3u8URL string `json:"hevc_m3u8_url"`
|
||||
}{
|
||||
mediaContentAlias: (*mediaContentAlias)(m),
|
||||
}
|
||||
if err := json.Unmarshal(data, &aux); err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.TrimSpace(m.H265Url) == "" {
|
||||
m.H265Url = strings.TrimSpace(aux.HevcM3u8URL)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type MediaContentListReq struct {
|
||||
MediaId int `json:"media_id" form:"media_id"`
|
||||
Page uint `json:"page" form:"page"`
|
||||
Size uint `json:"size" form:"size"`
|
||||
}
|
||||
|
||||
type MediaContentListResp struct {
|
||||
Data []*MediaContent `json:"data"`
|
||||
Pagination Pagination `json:"pagination"`
|
||||
}
|
||||
|
||||
type MediaUseReq struct {
|
||||
Ids []uint `json:"ids" form:"ids"`
|
||||
}
|
||||
|
||||
type MediaIgnoreReq struct {
|
||||
Ids []uint `json:"ids" form:"ids"`
|
||||
}
|
||||
|
||||
type MediaSyncReq struct {
|
||||
Id uint `json:"id" form:"id"`
|
||||
SyncTime int64 `json:"sync_time" form:"sync_time"` //从某一刻开始同步获取数据
|
||||
}
|
||||
|
||||
type MediaSyncResp struct {
|
||||
IsDelete bool `json:"-"`
|
||||
Media *Media `json:"media"`
|
||||
MediaContentList []MediaContent `json:"media_content_list"`
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package mediaCenter
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMediaContentUnmarshalH265URL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
data string
|
||||
wantH264 string
|
||||
wantH265 string
|
||||
}{
|
||||
{
|
||||
name: "h265_url",
|
||||
data: `{
|
||||
"m3u8_url":"https://cdn.example.com/h264/index.m3u8",
|
||||
"h265_url":"https://cdn.example.com/h265/index.m3u8"
|
||||
}`,
|
||||
wantH264: "https://cdn.example.com/h264/index.m3u8",
|
||||
wantH265: "https://cdn.example.com/h265/index.m3u8",
|
||||
},
|
||||
{
|
||||
name: "hevc_m3u8_url alias",
|
||||
data: `{
|
||||
"m3u8_url":"https://cdn.example.com/h264/index.m3u8",
|
||||
"hevc_m3u8_url":"https://cdn.example.com/hevc/index.m3u8"
|
||||
}`,
|
||||
wantH264: "https://cdn.example.com/h264/index.m3u8",
|
||||
wantH265: "https://cdn.example.com/hevc/index.m3u8",
|
||||
},
|
||||
{
|
||||
name: "h265_url takes precedence",
|
||||
data: `{
|
||||
"h265_url":"https://cdn.example.com/h265/index.m3u8",
|
||||
"hevc_m3u8_url":"https://cdn.example.com/hevc/index.m3u8"
|
||||
}`,
|
||||
wantH265: "https://cdn.example.com/h265/index.m3u8",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var content MediaContent
|
||||
if err := json.Unmarshal([]byte(tt.data), &content); err != nil {
|
||||
t.Fatalf("unmarshal media content: %v", err)
|
||||
}
|
||||
if content.M3u8Url != tt.wantH264 {
|
||||
t.Fatalf("unexpected H.264 URL: got %q want %q", content.M3u8Url, tt.wantH264)
|
||||
}
|
||||
if content.H265Url != tt.wantH265 {
|
||||
t.Fatalf("unexpected H.265 URL: got %q want %q", content.H265Url, tt.wantH265)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user