@@ -3,8 +3,13 @@ package cos
33import (
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
1015type 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
2127type 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+
158219type 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
171238type 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+
383475type 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
400493func (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