Skip to content

Commit 2130602

Browse files
authored
Merge pull request #167 from agin719/cos-v4-dev
Cos v4 dev
2 parents eb31d7f + 108941e commit 2130602

File tree

6 files changed

+865
-27
lines changed

6 files changed

+865
-27
lines changed

ci_media.go

Lines changed: 347 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ package cos
33
import (
44
"context"
55
"encoding/xml"
6+
"errors"
67
"fmt"
78
"net/http"
9+
"strings"
10+
11+
"github.com/clbanning/mxj"
12+
"github.com/mitchellh/mapstructure"
813
)
914

1015
type JobInput struct {
@@ -16,6 +21,7 @@ type JobOutput struct {
1621
Bucket string `xml:"Bucket,omitempty"`
1722
Object string `xml:"Object,omitempty"`
1823
SpriteObject string `xml:"SpriteObject,omitempty"`
24+
AuObject string `xml:"AuObject,omitempty"`
1925
}
2026

2127
type Container struct {
@@ -155,17 +161,78 @@ type Segment struct {
155161
Duration string `xml:"Duration,omitempty"`
156162
}
157163

164+
type VideoMontageVideo struct {
165+
Codec string `xml:"Codec"`
166+
Width string `xml:"Width"`
167+
Height string `xml:"Height"`
168+
Fps string `xml:"Fps"`
169+
Remove string `xml:"Remove,omitempty"`
170+
Bitrate string `xml:"Bitrate"`
171+
Crf string `xml:"Crf"`
172+
}
173+
174+
type VideoMontage struct {
175+
Container *Container `xml:"Container,omitempty"`
176+
Video *VideoMontageVideo `xml:"Video,omitempty"`
177+
Audio *Audio `xml:"Audio,omitempty"`
178+
Duration string `xml:"Duration,omitempty"`
179+
}
180+
181+
type AudioConfig struct {
182+
Codec string `xml:"Codec"`
183+
Samplerate string `xml:"Samplerate"`
184+
Bitrate string `xml:"Bitrate"`
185+
Channels string `xml:"Channels"`
186+
}
187+
188+
type VoiceSeparate struct {
189+
AudioMode string `xml:"AudioMode,omitempty"` // IsAudio 人声, IsBackground 背景声, AudioAndBackground 人声和背景声
190+
AudioConfig *AudioConfig `xml:"AudioConfig,omitempty"`
191+
}
192+
193+
type ColorEnhance struct {
194+
Enable string `xml:"Enable"`
195+
Contrast string `xml:"Contrast"`
196+
Correction string `xml:"Correction"`
197+
Saturation string `xml:"Saturation"`
198+
}
199+
200+
type MsSharpen struct {
201+
Enable string `xml:"Enable"`
202+
SharpenLevel string `xml:"SharpenLevel"`
203+
}
204+
205+
type VideoProcess struct {
206+
ColorEnhance *ColorEnhance `xml:"ColorEnhance,omitempty"`
207+
MsSharpen *MsSharpen `xml:"MsSharpen,omitempty"`
208+
}
209+
210+
type SDRtoHDR struct {
211+
HdrMode string `xml:"HdrMode,omitempty"` // HLG、HDR10
212+
}
213+
214+
type SuperResolution struct {
215+
Resolution string `xml:"Resolution,omitempty"` // sdtohd、hdto4k
216+
EnableScaleUp string `xml:"EnableScaleUp,omitempty"`
217+
}
218+
158219
type MediaProcessJobOperation struct {
159-
Tag string `xml:"Tag,omitempty"`
160-
Output *JobOutput `xml:"Output,omitempty"`
161-
Transcode *Transcode `xml:"Transcode,omitempty"`
162-
Watermark *Watermark `xml:"Watermark,omitempty"`
163-
TemplateId string `xml:"TemplateId,omitempty"`
164-
WatermarkTemplateId []string `xml:"WatermarkTemplateId,omitempty"`
165-
ConcatTemplate *ConcatTemplate `xml:"ConcatTemplate,omitempty"`
166-
Snapshot *Snapshot `xml:"Snapshot,omitempty"`
167-
Animation *Animation `xml:"Animation,omitempty"`
168-
Segment *Segment `xml:"Segment,omitempty"`
220+
Tag string `xml:"Tag,omitempty"`
221+
Output *JobOutput `xml:"Output,omitempty"`
222+
Transcode *Transcode `xml:"Transcode,omitempty"`
223+
Watermark *Watermark `xml:"Watermark,omitempty"`
224+
TemplateId string `xml:"TemplateId,omitempty"`
225+
WatermarkTemplateId []string `xml:"WatermarkTemplateId,omitempty"`
226+
ConcatTemplate *ConcatTemplate `xml:"ConcatTemplate,omitempty"`
227+
Snapshot *Snapshot `xml:"Snapshot,omitempty"`
228+
Animation *Animation `xml:"Animation,omitempty"`
229+
Segment *Segment `xml:"Segment,omitempty"`
230+
VideoMontage *VideoMontage `xml:"VideoMontage,omitempty"`
231+
VoiceSeparate *VoiceSeparate `xml:"VoiceSeparate,omitempty"`
232+
VideoProcess *VideoProcess `xml:"VideoProcess,omitempty"`
233+
TranscodeTemplateId string `xml:"TranscodeTemplateId,omitempty"` // 视频增强、超分、SDRtoHDR任务类型,可以选择转码模板相关参数
234+
SDRtoHDR *SDRtoHDR `xml:"SDRtoHDR,omitempty"`
235+
SuperResolution *SuperResolution `xml:"SuperResolution,omitempty"`
169236
}
170237

171238
type CreateMediaJobsOptions struct {
@@ -380,6 +447,31 @@ func (s *CIService) DescribeMediaJob(ctx context.Context, jobid string) (*Descri
380447
return &res, resp, err
381448
}
382449

450+
type DescribeMutilMediaProcessJobResult struct {
451+
XMLName xml.Name `xml:"Response"`
452+
JobsDetail []MediaProcessJobDetail `xml:"JobsDetail,omitempty"`
453+
NonExistJobIds []string `xml:"NonExistJobIds,omitempty"`
454+
}
455+
456+
func (s *CIService) DescribeMultiMediaJob(ctx context.Context, jobids []string) (*DescribeMutilMediaProcessJobResult, *Response, error) {
457+
jobidsStr := ""
458+
if len(jobids) < 1 {
459+
return nil, nil, errors.New("empty param jobids")
460+
} else {
461+
jobidsStr = strings.Join(jobids, ",")
462+
}
463+
464+
var res DescribeMutilMediaProcessJobResult
465+
sendOpt := sendOptions{
466+
baseURL: s.client.BaseURL.CIURL,
467+
uri: "/jobs/" + jobidsStr,
468+
method: http.MethodGet,
469+
result: &res,
470+
}
471+
resp, err := s.client.send(ctx, &sendOpt)
472+
return &res, resp, err
473+
}
474+
383475
type DescribeMediaJobsOptions struct {
384476
QueueId string `url:"queueId,omitempty"`
385477
Tag string `url:"tag,omitempty"`
@@ -397,6 +489,7 @@ type DescribeMediaJobsResult struct {
397489
NextToken string `xml:"NextToken,omitempty"`
398490
}
399491

492+
// https://cloud.tencent.com/document/product/460/48235
400493
func (s *CIService) DescribeMediaJobs(ctx context.Context, opt *DescribeMediaJobsOptions) (*DescribeMediaJobsResult, *Response, error) {
401494
var res DescribeMediaJobsResult
402495
sendOpt := sendOptions{
@@ -640,3 +733,247 @@ func (s *CIService) GetSnapshot(ctx context.Context, name string, opt *GetSnapsh
640733
resp, err := s.client.send(ctx, &sendOpt)
641734
return resp, err
642735
}
736+
737+
type GetPrivateM3U8Options struct {
738+
Expires int `url:"expires"`
739+
}
740+
741+
// 获取私有m3u8资源接口 https://cloud.tencent.com/document/product/460/63738
742+
func (s *CIService) GetPrivateM3U8(ctx context.Context, name string, opt *GetPrivateM3U8Options, id ...string) (*Response, error) {
743+
var u string
744+
if len(id) == 1 {
745+
u = fmt.Sprintf("/%s?versionId=%s&ci-process=pm3u8", encodeURIComponent(name), id[0])
746+
} else if len(id) == 0 {
747+
u = fmt.Sprintf("/%s?ci-process=pm3u8", encodeURIComponent(name))
748+
} else {
749+
return nil, fmt.Errorf("wrong params")
750+
}
751+
752+
sendOpt := sendOptions{
753+
baseURL: s.client.BaseURL.BucketURL,
754+
uri: u,
755+
method: http.MethodGet,
756+
optQuery: opt,
757+
disableCloseBody: true,
758+
}
759+
resp, err := s.client.send(ctx, &sendOpt)
760+
return resp, err
761+
}
762+
763+
type TriggerWorkflowOptions struct {
764+
WorkflowId string `url:"workflowId"`
765+
Object string `url:"object"`
766+
}
767+
768+
type TriggerWorkflowResult struct {
769+
XMLName xml.Name `xml:"Response"`
770+
InstanceId string `xml:"InstanceId"`
771+
RequestId string `xml:"RequestId"`
772+
}
773+
774+
//单文件触发工作流 https://cloud.tencent.com/document/product/460/54640
775+
func (s *CIService) TriggerWorkflow(ctx context.Context, opt *TriggerWorkflowOptions) (*TriggerWorkflowResult, *Response, error) {
776+
var res TriggerWorkflowResult
777+
sendOpt := sendOptions{
778+
baseURL: s.client.BaseURL.CIURL,
779+
uri: "/triggerworkflow",
780+
optQuery: opt,
781+
method: http.MethodPost,
782+
result: &res,
783+
}
784+
resp, err := s.client.send(ctx, &sendOpt)
785+
return &res, resp, err
786+
}
787+
788+
type DescribeWorkflowExecutionsOptions struct {
789+
WorkflowId string `url:"workflowId,omitempty"`
790+
Name string `url:"Name,omitempty"`
791+
OrderByTime string `url:"orderByTime,omitempty"`
792+
NextToken string `url:"nextToken,omitempty"`
793+
Size int `url:"size,omitempty"`
794+
States string `url:"states,omitempty"`
795+
StartCreationTime string `url:"startCreationTime,omitempty"`
796+
EndCreationTime string `url:"endCreationTime,omitempty"`
797+
}
798+
799+
type WorkflowExecutionList struct {
800+
RunId string `xml:"RunId,omitempty"`
801+
WorkflowId string `xml:"WorkflowId,omitempty"`
802+
State string `xml:"State,omitempty"`
803+
CreationTime string `xml:"CreationTime,omitempty"`
804+
Object string `xml:"Object,omitempty"`
805+
}
806+
807+
type DescribeWorkflowExecutionsResult struct {
808+
XMLName xml.Name `xml:"Response"`
809+
WorkflowExecutionList []WorkflowExecutionList `xml:"WorkflowExecutionList,omitempty"`
810+
NextToken string `xml:"NextToken,omitempty"`
811+
}
812+
813+
//获取工作流实例列表 https://cloud.tencent.com/document/product/460/45950
814+
func (s *CIService) DescribeWorkflowExecutions(ctx context.Context, opt *DescribeWorkflowExecutionsOptions) (*DescribeWorkflowExecutionsResult, *Response, error) {
815+
var res DescribeWorkflowExecutionsResult
816+
sendOpt := sendOptions{
817+
baseURL: s.client.BaseURL.CIURL,
818+
uri: "/workflowexecution",
819+
optQuery: opt,
820+
method: http.MethodGet,
821+
result: &res,
822+
}
823+
resp, err := s.client.send(ctx, &sendOpt)
824+
return &res, resp, err
825+
}
826+
827+
type NotifyConfig struct {
828+
URL string `xml:"Url,omitempty"`
829+
Event string `xml:"Event,omitempty"`
830+
Type string `xml:"Type,omitempty"`
831+
}
832+
833+
type ExtFilter struct {
834+
State string `xml:"State,omitempty"`
835+
Audio string `xml:"Audio,omitempty"`
836+
Custom string `xml:"Custom,omitempty"`
837+
CustomExts string `xml:"CustomExts,omitempty"`
838+
AllFile string `xml:"AllFile,omitempty"`
839+
}
840+
841+
type NodeInput struct {
842+
QueueId string `xml:"QueueId,omitempty"`
843+
ObjectPrefix string `xml:"ObjectPrefix,omitempty"`
844+
NotifyConfig *NotifyConfig `xml:"NotifyConfig,omitempty" json:"NotifyConfig,omitempty"`
845+
ExtFilter *ExtFilter `xml:"ExtFilter,omitempty" json:"ExtFilter,omitempty"`
846+
}
847+
848+
type NodeSegment struct {
849+
Format string `xml:"Format,omitempty"`
850+
Duration string `xml:"Duration,omitempty"`
851+
}
852+
853+
type NodeOutput struct {
854+
Region string `xml:"Region,omitempty"`
855+
Bucket string `xml:"Bucket,omitempty"`
856+
Object string `xml:"Object,omitempty"`
857+
AuObject string `xml:"AuObject,omitempty"`
858+
SpriteObject string `xml:"SpriteObject,omitempty"`
859+
}
860+
861+
type NodeSCF struct {
862+
Region string `xml:"Region,omitempty"`
863+
FunctionName string `xml:"FunctionName,omitempty"`
864+
Namespace string `xml:"Namespace,omitempty"`
865+
}
866+
867+
type NodeSDRtoHDR struct {
868+
HdrMode string `xml:"HdrMode,omitempty"`
869+
}
870+
871+
type NodeSmartCover struct {
872+
Format string `xml:"Format,omitempty"`
873+
Width string `xml:"Width,omitempty"`
874+
Height string `xml:"Height,omitempty"`
875+
Count string `xml:"Count,omitempty"`
876+
DeleteDuplicates string `xml:"DeleteDuplicates,omitempty"`
877+
}
878+
879+
type NodeOperation struct {
880+
TemplateId string `xml:"TemplateId,omitempty" json:"TemplateId,omitempty"`
881+
Segment *NodeSegment `xml:"Segment,omitempty" json:"Segment,omitempty" `
882+
Output *NodeOutput `xml:"Output,omitempty" json:"Output,omitempty"`
883+
SCF *NodeSCF `xml:"SCF,omitempty" json:"SCF,omitempty"`
884+
SDRtoHDR *NodeSDRtoHDR `xml:"SDRtoHDR,omitempty" json:"SDRtoHDR,omitempty"`
885+
SmartCover *NodeSmartCover `xml:"SmartCover,omitempty" json:"SmartCover,omitempty"`
886+
WatermarkTemplateId string `xml:"WatermarkTemplateId,omitempty" json:"WatermarkTemplateId,omitempty`
887+
TranscodeTemplateId string `xml:"TranscodeTemplateId,omitempty" json:"TranscodeTemplateId,omitempty"`
888+
}
889+
890+
type Node struct {
891+
Type string `xml:"Type"`
892+
Input *NodeInput `xml:"Input,omitempty" json:"Input,omitempty"`
893+
Operation *NodeOperation `xml:"Operation,omitempty" json:"Operation,omitempty"`
894+
}
895+
896+
type Topology struct {
897+
Dependencies map[string]string `json:"Dependencies,omitempty"`
898+
Nodes map[string]Node `json:"Nodes,omitempty"`
899+
}
900+
901+
func (m *Topology) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
902+
var v struct {
903+
XMLName xml.Name //`xml:"Topology"`
904+
Dependencies struct {
905+
Inner []byte `xml:",innerxml"`
906+
} `xml:"Dependencies"`
907+
Nodes struct {
908+
Inner []byte `xml:",innerxml"`
909+
} `xml:"Nodes"`
910+
}
911+
err := d.DecodeElement(&v, &start)
912+
if err != nil {
913+
return err
914+
}
915+
916+
myMap := make(map[string]interface{})
917+
918+
// ... do the mxj magic here ... -
919+
920+
temp := v.Nodes.Inner
921+
922+
prefix := "<Nodes>"
923+
postfix := "</Nodes>"
924+
str := prefix + string(temp) + postfix
925+
//fmt.Println(str)
926+
myMxjMap, _ := mxj.NewMapXml([]byte(str))
927+
myMap, _ = myMxjMap["Nodes"].(map[string]interface{})
928+
nodesMap := make(map[string]Node)
929+
930+
for k, v := range myMap {
931+
var node Node
932+
mapstructure.Decode(v, &node)
933+
nodesMap[k] = node
934+
}
935+
936+
// fill myMap
937+
m.Nodes = nodesMap
938+
939+
deps := make(map[string]interface{})
940+
941+
tep := "<Dependencies>" + string(v.Dependencies.Inner) + "</Dependencies>"
942+
tepMxjMap, _ := mxj.NewMapXml([]byte(tep))
943+
deps, _ = tepMxjMap["Dependencies"].(map[string]interface{})
944+
depsString := make(map[string]string)
945+
for k, v := range deps {
946+
depsString[k] = v.(string)
947+
}
948+
m.Dependencies = depsString
949+
return nil
950+
}
951+
952+
type WorkflowExecution struct {
953+
RunId string `xml:"RunId,omitempty" json:"RunId,omitempty"`
954+
WorkflowId string `xml:"WorkflowId,omitempty" json:"WorkflowId,omitempty"`
955+
WorkflowName string `xml:"WorkflowName,omitempty" json:"WorkflowName,omitempty"`
956+
State string `xml:"State,omitempty" json:"State,omitempty"`
957+
CreateTime string `xml:"CreateTime,omitempty" json:"CreateTime,omitempty"`
958+
Object string `xml:"Object,omitempty" json:"Object,omitempty"`
959+
Topology Topology `xml:"Topology,omitempty" json:"Topology,omitempty"`
960+
}
961+
962+
type DescribeWorkflowExecutionResult struct {
963+
XMLName xml.Name `xml:"Response"`
964+
WorkflowExecution []WorkflowExecution `xml:"WorkflowExecution,omitempty" json:"WorkflowExecution,omitempty"`
965+
NextToken string `xml:"NextToken,omitempty" json:"NextToken,omitempty"`
966+
}
967+
968+
//获取工作流实例详情 https://cloud.tencent.com/document/product/460/45949
969+
func (s *CIService) DescribeWorkflowExecution(ctx context.Context, runId string) (*DescribeWorkflowExecutionResult, *Response, error) {
970+
var res DescribeWorkflowExecutionResult
971+
sendOpt := sendOptions{
972+
baseURL: s.client.BaseURL.CIURL,
973+
uri: "/workflowexecution/" + runId,
974+
method: http.MethodGet,
975+
result: &res,
976+
}
977+
resp, err := s.client.send(ctx, &sendOpt)
978+
return &res, resp, err
979+
}

0 commit comments

Comments
 (0)