init: 初始化 web_hgdjb_server 项目

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-11-07 10:47:32 +08:00
co-authored by Claude Opus 4.7
commit f13d33af4d
707 changed files with 147705 additions and 0 deletions
+131
View File
@@ -0,0 +1,131 @@
package proxy
import (
"bytes"
"encoding/json"
"fmt"
"io"
"mime"
"mime/multipart"
"net/http"
"net/textproto"
"path/filepath"
"strconv"
"strings"
"time"
"videoweb/pub/common/log"
"videoweb/pub/pubdef"
)
const mediaAutopublishImagePath = "/media/web/autopublish/image"
type mediaImageUploadResp struct {
Code int `json:"code"`
Data struct {
Id string `json:"id"`
SourceNameFs string `json:"sourceNameFs"`
} `json:"data"`
Msg string `json:"msg"`
}
// UploadAutopublishImage 按 App /api/app/upload/image 同样方式上传到 media
// POST {media}/media/web/autopublish/image,表单字段 file + appId,不加盖水印。
func UploadAutopublishImage(fileName string, data []byte) (string, error) {
if len(data) == 0 {
return "", fmt.Errorf("图片内容为空")
}
fileName = sanitizeAutopublishFileName(fileName)
var buf bytes.Buffer
mw := multipart.NewWriter(&buf)
if err := mw.WriteField("appId", strconv.Itoa(pubdef.AppId)); err != nil {
return "", err
}
if err := writeAutopublishImageFile(mw, fileName, data); err != nil {
return "", err
}
if err := mw.Close(); err != nil {
return "", err
}
base := strings.TrimRight(DomainAddressRepair("", BucketVideoAddressV2), "/")
if base == "" || (!strings.HasPrefix(base, "http://") && !strings.HasPrefix(base, "https://")) {
return "", fmt.Errorf("media地址未配置")
}
url := base + mediaAutopublishImagePath
req, err := http.NewRequest(http.MethodPost, url, &buf)
if err != nil {
return "", err
}
req.Header.Set("Content-Type", mw.FormDataContentType())
cli := &http.Client{Timeout: 60 * time.Second}
resp, err := cli.Do(req)
if err != nil {
log.Error("上传media图片失败", log.Any("url", url), log.E(err))
return "", err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("media上传图片失败,状态码 %d,响应 %s", resp.StatusCode, trimRespBody(body))
}
var result mediaImageUploadResp
if err = json.Unmarshal(body, &result); err != nil {
return "", fmt.Errorf("解析media上传图片响应失败: %w,响应 %s", err, trimRespBody(body))
}
if result.Code != Success {
msg := strings.TrimSpace(result.Msg)
if msg == "" {
msg = "unknown"
}
return "", fmt.Errorf("media上传图片失败: %s,响应 %s", msg, trimRespBody(body))
}
pathStr := strings.TrimSpace(result.Data.SourceNameFs)
if pathStr == "" {
return "", fmt.Errorf("media上传图片返回空路径")
}
return pathStr, nil
}
func writeAutopublishImageFile(mw *multipart.Writer, fileName string, data []byte) error {
h := make(textproto.MIMEHeader)
contentType := mime.TypeByExtension(strings.ToLower(filepath.Ext(fileName)))
if contentType == "" {
contentType = "image/jpeg"
}
h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="file"; filename="%s"`, fileName))
h.Set("Content-Type", contentType)
part, err := mw.CreatePart(h)
if err != nil {
return err
}
_, err = part.Write(data)
return err
}
func sanitizeAutopublishFileName(fileName string) string {
fileName = filepath.Base(strings.TrimSpace(fileName))
fileName = strings.ReplaceAll(fileName, `"`, "")
if fileName == "" || fileName == "." || !strings.Contains(fileName, ".") {
return "playlet_cover.jpg"
}
for _, r := range fileName {
if r > 127 || r < 32 || r == '/' || r == '\\' {
return "playlet_cover.jpg"
}
}
return fileName
}
func trimRespBody(body []byte) string {
s := strings.TrimSpace(string(body))
if len(s) > 300 {
return s[:300]
}
return s
}
+509
View File
@@ -0,0 +1,509 @@
package proxy
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"strings"
"videoweb/pub/common/http"
"videoweb/pub/common/log"
)
const (
apiDomain = "http://resourcets.bbaazz.me/file/upload"
)
var (
header = map[string]string{"Content-Type": "application/json"}
)
const (
Success = 200
)
func UploadImg(fileName string, data []byte, domain string) (pathStr string, err error) {
r := objreq{
Name: fileName,
Data: base64.StdEncoding.EncodeToString(data),
}
jsonbytes, err := json.Marshal(r)
if err != nil {
return
}
url := ImageUploadAddressRepair(domain, BucketImageAddressV2)
resp, err := http.Post(url, header, bytes.NewReader(jsonbytes))
if err != nil {
return
}
var or objresp
if err = json.Unmarshal(resp.Data, &or); err != nil {
return
}
if or.Code != Success {
err = fmt.Errorf("上传失败:%s", or.Msg)
return
}
pathStr = or.Object.Name
return
}
func UploadBase64Img(fileName string, data string, domain string) (pathStr string, err error) {
r := objreq{
Name: fileName,
Data: data,
}
jsonbytes, err := json.Marshal(r)
if err != nil {
return
}
if len(domain) == 0 {
domain = apiDomain
}
url := domain
if !strings.Contains(domain, "/file/upload") {
url = domain + "/file/upload"
}
resp, err := http.Post(url, header, bytes.NewReader(jsonbytes))
if err != nil {
return
}
var or objresp
if err = json.Unmarshal(resp.Data, &or); err != nil {
return
}
if or.Code != Success {
err = fmt.Errorf("上传失败:%s", or.Msg)
return
}
pathStr = or.Object.Name
if strings.Contains(domain, "resourceimg.bbaazz.me") &&
!strings.HasPrefix(pathStr, "v2/") {
pathStr = "v2/" + pathStr
}
return
}
func fileServer() (url string) {
return "http://resourcets.bbaazz.me"
}
func PostOk(baseInfo *ShardOk, domain string) (result *VideoOkResult, err error) {
result = &VideoOkResult{}
paramJson, err := json.Marshal(baseInfo)
if err != nil {
return
}
url := VideoOkAddressRepair(domain, BucketVideoAddressV2)
fmt.Println(baseInfo)
fr, err := http.Post(url, header, bytes.NewReader(paramJson))
if err != nil {
return
}
fmt.Println(string(fr.Data))
if err = json.Unmarshal(fr.Data, result); err != nil {
fmt.Println(result)
return nil, err
}
fmt.Println(result)
return
}
func PostOkV2(baseInfo *ShardOk, domain string) (result *VideoOkResult, err error) {
result = &VideoOkResult{}
paramJson, err := json.Marshal(baseInfo)
if err != nil {
return
}
url := VideoOkAddressRepair(domain, BucketVideoAddressV2)
fmt.Println(paramJson)
fr, err := http.Post(url, header, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
fmt.Println(result)
return nil, err
}
fmt.Println(result)
return
}
func QueryMedia(baseInfo *MediaQueryeReq, domain string) (result *VideoQueryResult, err error) {
result = &VideoQueryResult{}
paramJson, err := json.Marshal(baseInfo)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/file/web/media/query") {
url = domain + "/file/web/media/query"
}
fr, err := http.Post(url, header, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
fmt.Println(err)
return nil, err
}
return
}
func QueryMedias(baseInfo *MediaQueryesReq, domain string) (result *VideoQuerysResult, err error) {
result = &VideoQuerysResult{
Data: make([]MediaResp, 0),
}
paramJson, err := json.Marshal(baseInfo)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/media/web/task/querys") {
url = domain + "/media/web/task/querys"
}
fr, err := http.Post(url, header, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
fmt.Println(err)
return nil, err
}
return
}
func UploadVideo(domain string, body *ShardBody) (result *Result, err error) {
if body == nil {
return nil, errors.New("no video to upload")
}
url := VideoBodyAddressRepair(domain, BucketVideoAddressV2)
fmt.Println(url)
buf, err := json.Marshal(body)
if err != nil {
return nil, err
}
resp, err := http.Post(url, header, bytes.NewBuffer(buf))
if err != nil {
return nil, err
}
fmt.Println("resp-->", string(resp.Data))
result = new(Result)
if err = json.Unmarshal(resp.Data, result); err != nil {
return nil, err
}
return
}
func UploadVideoV2(domain string, body *ShardBodyV2) (result *Result, err error) {
if body == nil {
return nil, errors.New("no video to upload")
}
url := VideoBodyAddressRepair(domain, BucketVideoAddressV2)
fmt.Println(url)
buf, err := json.Marshal(body)
if err != nil {
return nil, err
}
resp, err := http.Post(url, header, bytes.NewBuffer(buf))
if err != nil {
return nil, err
}
fmt.Println("resp-->", string(resp.Data))
result = new(Result)
if err = json.Unmarshal(resp.Data, result); err != nil {
return nil, err
}
return
}
func PostSearch(param *MediaSearchReq, domain string) (result *MediaSearchResult, err error) {
result = &MediaSearchResult{}
paramJson, err := json.Marshal(param)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/file/web/media/search") {
url = domain + "/file/web/media/search"
}
fr, err := http.Post(url, header, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
return nil, err
}
//log.Info("proxy:test", log.Any("url", url), log.Any("result", result))
return
}
func PostUpdate(param *MediaUpdateReq, domain string) (result *MediaUpdateResult, err error) {
result = &MediaUpdateResult{}
paramJson, err := json.Marshal(param)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/file/web/media/update") {
url = domain + "/file/web/media/update"
}
fr, perr := http.Post(url, header, bytes.NewReader(paramJson))
if perr != nil {
log.Error("PostUpdate Unmarshal", log.E(perr))
err = perr
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
log.Error("PostUpdate Unmarshal", log.E(err), log.Any("data", string(fr.Data)))
return nil, err
}
return
}
func PostDelete(param *MediaDelReq, domain string) (result *MediaDelResult, err error) {
result = &MediaDelResult{}
paramJson, err := json.Marshal(param)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/file/web/media/delete") {
url = domain + "/file/web/media/delete"
}
fr, err := http.Post(url, header, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
return nil, err
}
return
}
func PostUpdatePreTime(param *MediaUpdatePreTime, domain string) (result *MediaDelResult, err error) {
result = &MediaDelResult{}
paramJson, err := json.Marshal(param)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/file/web/media/update/prefile") {
url = domain + "/file/web/media/update/prefile"
}
fr, err := http.Post(url, header, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
return nil, err
}
return
}
func UploadVideoV2New(domain string, body *ShardBodyV2) (result *Result, err error) {
if body == nil {
return nil, errors.New("no video to upload")
}
if len(domain) == 0 {
domain = fileServer()
}
url := domain
if !strings.Contains(domain, "/file/web/proxy/videoBodyV2") {
url = domain + "/file/web/proxy/videoBodyV2"
}
fmt.Println(url)
buf, err := json.Marshal(body)
if err != nil {
return nil, err
}
resp, err := http.Post(url, header, bytes.NewBuffer(buf))
if err != nil {
return nil, err
}
fmt.Println("resp-->", string(resp.Data))
result = new(Result)
if err = json.Unmarshal(resp.Data, result); err != nil {
return nil, err
}
// if strings.Contains(domain, "resourcets.bbaazz.me") && !strings.HasPrefix(result.Data.VideoUri, "v2/") {
// result.Data.VideoUri = "v2/" + result.Data.VideoUri
// }
fmt.Println("result-->", result)
if result.Code != 200 {
err = fmt.Errorf("result code err")
}
return
}
func SyncMedia(baseInfo *MediaTaskSyncReq, domain string) (result *VideoQuerysResult, err error) {
result = &VideoQuerysResult{}
paramJson, err := json.Marshal(baseInfo)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/media/web/task/sync") {
url = domain + "/media/web/task/sync"
}
fr, err := http.Post(url, header, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
fmt.Println(err)
return nil, err
}
return
}
// SyncMediaFile 将相对路径 m3u8 登记到 media 切片服(status=MediaFileSyncing)
func SyncMediaFile(req *MediaFileSyncReq, domain string) (result *MediaAPIResult, err error) {
result = &MediaAPIResult{}
paramJson, err := json.Marshal(req)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/media/web/mediafile/sync") {
url = domain + "/media/web/mediafile/sync"
}
fr, err := http.Post(url, header, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
return nil, err
}
return
}
// AddMediaTask 提交 media 加水印切片任务
func AddMediaTask(req *MediaTaskAddReq, domain string) (result *MediaAPIResult, err error) {
result = &MediaAPIResult{}
paramJson, err := json.Marshal(req)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/media/web/task/add") {
url = domain + "/media/web/task/add"
}
reqHeader := map[string]string{
"Content-Type": "application/json",
"acc-id": "1",
"acc-name": "playlet-watermark",
"app-id": fmt.Sprintf("%d", req.AppId),
}
fr, err := http.Post(url, reqHeader, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
return nil, err
}
return
}
// UpdateMediaWatermark 按已有 media 任务重新加水印切片
func UpdateMediaWatermark(req *MediaTaskUpdateWatermarkReq, domain string) (result *MediaAPIResult, err error) {
result = &MediaAPIResult{}
paramJson, err := json.Marshal(req)
if err != nil {
return
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/media/web/task/update/watermark") {
url = domain + "/media/web/task/update/watermark"
}
reqHeader := map[string]string{
"Content-Type": "application/json",
"acc-id": "1",
"acc-name": "playlet-watermark",
"app-id": fmt.Sprintf("%d", req.AppId),
}
fr, err := http.Post(url, reqHeader, bytes.NewReader(paramJson))
if err != nil {
return
}
if err = json.Unmarshal(fr.Data, result); err != nil {
return nil, err
}
return
}
// QueryMediaSource 按原片 ID 查询 media source 状态
func QueryMediaSource(sourceID string, appId int64, domain string) (*MediaSourceListItem, error) {
req := MediaSourceListReq{
Id: sourceID,
AppId: appId,
WebAppId: appId,
PageNum: 1,
PageSize: 1,
}
paramJSON, err := json.Marshal(req)
if err != nil {
return nil, err
}
if len(domain) == 0 {
domain = DomainAddressRepair(domain, BucketVideoAddressV2)
}
url := domain
if !strings.Contains(domain, "/media/web/source/list") {
url = domain + "/media/web/source/list"
}
reqHeader := map[string]string{
"Content-Type": "application/json",
"acc-id": "1",
"acc-name": "playlet-watermark",
"app-id": fmt.Sprintf("%d", appId),
}
fr, err := http.Post(url, reqHeader, bytes.NewReader(paramJSON))
if err != nil {
return nil, err
}
result := &MediaSourceListResult{}
if err = json.Unmarshal(fr.Data, result); err != nil {
return nil, err
}
if result.Code != Success || len(result.Data.List) == 0 {
return nil, nil
}
return &result.Data.List[0], nil
}
+1
View File
@@ -0,0 +1 @@
package proxy
+3
View File
@@ -0,0 +1,3 @@
<div class="line" style="margin-top: 0"></div>
<blockquote><p>51吃瓜国内最新地址 <a href="https://51cga33.com">https://51cga33.com</a></p><p>51吃瓜海外永久地址 <a href="https://51cg1.com">https://51cg1.com</a></p><p>播放异常? 请刷新 或 使用<a href="/app.html">51吃瓜App</a> </p><p>苹果App白屏 请等待1分钟/切换网络/重新下载</p><p>发邮件获取 最新网址 👇长按复制保存👇<br> <a href="mailto:51cgfun@pm.me">51cgfun@pm.me</a></p></blockquote><p>曲阜师范大学学生【何鑫】的私密自拍视频流出,尺度炸裂,令人瞠目!这位清纯外表的学妹私下化身小母狗,为完成神秘“主人”的任务大秀骚浪本性!视频中,她身着宽松裸体背带裤,半遮半掩的布料勾勒出白嫩胴体,饱满小胸和粉嫩美穴若隐若现。</p><p><img loading="lazy" src="/usr/plugins/tbxw/zw.png" data-xuid="1" data-xkrkllgl="https://pic.arohkt.cn/upload_01/xiao/20250716/2025071618595633850.jpeg" alt="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 1" title="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 1"></p><p><img loading="lazy" src="/usr/plugins/tbxw/zw.png" data-xuid="2" data-xkrkllgl="https://pic.arohkt.cn/upload_01/xiao/20250716/2025071618595716822.jpeg" alt="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 2" title="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 2"></p><p><img loading="lazy" src="/usr/plugins/tbxw/zw.png" data-xuid="3" data-xkrkllgl="https://pic.arohkt.cn/upload_01/xiao/20250716/2025071618595888952.jpeg" alt="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 3" title="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 3"></p><p><img loading="lazy" src="/usr/plugins/tbxw/zw.png" data-xuid="4" data-xkrkllgl="https://pic.arohkt.cn/upload_01/xiao/20250716/2025071618595914322.jpeg" alt="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 4" title="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 4"></p><span id="menu_index_1" name="menu_index_1"></span><h2>何鑫裸体自拍玩穴</h2><p>她站在宿舍镜前,挑逗地拉下背带裤,露出湿漉漉的私处,手指大胆深入玩穴,湿滑水声混杂娇喘,镜头特写捕捉到她揉搓嫩穴的每一个细节,令人血脉喷张!</p><p><img loading="lazy" src="/usr/plugins/tbxw/zw.png" data-xuid="5" data-xkrkllgl="https://pic.arohkt.cn/upload_01/xiao/20250716/2025071619000598058.jpeg" alt="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 5" title="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 5"></p><p><img loading="lazy" src="/usr/plugins/tbxw/zw.png" data-xuid="6" data-xkrkllgl="https://pic.arohkt.cn/upload_01/xiao/20250716/2025071619000664755.jpeg" alt="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 6" title="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 6"></p><p><img loading="lazy" src="/usr/plugins/tbxw/zw.png" data-xuid="7" data-xkrkllgl="https://pic.arohkt.cn/upload_01/xiao/20250716/2025071619000740149.jpeg" alt="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 7" title="曲阜师范大学05年小母狗何鑫裸体自拍玩穴 7"></p><span id="menu_index_2" name="menu_index_2"></span><h2>何鑫足交伺候主人</h2><p>何鑫还完成足交任务,赤裸坐在床边,用白嫩玉足轻抚主人粗大肉棒,脚趾灵活挑逗,油亮光泽的脚掌摩擦到主人爽到低吼!</p><p><div class="dplayer" data-config='{"live":false,"autoplay":false,"theme":"#FADFA3","loop":false,"screenshot":false,"hotkey":true,"preload":"metadata","lang":"zh-cn","logo":null,"volume":0.69999999999999996,"mutex":true,"video_ads_url":"","ads_jump_url":"","ads_jump_time":-1,"video":{"url":"https:\/\/hls.qzkj.tech\/videos5\/8237add62367e0f0a4577a6e01a9ac41\/8237add62367e0f0a4577a6e01a9ac41.m3u8?auth_key=1752753843-6878e6b3b6eba-0-1dc27d84112bedd2d5e026d20954248a&v=3&time=0","type":"hls","thumbnails":null},"open_danmaku":"1"}'></div></p><p>关键词:#曲阜师范大学何鑫 #何鑫裸体自拍 #何鑫对镜玩穴自慰 #何鑫足交伺候主人 #何鑫不雅自拍视频 #曲阜师范大学 #何鑫 #自慰 #足交 #51吃瓜 #51吃瓜网 #黑料 #吃瓜</p><p>想看更多精彩完整版,下载51吃瓜APP一爽到底~</p><blockquote><p>51吃瓜APP下载地址:<br> 最新地址 <a href="https://url46.co/1222">https://url46.co/1222</a><br> 安卓下载备用地址一: <a href="https://url46.co/1237">https://url46.co/1237</a><br> 安卓下载备用地址二: <a href="https://url46.co/1238">https://url46.co/1238</a><br> iOS下载备用地址 <a href="https://url46.co/1239">https://url46.co/1239</a></p></blockquote> <div class="tags">
<div itemprop="keywords" class="keywords YkziYC"><a href="/tag/%E8%87%AA%E6%85%B0/">自慰</a><a href="/tag/%E8%B6%B3%E4%BA%A4/">足交</a><a href="/tag/%E9%BB%91%E6%96%99/">黑料</a><a href="/tag/%E5%90%83%E7%93%9C/">吃瓜</a><a href="/tag/51%E5%90%83%E7%93%9C%E7%BD%91/">51吃瓜网</a><a href="/tag/%E6%9B%B2%E9%98%9C%E5%B8%88%E8%8C%83%E5%A4%A7%E5%AD%A6/">曲阜师范大学</a><a href="/tag/51%E5%90%83%E7%93%9C/">51吃瓜</a><a href="/tag/%E6%9B%B2%E9%98%9C%E5%B8%88%E8%8C%83%E5%A4%A7%E5%AD%A6%E4%BD%95%E9%91%AB/">曲阜师范大学何鑫</a><a href="/tag/%E4%BD%95%E9%91%AB%E8%A3%B8%E4%BD%93%E8%87%AA%E6%8B%8D/">何鑫裸体自拍</a><a href="/tag/%E4%BD%95%E9%91%AB%E5%AF%B9%E9%95%9C%E7%8E%A9%E7%A9%B4%E8%87%AA%E6%85%B0/">何鑫对镜玩穴自慰</a><a href="/tag/%E4%BD%95%E9%91%AB%E8%B6%B3%E4%BA%A4%E4%BC%BA%E5%80%99%E4%B8%BB%E4%BA%BA/">何鑫足交伺候主人</a><a href="/tag/%E4%BD%95%E9%91%AB%E4%B8%8D%E9%9B%85%E8%87%AA%E6%8B%8D%E8%A7%86%E9%A2%91/">何鑫不雅自拍视频</a><a href="/tag/%E4%BD%95%E9%91%AB/">何鑫</a></div>
+529
View File
@@ -0,0 +1,529 @@
package proxy
import (
"strings"
"time"
"videoweb/pub/models/videoinformationmod"
"videoweb/pub/mongos"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type objreq struct {
Name string `json:"fileName"`
Data string `json:"fileData"`
}
type Obj struct {
Domain string `json:"domain"`
Name string `json:"fileName"`
}
type objresp struct {
Code int `json:"code"`
Object Obj `json:"data"`
Msg string `json:"msg"`
}
type ShardBody struct {
TaskId string `json:"taskId,omitempty"` // 文档md5
Pos int `json:"pos,omitempty"` // 位置
FileData string `json:"fileData,omitempty"` // 数据
Type string `json:"type,omitempty"`
TotalPos int `json:"totalPos,omitempty"` // 分片总数
}
type ShardBodyV2 struct {
TaskId string `json:"taskId,omitempty"` // 文档md5
Pos int `json:"pos,omitempty"` // 位置
FileData string `json:"fileData,omitempty"` // 数据
Type string `json:"type,omitempty"`
TotalPos int `json:"totalPos,omitempty"`
FileName string `json:"fileName,omitempty"`
Publish string `json:"publish,omitempty"`
AppId int `json:"appId,omitempty"`
MP4Folder string `json:"mp4Folder"` // 保存mp4的文件夹名,为空表示不需要保存mp4
}
type Data struct {
Id string `json:"id,omitempty"`
VideoUri string `json:"videoUri,omitempty"`
}
type Result struct {
Code int `json:"code,omitempty"` //
Data Data `json:"data,omitempty"` //
Msg string `json:"msg,omitempty"` //
}
type VideoOkResult struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"` //
Data string `json:"data,omitempty"`
}
type ShardOk struct {
TaskId string `json:"taskId,omitempty"` // 文档md5
Id string `json:"id,omitempty"` // Id
Title *string `json:"title,omitempty"` // 标题
CoverImg *string `json:"coverImg,omitempty"` // 封面
}
type MediaTaskSyncReq struct {
AppId int64 `bson:"appId" json:"appId"` // APPID
LastUpdateTime time.Time `bson:"lastUpdateTime" json:"lastUpdateTime"` // 最后更新时间
PageSize int64 `bson:"pageSize" json:"pageSize"`
}
type MediaQueryeReq struct {
Id string `json:"id"`
TaskId string `json:"taskId"`
}
type MediaQueryesReq struct {
Ids []string `json:"ids,omitempty"`
MediaSourceIds []string `json:"mediaSourceIds,omitempty"`
AppId int64 `json:"appId,omitempty"`
}
type VideoQueryResult struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"` //
Data MediaResp `json:"data,omitempty"`
}
type VideoQuerysResult struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"` //
Data []MediaResp `json:"data,omitempty"`
}
type MediaSyncReq struct {
PageNum int64 `json:"pageNum"`
PageSize int64 `json:"pageSize"`
Param *SyncParam `json:"param"`
}
type SyncParam struct {
Status string `bson:"status,omitempty" json:"status,omitempty"` // 当前状态
FirstTag string `json:"firstTag,omitempty"` // 一级标签
Publish string `json:"publish,omitempty"` // 视频发布者
}
type VideoSyncResult struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"` //
Data MediaSearchResp `json:"data,omitempty"`
}
// type MediaSearchResp struct {
// Total int64 `json:"total"`
// List []*MediaSync `json:"list"`
// }
type MediaResp struct {
Id primitive.ObjectID `bson:"_id,omitempty" json:"id"`
MediaSourceId primitive.ObjectID `bson:"mediaSourceId,omitempty" json:"mediaSourceId"` // 原始Id
VideoTime int32 `bson:"videoTime,omitempty" json:"videoTime"` // 影片长度
Size int64 `bson:"size,omitempty" json:"size"` // 文件size,单位byte
AppId int64 `bson:"appId,omitempty" json:"appId"` // 应用列表
CoverImg string `bson:"coverImg,omitempty" json:"coverImg"` // 封面
UnencryptedImage string `bson:"unencryptedImage,omitempty" json:"unencryptedImage"` // 不加密封面
VideoCover string `bson:"videoCover,omitempty" json:"videoCover"` // 视频封面
Title string `bson:"title,omitempty" json:"title"` // 标题
Publish string `bson:"publish,omitempty" json:"publish"` // 视频发布者
Remark string `bson:"remark,omitempty" json:"remark"` // 备注
Keyworld []string `bson:"keyworld,omitempty" json:"keyworld"` // 关键字
Nodes []videoinformationmod.Node `bson:"nodes" json:"nodes"` // 节点
FirstTag string `bson:"firstTag,omitempty" json:"firstTag"` // 一级标签
SecondTags []string `bson:"secondTags,omitempty" json:"secondTags"` // 二级标签标签
Status string `bson:"status,omitempty" json:"status"` // 当前状态
Desc string `bson:"desc,omitempty" json:"desc"` // 详细描述
TaskStartTime time.Time `bson:"taskStartTime,omitempty" json:"taskStartTime"` // 任务开始时间
SourceNameFs string `bson:"sourceNameFs,omitempty" json:"sourceNameFs"` // 远程源文件
IsDelLocalDir bool `bson:"isDelLocalDir,omitempty" json:"isDelLocalDir"` // 是否删除本机文件
WatermarkImage string `json:"watermarkImage" bson:"watermarkImage"` // 图片水印文件
WatermarkMedia string `json:"watermarkMedia" bson:"watermarkMedia"` // 视频水印文件
DownloadRetry int `bson:"downloadRetry,omitempty" json:"downloadRetry"` // 下载重试次数
WatermarkRetry int `bson:"watermarkRetry" json:"watermarkRetry"` // 水印重试次数
CompressRetry int `bson:"compressRetry" json:"compressRetry"` // 压缩重试次数
SegmentRetry int `bson:"segmentRetry" json:"segmentRetry"` // 切片重试次数
LinodeRetry int `bson:"linodeRetry" json:"linodeRetry"` // 上传重试次数
// 切片相关信息
Filename string `bson:"filename,omitempty" json:"filename"` // 文件名称
FieldNameFs string `bson:"fieldNameFs,omitempty" json:"fieldNameFs"` // 文件名称
PreMp4FileNameFs string `bson:"preMp4FileNameFs,omitempty" json:"preMp4FileNameFs"` // 预览MP4文件
UnencryptedPreMp4 string `bson:"unencryptedPreMp4,omitempty" json:"unencryptedPreMp4"` // 不加密的预览MP4
TempFieldNameFs string `bson:"tempFieldNameFs,omitempty" json:"tempFieldNameFs"` // 临时存储
Ext string `bson:"ext,omitempty" json:"ext"` // 视频后缀
TaskID string `bson:"taskId,omitempty" json:"taskId"` // 项目组传来的唯一标示
Width int64 `bson:"width,omitempty" json:"width"` // 分辨率宽
Height int64 `bson:"height,omitempty" json:"height"` // 分辨率高
FrameRate string `bson:"frameRate,omitempty" json:"frameRate"` // 视频贞数
SyBitRate string `bson:"syBitRate,omitempty" json:"syBitRate"` // 音频bit率
VidBitRate string `bson:"vidBitRate,omitempty" json:"vidBitRate"` // 视频bit率
CreatedAt time.Time `bson:"createdAt,omitempty" json:"createdAt"` // 创建时间
UpdatedAt time.Time `bson:"updatedAt,omitempty" json:"updatedAt"` // 更新时间
ProxyUpload *int32 `bson:"proxyUpload,omitempty" json:"proxyUpload"` // 代理上传
Retry int `bson:"retry" json:"retry"` // 重试次数 默认为零 最大重试3次
NotifySignal bool `bson:"notifySignal" json:"notifySignal"` //中止通知的信号 false 可以发送通知,true 中止发送通知
InfoTsName string `bson:"infoTsName" json:"infoTsName"` // 从该ts中获取视频分辨率等信息
SyncFlag int64 `bson:"syncFlag" json:"syncFlag"` // 同步状态
SrcKey string `bson:"srcKey,omitempty" json:"srcKey"` // 原始Key
IsPlaylet bool `bson:"isPlaylet,omitempty" json:"isPlaylet,omitempty"` // 是否短剧视频
UploadUserName string `bson:"uploadUserName" json:"uploadUserName,omitempty"` // 上传用户名
OptionAccount string `bson:"optionAccount,omitempty" json:"optionAccount"` // 最后操作人
}
// PlayletKeys 短剧媒资比对用的 ID(任务 id / 源 id / taskId)
func (info MediaResp) PlayletKeys() []string {
keys := make([]string, 0, 3)
if !info.Id.IsZero() {
keys = append(keys, info.Id.Hex())
}
if !info.MediaSourceId.IsZero() {
keys = append(keys, info.MediaSourceId.Hex())
}
if taskID := strings.TrimSpace(info.TaskID); taskID != "" {
keys = append(keys, taskID)
}
return keys
}
func (info *MediaResp) ToVideoInfo() *videoinformationmod.VideoInformation {
rsl := &videoinformationmod.VideoInformation{
Id: mongos.Lid.VideoInfo.Get(),
Title: info.Title,
AddedTime: time.Time{},
Keyworld: info.Keyworld,
FirstTag: info.FirstTag,
SecondTags: info.SecondTags,
CoverImg: info.CoverImg,
Desc: info.Desc,
Remark: info.Remark,
MediaType: videoinformationmod.MediaType_VideoV2,
Status: videoinformationmod.InformationSatusWaiting,
CategoryIds: make([]int64, 0),
Tags: make([]int64, 0),
Real: videoinformationmod.Flow{},
UpdatedAt: time.Now(),
CreatedAt: time.Now(),
OptionAccount: info.OptionAccount,
UploadUserName: info.UploadUserName,
UnencryptedImage: info.UnencryptedImage,
SyncId: info.Id.Hex(),
}
rsl.Nodes = make([]videoinformationmod.Node, 0)
if info.Nodes != nil && len(info.Nodes) > 0 {
for _, node := range info.Nodes {
node.Videos = make([]videoinformationmod.VideoInfo, 0)
rsl.Nodes = append(rsl.Nodes, node)
}
}
if len(info.FieldNameFs) > 0 {
rsl.Video = videoinformationmod.VideoInfo{
TaskId: info.TaskID,
FileId: info.Id.Hex(),
Url: info.FieldNameFs,
Cover: info.VideoCover,
Height: info.Height,
Width: info.Width,
VideoTime: info.VideoTime,
PreMp4FileNameFs: info.PreMp4FileNameFs,
UnencryptedPreMp4: info.UnencryptedPreMp4,
}
if !strings.HasSuffix(rsl.Video.Url, ".m3u8") {
rsl.Video.Url += ".m3u8"
}
}
return rsl
}
type MediaType int
const (
Preview MediaType = 1
Normal MediaType = 2
)
type FailReason string
const (
FailReasonNone FailReason = ""
FailReasonUploadTimeoutError FailReason = "UploadTimeoutError" // 上传超时
FailReasonMergeError FailReason = "MergeError" // 合并错误
FailReasonCompressError FailReason = "CompressError" // 压缩错误
FailReasonSegmentError FailReason = "SegmentError" // 分片错误
FailReasonLinodeError FailReason = "LinodeError" // Linode错误
)
type BaseInfo struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"id"`
SrcId int64 `bson:"srcId,omitempty" json:"srcId"` // 原始ID
Title string `bson:"title,omitempty" json:"title"` // 标题
CheckSum string `bson:"checkSum,omitempty" json:"checkSum"` // md5校验码
VideoTime int32 `bson:"videoTime,omitempty" json:"videoTime"` // 影片长度
Publish string `json:"publish,omitempty" bson:"publish"` // 视频发布者
Type string `bson:"type,omitempty" json:"type"` // 长视频/短视频
Preview MediaType `bson:"preview,omitempty" json:"preview"` // 预览普通视频:1:预览 2:正片
Country string `bson:"country,omitempty" json:"country"` // 国家 (国产、日本、欧美.... 前端固定)
FirstTag string `bson:"firstTag,omitempty" json:"firstTag"` // 一级标签
SecondTags []string `bson:"secondTags,omitempty" json:"secondTags"` // 二级标签标签
CoverImg string `bson:"coverImg,omitempty" json:"coverImg"` // 封面
PreFileName string `bson:"preFileName,omitempty" json:"preFileName"` // 预览文件
Status string `bson:"status,omitempty" json:"status"` // 当前状态
Desc string `bson:"desc,omitempty" json:"desc"` // 详细描述
Size int64 `bson:"size,omitempty" json:"size"` // 文件size,单位byte
Bango string `bson:"bango,omitempty" json:"bango"` // 番号,唯一
Directors []string `bson:"directors,omitempty" json:"directors"` // 导演
Actors []string `bson:"actors,omitempty" json:"actors"` // 演员
Studio string `bson:"studio,omitempty" json:"studio"` // 工作室/所有者
AddedTime time.Time `bson:"addedTime,omitempty" json:"addedTime"` // 上架时间
AppIds []int64 `bson:"appids,omitempty" json:"appids,omitempty"` // 应用列表
// 切片相关信息
Filename string `bson:"filename,omitempty" json:"filename"` // 文件名称
FieldNameFs string `bson:"fieldNameFs,omitempty" json:"fieldNameFs"` // 文件名称
Ext string `bson:"ext,omitempty" json:"ext"` // 视频后缀
TaskID string `bson:"taskId,omitempty" json:"taskId"` // 项目组传来的唯一标示
Width int `bson:"width,omitempty" json:"width"` // 分辨率宽
Height int `bson:"height,omitempty" json:"height"` // 分辨率高
Ratio float64 `bson:"ratio,omitempty" json:"ratio"` // 宽高比
FrameRate string `bson:"frameRate,omitempty" json:"frameRate"` // 视频贞数
SyBitRate string `bson:"syBitRate,omitempty" json:"syBitRate"` // 音频bit率
VidBitRate string `bson:"vidBitRate,omitempty" json:"vidBitRate"` // 视频bit率
CreatedAt time.Time `bson:"createdAt,omitempty" json:"createdAt"` // 创建时间
UpdatedAt time.Time `bson:"updatedAt,omitempty" json:"updatedAt"` // 更新时间
ProxyUpload *int32 `bson:"proxyUpload,omitempty" json:"proxyUpload"` // 代理上传
IsAdd bool `bson:"isAdd,omitempty" json:"isAdd"` // 是否加入到本地
Retry int `bson:"retry" json:"retry"` // 重试次数 默认为零 最大重试3次
NotifySignal bool `bson:"notifySignal" json:"notifySignal"` //中止通知的信号 false 可以发送通知,true 中止发送通知
ShowLocation int64 `bson:"showLocation" json:"showLocation"` // 显示位置
Remark string `bson:"remark,omitempty" json:"remark"`
MergeRetry int `bson:"mergeRetry" json:"mergeRetry"` //合并重试次数
CompressRetry int `bson:"compressRetry" json:"compressRetry"` //压缩重试次数
SegmentRetry int `bson:"segmentRetry" json:"segmentRetry"` //切片重试次数
LinodeRetry int `bson:"linodeRetry" json:"linodeRetry"` //上传linode重试次数
FailReason FailReason `bson:"failReason" json:"failReason"` //失败原因
DeleteDisk bool `bson:"deleteDisk" json:"deleteDisk"` //是否删除了对于磁盘文件
InfoTsName string `bson:"infoTsName" json:"infoTsName"` //从该ts中获取视频分辨率等信息
UploadedPoses []int64 `bson:"uploadedPoses" json:"uploadedPoses"` //上传过的pos列表
}
type MediaUpdate struct {
ID string `json:"id,omitempty"`
Title *string `bson:"title,omitempty" json:"title,omitempty"` // 标题
AddedTime *time.Time `bson:"addedTime,omitempty" json:"addedTime,omitempty"` // 上架时间
Publish *string `json:"publish,omitempty" bson:"publish,omitempty"` // 视频发布者
Country *string `bson:"country,omitempty" json:"country,omitempty"` // 国家 (国产、日本、欧美....)
Preview *MediaType `bson:"preview,omitempty" json:"preview,omitempty"` // 预览普通视频:1:预览 2:正片
Type *string `bson:"type,omitempty" json:"type,omitempty"` // 长视频/短视频
FirstTag *string `bson:"firstTag,omitempty" json:"firstTag,omitempty"` // 一级标签
SecondTags *[]string `bson:"secondTags,omitempty" json:"secondTags,omitempty"` // 二级标签标签
Bango *string `bson:"bango,omitempty" json:"bango,omitempty"` // 番号,唯一
AppIds *[]int64 `bson:"appids,omitempty" json:"appids,omitempty"` // 应用列表
Desc *string `bson:"desc,omitempty" json:"desc,omitempty"` // 详细描述
PreFileName *string `bson:"preFileName,omitempty" json:"preFileName,omitempty"` // 预览文件
CoverImg *string `bson:"coverImg,omitempty" json:"coverImg,omitempty"` // 封面
UnencryptedImage *string `bson:"unencryptedImage,omitempty" json:"unencryptedImage,omitempty"` // 不加密封面
CreatedAt *time.Time `bson:"createdAt,omitempty" json:"createdAt,omitempty"` // 创建时间
UpdatedAt *time.Time `bson:"updatedAt,omitempty" json:"updatedAt,omitempty"` // 更新时间
ShowLocation *int64 `bson:"showLocation,omitempty" json:"showLocation"` // 显示位置
MoveInfo *MoveInfo `bson:"moveInfo,omitempty" json:"moveInfo,omitempty"` // 电影自动更新
}
type MoveInfo struct {
Score float64 `json:"score" bson:"score"` // 评分 暂无评分=0
SerialCount int64 `json:"serialCount" bson:"serialCount"` // 总集数 serialCount
SerialIndex int64 `json:"serialIndex" bson:"serialIndex"` // 集数 lastName
Likes int64 `json:"likes" bson:"likes"` // 点赞数量 favoriteCount
Watchs int64 `json:"watchs" bson:"watchs"` // 点赞数量 view
UpdateDate time.Time `json:"updateDate" bson:"updateDate"` // 更新时间 languagesplaylist 短剧和剧集有更新 电影
MoveTag []string `json:"moveTag" bson:"moveTag"` // 标签:cidMapper + post_Year + regional
}
type VideoSearch struct {
ID string `json:"id,omitempty"`
Title *string `json:"title,omitempty"` // 标题
TaskID *string `json:"taskId,omitempty"` // 项目组传来的唯一标示
Publish *string `bson:"publish,omitempty"` // 视频发布者
Type *string `json:"type"` // 视频:长视频/短视频--时间阈值
Preview *int32 `json:"preview"` // 预览:1:预览 2:普通视频
Country *string `json:"country"` // 国家 (国产、日本、欧美.... 前端固定)
Appid *int64 `json:"appid"` // 应用ID
FirstTag *string `json:"firstTag,omitempty"` // 一级标签
SecondTags *string `json:"secondTags,omitempty"` // 二级标签标签
Status *string `json:"status,omitempty"` // 当前状态
Directors *[]string `json:"director,omitempty"` // 导演
Actors *[]string `json:"actors,omitempty"` // 演员
Studio *string `json:"studio,omitempty"` // 工作室
Bango *string `json:"bango,omitempty"` // 番号,唯一
Via *string `json:"via,omitempty"` // 来源
Remark *string `json:"remark,omitempty"` // 备注
AddedTime *string `json:"addedTime,omitempty"` // 上架时间
UploadTime *string `json:"uploadTime,omitempty"` // 上传时间
Start *time.Time `json:"start"` // 开始时间
End *time.Time `json:"end"` // 结束时间
ShowLocation *int64 `json:"showLocation"` // 显示位置
}
type MediaSearchReq struct {
PageNum int64 `json:"pageNum"`
PageSize int64 `json:"pageSize"`
Param VideoSearch `json:"param"`
}
// MediaSearchReq 媒体搜索请求返回
type MediaSearchResp struct {
Total int64 `json:"total"`
List []*BaseInfo `json:"list"`
}
type MediaSearchResult struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"` //
Data MediaSearchResp `json:"data,omitempty"`
}
type MediaDelReq struct {
ID string `json:"id,omitempty"`
}
// MediasDelResp 请求批量删除媒体回复
type MediaDelResp struct {
}
type MediaUpdatePreTime struct {
ID string `json:"id,omitempty"`
PreFileTime int64 `bson:"preFileTime,omitempty" json:"preFileTime"` // 预览文件(开始时间)
}
type MediaDelResult struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"` //
// Data MediaDelResp `json:"data,omitempty"`
}
type MediaUpdateReq struct {
//Ids []string `json:"id"`
MediaUpdate
}
// MediasUpdateResp 请求批量更新媒体回复
type MediaUpdateResp struct {
}
type MediaUpdateResult struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"` //
Data MediaUpdateResp `json:"data,omitempty"`
}
type AppAdvitiseInfoReq struct {
Id int64 `json:"id" binding:"required"`
}
type AdvitiseInfo struct {
Id string `json:"id" bson:"_id"` // 广告id
Location int64 `json:"location" bson:"location"` // 位置id
Title string `json:"title" bson:"title"` // 广告标题
Images string `json:"images" bson:"images"` // 视频banner
Link string `json:"link" bson:"link"` // 链接
}
type AdvitiseData struct {
DialogList []AdvitiseInfo `json:"dialogList" bson:"dialogList"` // 弹窗广告
HomeList []AdvitiseInfo `json:"homeList" bson:"homeList"` // 首页列表
VideoTopList []AdvitiseInfo `json:"videoTopList" bson:"videoTopList"` // 帖子详情(上)
VideoDownList []AdvitiseInfo `json:"videoDownList" bson:"videoDownList"` // 帖子详情(下)
HotAppList []AdvitiseInfo `json:"hotAppList" bson:"hotAppList"` // 热门应用
NewAppList []AdvitiseInfo `json:"newAppList" bson:"newAppList"` // 最新上架
MustAppList []AdvitiseInfo `json:"mustAppList" bson:"mustAppList"` // 必备精品
TitleAppList []AdvitiseInfo `json:"titleAppList" bson:"titleAppList"` // 标题广告(APP名称)
FriendList []AdvitiseInfo `json:"friendList" bson:"friendList"` // 友链
NineGridList []AdvitiseInfo `json:"nineGridList" bson:"nineGridList"` // 9宫格
VideoList []AdvitiseInfo `json:"videoList" bson:"videoList"` // 视频列表
StopList []AdvitiseInfo `json:"stopList" bson:"stopList"` // 暂停广告
ForcedJumpList []AdvitiseInfo `json:"forcedJumpList" bson:"forcedJumpList"` // 强制跳转广告
AppInfoAList []AdvitiseInfo `json:"appInfoAList" bson:"appInfoAList"` // 应用管理广告A
AppInfoBList []AdvitiseInfo `json:"appInfoBList" bson:"appInfoBList"` // 应用管理广告B
}
type AdvitiseQuerysResult struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"` //
Data AdvitiseData `json:"data,omitempty"`
}
// MediaFileSyncItem mediafile/sync 单条媒资项
type MediaFileSyncItem struct {
ID string `json:"id"`
Title string `json:"title"`
TaskID string `json:"taskId"`
FieldNameFs string `json:"fieldNameFs"`
CoverImg string `json:"coverImg"`
Width int64 `json:"width"`
Height int64 `json:"height"`
VideoTime int64 `json:"videoTime"`
Size int64 `json:"size"`
MediaFileVersion string `json:"mediaFileVersion"`
IsPlaylet bool `json:"isPlaylet"`
}
// MediaFileSyncReq 同步媒资库 m3u8 到 media 切片服
type MediaFileSyncReq struct {
AppId int64 `json:"appId"`
AppKey string `json:"appKey"`
VideoList []MediaFileSyncItem `json:"videoList"`
}
// MediaTaskAddReq 提交 media 加水印切片任务
type MediaTaskAddReq struct {
MediaSourceId string `json:"mediaSourceId"`
AppId int64 `json:"appId"`
AppKey string `json:"appKey"`
Title string `json:"title"`
WatermarkImage string `json:"watermarkImage"`
WatermarkMedia string `json:"watermarkMedia"`
WatermarkMediaTop string `json:"watermarkMediaTop"`
WatermarkMediaTopRight string `json:"watermarkMediaTopRight"`
WatermarkMediaBottomLeft string `json:"watermarkMediaBottomLeft"`
}
// MediaTaskUpdateWatermarkReq 按已有切片任务重新加水印
type MediaTaskUpdateWatermarkReq struct {
Id string `json:"id"`
AppId int64 `json:"appId"`
AppKey string `json:"appKey"`
WatermarkImage *string `json:"watermarkImage,omitempty"`
WatermarkMedia *string `json:"watermarkMedia,omitempty"`
WatermarkMediaTop *string `json:"watermarkMediaTop,omitempty"`
WatermarkMediaTopRight *string `json:"watermarkMediaTopRight,omitempty"`
WatermarkMediaBottomLeft *string `json:"watermarkMediaBottomLeft,omitempty"`
}
// MediaAPIResult media 通用响应
type MediaAPIResult struct {
Code int `json:"code"`
Msg string `json:"msg"`
Tip string `json:"tip"`
}
const MediaSourceCompletedFail = "CompletedFail"
// MediaSourceListReq 按 ID 查询 media 原片状态
type MediaSourceListReq struct {
Id string `json:"id"`
AppId int64 `json:"appId,omitempty"`
WebAppId int64 `json:"webAppId,omitempty"`
PageNum int64 `json:"pageNum"`
PageSize int64 `json:"pageSize"`
}
type MediaSourceListItem struct {
Status string `json:"status"`
FailReason string `json:"failReason"`
}
type MediaSourceListResult struct {
Code int `json:"code"`
Msg string `json:"msg"`
Tip string `json:"tip"`
Data struct {
Total int64 `json:"total"`
List []MediaSourceListItem `json:"list"`
} `json:"data"`
}
+139
View File
@@ -0,0 +1,139 @@
package proxy
import (
"fmt"
"strings"
)
const (
// 视频桶地址
BucketVideoAddressV1 = "http://ts.bbaazz.me"
// 图片桶地址
BucketImageAddressV1 = "http://img.bbaazz.me"
BucketImageAddressV2 = "http://tong3yuanimg.bbaazz.me"
// 上传路径
ImageUploadPathV1 = "/file/upload"
ImageUploadPathV2 = "/file/upload" // "/file/web/media/uploadImg"
VideoBodyPathV1 = "/file/web/proxy/videoBody"
VideoBodyPathV2 = "/file/web/proxy/videoBodyV2"
VideoOkPathV1 = "/file/web/proxy/videoOk"
VideoOkPathV2 = "/file/web/proxy/videoOkv2"
)
var (
BucketVideoAddressV2 = "http://139.162.27.29:19996" //正式
)
func InitBucketVideoAddress(addressV2 string) {
BucketVideoAddressV2 = addressV2
}
func DomainAddressRepair(domain string, defaultBucketAddress ...string) string {
if domain == "" {
if len(defaultBucketAddress) > 0 && defaultBucketAddress[0] != "" {
domain = defaultBucketAddress[0]
} else {
domain = BucketVideoAddressV2
}
}
return domain
}
func ImageUploadAddressRepair(domain string, defaultBucketAddress ...string) string {
domain = DomainAddressRepair(domain, defaultBucketAddress...)
if !strings.Contains(domain, ImageUploadPathV1) && !strings.Contains(domain, ImageUploadPathV2) {
if strings.HasPrefix(domain, BucketImageAddressV1) {
return domain + ImageUploadPathV1
} else if strings.HasPrefix(domain, BucketImageAddressV2) {
return domain + ImageUploadPathV2
}
return domain + ImageUploadPathV2
}
return domain
}
func VideoBodyAddressRepair(domain string, defaultBucketAddress ...string) string {
domain = DomainAddressRepair(domain, defaultBucketAddress...)
if strings.HasPrefix(domain, BucketVideoAddressV1) {
if !strings.Contains(domain, VideoBodyPathV1) {
return domain + VideoBodyPathV1
}
return domain
} else if strings.HasPrefix(domain, BucketVideoAddressV2) {
if !strings.Contains(domain, VideoBodyPathV2) {
return domain + VideoBodyPathV2
}
return domain
} else { // 未知存储桶,默认v2
if !strings.Contains(domain, VideoBodyPathV2) {
return domain + VideoBodyPathV2
}
return domain
}
}
func VideoOkAddressRepair(domain string, defaultBucketAddress ...string) string {
domain = DomainAddressRepair(domain, defaultBucketAddress...)
if strings.HasPrefix(domain, BucketVideoAddressV1) {
if !strings.Contains(domain, VideoOkPathV1) {
return domain + VideoOkPathV1
}
return domain
} else if strings.HasPrefix(domain, BucketVideoAddressV2) {
if !strings.Contains(domain, VideoOkPathV2) {
return domain + VideoOkPathV2
}
return domain
} else { // 未知存储桶,默认v2
if !strings.Contains(domain, VideoOkPathV2) {
return domain + VideoOkPathV2
}
return domain
}
}
func GetExistsUrlPathBucketAddress(path string) string {
if strings.HasPrefix(path, "v1/") {
return BucketVideoAddressV1
} else if strings.HasPrefix(path, "v2/") {
return BucketVideoAddressV2
} else if strings.HasPrefix(path, "v3/") {
return BucketVideoAddressV2
} else {
return BucketVideoAddressV1 // 欲漫涩、微博、快看禁漫 默认用桶2,其他的app,默认用桶1
}
}
func AppendV2PrefixToUrlPath(name string) string {
if name != "" && !strings.HasPrefix(name, "v2/") && !strings.HasPrefix(name, "v1/") && !strings.HasPrefix(name, "v3/") &&
!strings.HasPrefix(name, "/v2") && !strings.HasPrefix(name, "/v1") && !strings.HasPrefix(name, "/v3") {
name = fmt.Sprintf("v2/%s", name)
}
return name
}
func AppendV1PrefixToUrlPath(name string) string {
if name != "" && !strings.HasPrefix(name, "v2/") && !strings.HasPrefix(name, "v1/") && !strings.HasPrefix(name, "v3/") &&
!strings.HasPrefix(name, "/v2") && !strings.HasPrefix(name, "/v1") && !strings.HasPrefix(name, "/v3") {
name = fmt.Sprintf("v1/%s", name)
}
return name
}
func AppendsMediaS3Version(name string) string {
// 默认使用V1
if name != "" && !strings.HasPrefix(name, "v2/") && !strings.HasPrefix(name, "v1/") && !strings.HasPrefix(name, "v3/") &&
!strings.HasPrefix(name, "/v2") && !strings.HasPrefix(name, "/v1") && !strings.HasPrefix(name, "/v3") {
return "/v2"
}
return ""
}
func AppendsMediaS3VersionV1(name string) string {
// 默认使用V1
if name != "" && !strings.HasPrefix(name, "v2/") && !strings.HasPrefix(name, "v1/") && !strings.HasPrefix(name, "v3/") &&
!strings.HasPrefix(name, "/v2") && !strings.HasPrefix(name, "/v1") && !strings.HasPrefix(name, "/v3") {
return "/v1"
}
return ""
}
+157
View File
@@ -0,0 +1,157 @@
package proxy
import "testing"
func TestImageUploadAddressRepair(t *testing.T) {
type args struct {
domain string
defaultBucketAddress []string
}
tests := []struct {
name string
args args
want string
}{
{
name: "a",
args: args{
domain: "http://aaa",
defaultBucketAddress: []string{},
},
want: "http://aaa/file/upload",
},
{
name: "b",
args: args{
domain: "http://ts.bbaazz.me",
defaultBucketAddress: []string{},
},
want: "http://ts.bbaazz.me/file/upload",
},
{
name: "c",
args: args{
domain: "http://resourcets.bbaazz.me",
defaultBucketAddress: []string{},
},
want: "http://resourcets.bbaazz.me/file/upload",
},
{
name: "d",
args: args{
domain: "",
defaultBucketAddress: []string{BucketImageAddressV1},
},
want: "http://ts.bbaazz.me/file/upload",
},
{
name: "e",
args: args{
domain: "",
defaultBucketAddress: []string{BucketImageAddressV2},
},
want: "http://resourcets.bbaazz.me/file/upload",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ImageUploadAddressRepair(tt.args.domain, tt.args.defaultBucketAddress...); got != tt.want {
t.Errorf("ImageUploadAddressRepair() = %v, want %v", got, tt.want)
}
})
}
}
func TestVideoBodyAddressRepair(t *testing.T) {
type args struct {
domain string
}
tests := []struct {
name string
args args
want string
}{
{
name: "a",
args: args{domain: "http://aaa"},
want: "http://aaa/file/web/proxy/videoBodyV2",
},
{
name: "b",
args: args{domain: "http://ts.bbaazz.me"},
want: "http://ts.bbaazz.me/file/web/proxy/videoBody",
},
{
name: "c",
args: args{domain: "http://resourcets.bbaazz.me"},
want: "http://resourcets.bbaazz.me/file/web/proxy/videoBodyV2",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := VideoBodyAddressRepair(tt.args.domain); got != tt.want {
t.Errorf("VideoBodyAddressRepair() = %v, want %v", got, tt.want)
}
})
}
}
func TestVideoOkAddressRepair(t *testing.T) {
type args struct {
domain string
}
tests := []struct {
name string
args args
want string
}{
{
name: "a",
args: args{domain: "http://aaa"},
want: "http://aaa/file/web/proxy/videoOkv2",
},
{
name: "b",
args: args{domain: "http://ts.bbaazz.me"},
want: "http://ts.bbaazz.me/file/web/proxy/videoOk",
},
{
name: "c",
args: args{domain: "http://resourcets.bbaazz.me"},
want: "http://resourcets.bbaazz.me/file/web/proxy/videoOkv2",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := VideoOkAddressRepair(tt.args.domain); got != tt.want {
t.Errorf("VideoOkAddressRepair() = %v, want %v", got, tt.want)
}
})
}
}
func TestAppendV2PrefixToUrlPath(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
args args
want string
}{
{
name: "a",
args: args{
name: "abc/aaa",
},
want: "v2/abc/aaa",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := AppendV2PrefixToUrlPath(tt.args.name); got != tt.want {
t.Errorf("AppendV2PrefixToUrlPath() = %v, want %v", got, tt.want)
}
})
}
}