Initial commit

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 13:57:10 +08:00
co-authored by Claude Opus 5
commit 8679200f41
1897 changed files with 257900 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
package video_media_service
import (
"91porn-server/common/httputil"
"91porn-server/common/log"
"91porn-server/common/stderr"
"91porn-server/models/v/vidmod"
"fmt"
"net/http"
"strings"
)
// UploadSkdVideoMedia 上传视频
func UploadSkdVideoMedia(up vidmod.UploadMediaVideo) error {
var (
params = (&UploadMediaVideoRequest{
FsResourceId: up.FsResourceId,
HashId: up.HashId,
Title: HandleTitle(up.Title),
CoverImage: up.CoverImage,
M3u8Src: up.M3u8Src,
FileSize: up.FileSize,
Length: up.Length,
Width: up.Width,
Height: up.Height,
TagsText: up.TagsText,
}).GenerateSkdParams()
out CommonResponse
)
code, err := httputil.DefaultClientPostJsonWithResp(&out, params.GetSkdURL(), nil, params)
if err != nil || code != http.StatusOK {
log.Error(fmt.Sprintf("Requst skd upload video media Http.Post fail error:%v;code:%v", err, code))
return err
}
c := out.Code
m := out.Msg
if c != 0 || m != "success" {
log.Error(fmt.Sprintf("Requst skd upload video media Http.Post code error:%v;response:%v;msg:%v;params%v", err, code, out.Msg, params))
return stderr.Failure
}
return nil
}
// UploadSkdShortVideoMedia 上传短视频
func UploadSkdShortVideoMedia(up vidmod.UploadMediaVideo) error {
var (
params = (&UploadMediaVideoRequest{
FsResourceId: up.FsResourceId,
HashId: up.HashId,
Title: HandleTitle(up.Title),
CoverImage: up.CoverImage,
M3u8Src: up.M3u8Src,
FileSize: up.FileSize,
Length: up.Length,
Width: up.Width,
Height: up.Height,
TagsText: up.TagsText,
}).GenerateSkdParams()
out CommonResponse
)
code, err := httputil.DefaultClientPostJsonWithResp(&out, params.GetSkdShortURL(), nil, params)
if err != nil || code != http.StatusOK {
log.Error(fmt.Sprintf("Requst skd upload short video media Http.Post fail error:%v;code:%v", err, code))
return err
}
c := out.Code
m := out.Msg
if c != 0 || m != "success" {
log.Error(fmt.Sprintf("Requst skd upload short video media Http.Post code error:%v;response:%v;msg:%v;params%v", err, code, out.Msg, params))
return stderr.Failure
}
return nil
}
func HandleTitle(title string) (t string) {
// 去除首位空格
title = strings.TrimSpace(title)
// 去除换行
title = strings.Replace(title, "\n", "", -1)
return title
}
+189
View File
@@ -0,0 +1,189 @@
package video_media_service
import (
"91porn-server/common/log"
"91porn-server/common/rchgutil"
"91porn-server/skd/skdg"
"bytes"
"crypto/md5"
"encoding/hex"
"fmt"
"reflect"
"sort"
"strconv"
"strings"
"time"
)
const (
UploadShortVideoMediaRouter = "/services/short_video/create" // 上传短视频API
UploadVideoMediaRouter = "/services/video/create" // 上传长视频API
)
type CommonResponse struct {
Code int64 `json:"code"`
Data ResponseData `json:"data"`
Msg string `json:"msg"`
}
type ResponseData struct {
Data []VideoMediaInfo `json:"data"`
Pagination ResponsePagination `json:"pagination"`
}
type ResponsePagination struct {
IsLastPage bool `json:"is_last_page"` // 视频是否是最一页
Page int64 `json:"page" binding:"required" ` // 当前页
Size int64 `json:"size" binding:"required" ` // 条数
Count int64 `json:"count" binding:"required" ` // 视频总条数
}
// VideoMediaInfo 媒资库数据响应模型
type VideoMediaInfo struct {
Id int64 `json:"id" bson:"id"` // 视频ID
HashId string `json:"hash_id" bson:"hash_id"` // 视频唯一ID
VLoggerUserId int64 `json:"vlogger_user_id" bson:"vlogger_user_id"` // 视频资源博主ID
Title string `json:"title" bson:"title"` // 视频标题
Content string `json:"content" bson:"content"` // 帖子详情
CoverImage string `json:"cover_image" bson:"cover_image"` // 视频资源封面图片
CoverGif string `json:"cover_gif" bson:"cover_gif"` // 视频资源封面GIF
Pics string `json:"pics" bson:"pics"` // 视频封面
Gifs string `json:"gifs" bson:"gifs"` // 视频GIF
Src480 string `json:"src_480" bson:"src_480"` // 视频480m3u8文件
Src720 string `json:"src_720" bson:"src_720"` // 视频720m3u8文件
Src1080 string `json:"src_1080" bson:"src_1080"` // 视频1080m3u8文件
FileSize480 int64 `json:"file_size_480" bson:"file_size_480"` // 视频480文件大小
FileSize720 int64 `json:"file_size_720" bson:"file_size_720"` // 视频720文件大小
FileSize1080 int64 `json:"file_size1080" bson:"file_size_1080"` // 视频1080文件大小
Width int64 `json:"width" bson:"width"` // 视频宽度
Height int64 `json:"height" bson:"height"` // 视频高度
Length int64 `json:"length" bson:"length"` // 视频长度
SaleCoin int64 `json:"sale_coin" bson:"sale_coin"` // 视频金币售价
Used int64 `json:"used" bson:"used"` // 视频是否使用
TagsText string `json:"tags_text" bson:"tags_text"` // 视频标题文本
}
// UploadMediaVideoRequest 上传到媒资库的基础信息请求体
type UploadMediaVideoRequest struct {
ProId string `json:"pro_id"` // 产品ID
Timestamp string `json:"timestamp"` // unix时间戳10位
FsResourceId string `json:"fs_resource_id"` // 文件资源id
HashId string `json:"hash_id"` // 视频唯一id
Title string `json:"title"` // 视频标题
CoverImage string `json:"cover_image"` // 封面图
M3u8Src string `json:"m3u8_src"` // m3u8地址
FileSize int `json:"file_size"` // 视频大小
Length int `json:"length"` // 视频时长 秒
Width int `json:"width"` // 宽度
Height int `json:"height"` // 高度
TagsText string `json:"tags_text"` // 视频标签,多个以逗号分割
Sign string `json:"sign" binding:"sign"` // 签名
}
// UploadMediaVideo 上传到媒资库的基础信息请求体
type UploadMediaVideo struct {
ProId string `json:"pro_id" sign:"1"` // 产品ID
Timestamp string `json:"timestamp" sign:"1"` // unix时间戳10位
FsResourceId string `json:"fs_resource_id" sign:"1"` // 文件资源id
HashId string `json:"hash_id" sign:"1"` // 视频唯一id
Title string `json:"title" sign:"1"` // 视频标题
CoverImage string `json:"cover_image" sign:"1"` // 封面图
M3u8Src string `json:"m3u8_src" sign:"1"` // m3u8地址
FileSize int `json:"file_size" sign:"1"` // 视频大小
Length int `json:"length" sign:"1"` // 视频时长 秒
Width int `json:"width" sign:"1"` // 宽度
Height int `json:"height" sign:"1"` // 高度
TagsText string `json:"tags_text" sign:"1"` // 视频标签,多个以逗号分割
Sign string `json:"sign" binding:"sign"` // 签名
}
// GetSKDProID 获取商户编号
func (*UploadMediaVideoRequest) GetSKDProID() string {
return skdg.Conf.MediaResourcesCfg.ProId
}
// ToSkdSign 签名
func (umv *UploadMediaVideoRequest) ToSkdSign(um UploadMediaVideo) (sign string) {
ss := um.ToStringSlice()
sort.Sort(&ss)
var buf bytes.Buffer
for k, v := range ss {
if k == 0 {
buf.WriteString(v)
} else {
buf.WriteString("&")
buf.WriteString(v)
}
}
buf.WriteString("&secret=")
buf.WriteString(umv.GetSKDAppSecret())
log.Info(fmt.Sprintf("Upload videoMedia md5 skdsign string:%s", buf.String()))
return strings.ToUpper(md5Sign(buf.String()))
}
// md5签名
func md5Sign(buf string) string {
md5Ctx := md5.New()
md5Ctx.Write([]byte(buf))
cipherStr := md5Ctx.Sum(nil)
newSign := hex.EncodeToString(cipherStr)
return newSign
}
// ToStringSlice 转化为string切片切片
func (umv *UploadMediaVideo) ToStringSlice() rchgutil.StringList {
data := make([]string, 0)
t := reflect.TypeOf(*umv)
v := reflect.ValueOf(*umv)
for k := 0; k < v.NumField(); k++ {
jsonTag, _ := t.Field(k).Tag.Lookup("json")
signTag, _ := t.Field(k).Tag.Lookup("sign")
fv := v.Field(k)
if v.Field(k).String() != "" && signTag == "1" {
switch fv.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
data = append(data, jsonTag+"="+strconv.FormatInt(v.Field(k).Int(), 10))
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
data = append(data, jsonTag+"="+strconv.FormatUint(v.Field(k).Uint(), 10))
case reflect.String:
data = append(data, jsonTag+"="+v.Field(k).String())
}
}
}
return data
}
// GetSKDAppSecret 获取app签名密钥
func (*UploadMediaVideoRequest) GetSKDAppSecret() string {
return skdg.Conf.MediaResourcesCfg.AppSecret
}
func (umv *UploadMediaVideoRequest) GenerateSkdParams() UploadMediaVideo {
var upVideoMedia UploadMediaVideo
now := time.Now().Unix()
upVideoMedia.ProId = umv.GetSKDProID()
upVideoMedia.FsResourceId = umv.FsResourceId
upVideoMedia.HashId = umv.HashId
upVideoMedia.Title = umv.Title
upVideoMedia.CoverImage = umv.CoverImage
upVideoMedia.M3u8Src = umv.M3u8Src
upVideoMedia.FileSize = umv.FileSize
upVideoMedia.Length = umv.Length
upVideoMedia.Width = umv.Width
upVideoMedia.Height = umv.Height
upVideoMedia.TagsText = umv.TagsText
upVideoMedia.Timestamp = strconv.FormatInt(now, 10)
upVideoMedia.Sign = umv.ToSkdSign(upVideoMedia)
return upVideoMedia
}
// GetSkdShortURL 获取短视频上传请求URL
func (umv *UploadMediaVideo) GetSkdShortURL() string {
return skdg.Conf.MediaResourcesCfg.UploadMediaUrl + UploadShortVideoMediaRouter
}
// GetSkdURL 获取视频上传请求URL
func (umv *UploadMediaVideo) GetSkdURL() string {
return skdg.Conf.MediaResourcesCfg.UploadMediaUrl + UploadVideoMediaRouter
}