253 lines
7.5 KiB
Go
253 lines
7.5 KiB
Go
package api
|
||
|
||
import (
|
||
"fmt"
|
||
"time"
|
||
|
||
"contentSecurityDemo/conf"
|
||
"contentSecurityDemo/internal/model"
|
||
|
||
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
||
green20220302 "github.com/alibabacloud-go/green-20220302/v2/client"
|
||
util "github.com/alibabacloud-go/tea-utils/v2/service"
|
||
"github.com/alibabacloud-go/tea/tea"
|
||
)
|
||
|
||
// VideoScanner 视频内容安全扫描器2.0
|
||
type VideoScanner struct {
|
||
Client *green20220302.Client
|
||
Config *conf.Config
|
||
}
|
||
|
||
// VideoServiceType 视频审核服务类型
|
||
type VideoServiceType string
|
||
|
||
const (
|
||
// VideoBaselineCheckGlobal 视频文件检测
|
||
VideoBaselineCheckGlobal VideoServiceType = "videoDetection_global"
|
||
// VideoPostCheckByVLGlobal 视频文件检测_大模型版
|
||
VideoPostCheckByVLGlobal VideoServiceType = "videoDetectionByVL_global"
|
||
)
|
||
|
||
// NewVideoScanner 创建视频扫描器
|
||
func NewVideoScanner(config *conf.Config) (*VideoScanner, error) {
|
||
// 获取有效的访问凭证
|
||
accessKeyID, accessKeySecret, securityToken := config.GetEffectiveCredentials()
|
||
|
||
// 创建配置
|
||
clientConfig := &openapi.Config{
|
||
AccessKeyId: tea.String(accessKeyID),
|
||
AccessKeySecret: tea.String(accessKeySecret),
|
||
SecurityToken: tea.String(securityToken),
|
||
RegionId: tea.String(config.Region),
|
||
Endpoint: tea.String(config.Endpoint),
|
||
}
|
||
|
||
// 创建客户端
|
||
client, err := green20220302.NewClient(clientConfig)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("创建客户端失败: %v", err)
|
||
}
|
||
|
||
return &VideoScanner{
|
||
Client: client,
|
||
Config: config,
|
||
}, nil
|
||
}
|
||
|
||
// ScanVideoAsync 异步扫描视频
|
||
func (s *VideoScanner) ScanVideoAsync(videoURL string, dataID string, serviceType VideoServiceType) (*model.VideoScanResponse, error) {
|
||
// 创建运行时配置
|
||
runtime := &util.RuntimeOptions{}
|
||
runtime.ReadTimeout = tea.Int(10000)
|
||
runtime.ConnectTimeout = tea.Int(10000)
|
||
|
||
// 构建请求参数
|
||
videoScanRequest := &green20220302.VideoModerationRequest{
|
||
Service: tea.String(string(serviceType)),
|
||
ServiceParameters: tea.String(fmt.Sprintf(`{"url":"%s","dataId":"%s"}`, videoURL, dataID)),
|
||
}
|
||
|
||
// 调用API
|
||
response, err := s.Client.VideoModerationWithOptions(videoScanRequest, runtime)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("请求失败: %v", err)
|
||
}
|
||
|
||
// 转换响应格式
|
||
scanResponse := &model.VideoScanResponse{
|
||
Code: tea.Int32Value(response.Body.Code),
|
||
Message: tea.StringValue(response.Body.Message),
|
||
Data: make([]model.VideoScanData, 0),
|
||
}
|
||
|
||
// 创建单个数据项
|
||
scanData := model.VideoScanData{
|
||
DataID: tea.StringValue(response.Body.Data.DataId),
|
||
TaskID: tea.StringValue(response.Body.Data.TaskId),
|
||
Code: tea.Int32Value(response.Body.Code),
|
||
Message: tea.StringValue(response.Body.Message),
|
||
URL: videoURL,
|
||
}
|
||
|
||
scanResponse.Data = append(scanResponse.Data, scanData)
|
||
|
||
return scanResponse, nil
|
||
}
|
||
|
||
// GetVideoResult 获取视频审核结果
|
||
func (s *VideoScanner) GetVideoResult(taskID string) (*model.VideoResultResponse, error) {
|
||
// 创建运行时配置
|
||
runtime := &util.RuntimeOptions{}
|
||
runtime.ReadTimeout = tea.Int(10000)
|
||
runtime.ConnectTimeout = tea.Int(10000)
|
||
|
||
// 构建请求参数
|
||
videoResultRequest := &green20220302.VideoModerationResultRequest{
|
||
Service: tea.String("videoDetection_global"),
|
||
ServiceParameters: tea.String(fmt.Sprintf(`{"taskId":"%s"}`, taskID)),
|
||
}
|
||
|
||
// 调用API
|
||
response, err := s.Client.VideoModerationResultWithOptions(videoResultRequest, runtime)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("请求失败: %v", err)
|
||
}
|
||
|
||
// 转换响应格式
|
||
resultResponse := &model.VideoResultResponse{
|
||
Code: tea.Int32Value(response.Body.Code),
|
||
Message: tea.StringValue(response.Body.Message),
|
||
Data: make([]model.VideoResultData, 0),
|
||
}
|
||
|
||
// 创建单个数据项
|
||
resultData := model.VideoResultData{
|
||
Code: tea.Int32Value(response.Body.Code),
|
||
Message: tea.StringValue(response.Body.Message),
|
||
}
|
||
if tea.StringValue(response.Body.Message) == "SUCCESS" {
|
||
resultData.Status = "success"
|
||
} else if tea.StringValue(response.Body.Message) == "PROCESSING" {
|
||
resultData.Status = "running"
|
||
} else {
|
||
resultData.Status = "failure"
|
||
}
|
||
|
||
// 如果有结果数据,进行转换
|
||
if response.Body.Data != nil {
|
||
resultData.DataID = tea.StringValue(response.Body.Data.DataId)
|
||
resultData.TaskID = tea.StringValue(response.Body.Data.TaskId)
|
||
resultData.Results = response.Body.Data
|
||
}
|
||
|
||
resultResponse.Data = append(resultResponse.Data, resultData)
|
||
|
||
return resultResponse, nil
|
||
}
|
||
|
||
// ScanVideoAndWait 扫描视频并等待结果
|
||
func (s *VideoScanner) ScanVideoAndWait(videoURL string, dataID string, serviceType VideoServiceType, maxWaitTime time.Duration) (*model.VideoResultResponse, error) {
|
||
// 提交扫描任务
|
||
scanResponse, err := s.ScanVideoAsync(videoURL, dataID, serviceType)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("提交扫描任务失败: %v", err)
|
||
}
|
||
|
||
if len(scanResponse.Data) == 0 {
|
||
return nil, fmt.Errorf("未获取到任务ID")
|
||
}
|
||
|
||
taskID := scanResponse.Data[0].TaskID
|
||
fmt.Printf("视频扫描任务已提交,任务ID: %s\n", taskID)
|
||
|
||
// 轮询获取结果
|
||
startTime := time.Now()
|
||
for time.Since(startTime) < maxWaitTime {
|
||
result, err := s.GetVideoResult(taskID)
|
||
if err != nil {
|
||
return nil, fmt.Errorf("获取结果失败: %v", err)
|
||
}
|
||
|
||
if len(result.Data) > 0 {
|
||
status := result.Data[0].Status
|
||
fmt.Printf("当前状态: %s\n", status)
|
||
|
||
switch status {
|
||
case "success":
|
||
return result, nil
|
||
case "failure":
|
||
return nil, fmt.Errorf("视频审核失败: %s", result.Data[0].Message)
|
||
case "running", "pending":
|
||
// 继续等待
|
||
time.Sleep(5 * time.Second)
|
||
default:
|
||
return nil, fmt.Errorf("未知状态: %s", status)
|
||
}
|
||
} else {
|
||
time.Sleep(5 * time.Second)
|
||
}
|
||
}
|
||
|
||
return nil, fmt.Errorf("等待超时,请稍后手动查询结果,任务ID: %s", taskID)
|
||
}
|
||
|
||
// PrintScanResult 打印扫描提交结果
|
||
func (s *VideoScanner) PrintScanResult(response *model.VideoScanResponse) {
|
||
fmt.Println("=== 视频扫描任务提交结果 ===")
|
||
fmt.Printf("状态码: %d\n", response.Code)
|
||
fmt.Printf("消息: %s\n", response.Message)
|
||
|
||
for _, data := range response.Data {
|
||
fmt.Printf("数据ID: %s\n", data.DataID)
|
||
fmt.Printf("任务ID: %s\n", data.TaskID)
|
||
fmt.Printf("处理状态: %d - %s\n", data.Code, data.Message)
|
||
fmt.Printf("视频URL: %s\n", data.URL)
|
||
}
|
||
}
|
||
|
||
// PrintResult 打印审核结果
|
||
func (s *VideoScanner) PrintResult(response *model.VideoResultResponse) {
|
||
fmt.Println("=== 视频内容安全审核结果===")
|
||
fmt.Printf("状态码: %d\n", response.Code)
|
||
fmt.Printf("消息: %s\n", response.Message)
|
||
|
||
for _, data := range response.Data {
|
||
fmt.Printf("\n数据ID: %s\n", data.DataID)
|
||
fmt.Printf("任务ID: %s\n", data.TaskID)
|
||
fmt.Printf("处理状态: %d - %s\n", data.Code, data.Message)
|
||
fmt.Printf("审核状态: %s\n", data.Status)
|
||
|
||
if data.Results != nil {
|
||
result := *data.Results
|
||
if result.LiveId != nil {
|
||
fmt.Printf("直播ID: %s\n", *result.LiveId)
|
||
}
|
||
if result.ManualTaskId != nil {
|
||
fmt.Printf("人工任务ID: %s\n", *result.ManualTaskId)
|
||
}
|
||
if result.RiskLevel != nil {
|
||
fmt.Printf("风险等级: %s\n", *result.RiskLevel)
|
||
}
|
||
// 打印详细信息
|
||
if result.AudioResult != nil {
|
||
fmt.Println("音频审核结果:")
|
||
audioResult := *result.AudioResult
|
||
if audioResult.RiskLevel != nil {
|
||
fmt.Printf("风险等级: %s\n", *audioResult.RiskLevel)
|
||
}
|
||
}
|
||
|
||
// 打印扩展信息
|
||
if result.FrameResult != nil {
|
||
fmt.Println("帧审核结果:")
|
||
frameResult := *result.FrameResult
|
||
if frameResult.RiskLevel != nil {
|
||
fmt.Printf("风险等级: %s\n", *frameResult.RiskLevel)
|
||
}
|
||
}
|
||
fmt.Println("---")
|
||
}
|
||
}
|
||
}
|