简介
本文档提供关于同步转码(边转边播)的相关 API 概览以及 SDK 示例代码。
API | 操作描述 |
生成边转边播的播放列表能够分析视频文件产出 m3u8文件。生成播放列表后即时播放,并根据播放进度实施按需转码,相比离线转码能极大减少了转码等待时间并大幅度降低了转码和存储开销。 |
生成播放列表任务
方法原型
func (s *CIService) CreateGeneratePlayListJob(ctx context.Context, opt *CreateGeneratePlayListJobOptions) (*CreateJobsResult, *Response, error)
参数说明
type LiveTanscodeVideo struct {Codec string `xml:"Codec"`Width string `xml:"Width,omitempty"`Height string `xml:"Height,omitempty"`Fps string `xml:"Fps,omitempty"`Profile string `xml:"Profile,omitempty"`Bitrate string `xml:"Bitrate,omitempty"`Gop string `xml:"Gop,omitempty"`Maxrate string `xml:"Maxrate,omitempty"`Crf string `xml:"Crf,omitempty"`Pixfmt string `xml:"Pixfmt,omitempty"`LongShortMode string `xml:"LongShortMode,omitempty"`Interlaced string `xml:"Interlaced,omitempty"`ColorParam *VideoColorParam `xml:"ColorParam,omitempty"`}type LiveTanscodeTransConfig struct {InitialClipNum string `xml:"InitialClipNum,omitempty"`CosTag string `xml:"CosTag,omitempty"`HlsEncrypt *HlsEncrypt `xml:"HlsEncrypt,omitempty"`}type LiveTanscode struct {Container *Container `xml:"Container,omitempty"`Video *LiveTanscodeVideo `xml:"Video,omitempty"`// TimeInterval *TimeInterval `xml:"TimeInterval,omitempty"`// Audio *Audio `xml:"Audio,omitempty"`TransConfig *LiveTanscodeTransConfig `xml:"TransConfig,omitempty"`}type GeneratePlayListJobOperation struct {Tag string `xml:"Tag,omitempty"`Output *JobOutput `xml:"Output,omitempty"`MediaResult *MediaResult `xml:"MediaResult,omitempty"`MediaInfo *MediaInfo `xml:"MediaInfo,omitempty"`Transcode *LiveTanscode `xml:"Transcode,omitempty"`UserData string `xml:"UserData,omitempty"`JobLevel int `xml:"JobLevel,omitempty"`Watermark []Watermark `xml:"Watermark,omitempty"`WatermarkTemplateId []string `xml:"WatermarkTemplateId,omitempty"`}type CreateGeneratePlayListJobOptions struct {XMLName xml.Name `xml:"Request"`Tag string `xml:"Tag,omitempty"`Input *JobInput `xml:"Input,omitempty"`Operation *GeneratePlayListJobOperation `xml:"Operation,omitempty"`QueueId string `xml:"QueueId,omitempty"`QueueType string `xml:"QueueType,omitempty"`CallBackFormat string `xml:"CallBackFormat,omitempty"`CallBackType string `xml:"CallBackType,omitempty"`CallBack string `xml:"CallBack,omitempty"`CallBackMqConfig *NotifyConfigCallBackMqConfig `xml:"CallBackMqConfig,omitempty"`}
请求示例
// 将 examplebucket-1250000000 和 COS_REGION 修改为真实的信息bu, _ := url.Parse("https://examplebucket-1250000000.cos.COS_REGION.myqcloud.com")cu, _ := url.Parse("https://examplebucket-1250000000.ci.COS_REGION.myqcloud.com")b := &cos.BaseURL{BucketURL: bu, CIURL: cu}c := cos.NewClient(b, &http.Client{Transport: &cos.AuthorizationTransport{SecretID: os.Getenv("SECRETID"),SecretKey: os.Getenv("SECRETKEY"),},})createJobOpt := &cos.CreateGeneratePlayListJobOptions{Tag: "GeneratePlayList",Input: &cos.JobInput{Object: "a.mp4",},Operation: &cos.GeneratePlayListJobOperation{Output: &cos.JobOutput{Region: "ap-chongqing",Bucket: "test-1250000000",Object: "live/a.m3u8",},Transcode: &cos.LiveTanscode{Video: &cos.LiveTanscodeVideo{Codec: "H.264",Width: "960", // 设置480、720、960、1080Bitrate: "2000",Maxrate: "5000",Fps: "30",},Container: &cos.Container{Format: "hls",ClipConfig: &cos.ClipConfig{Duration: "5",},},TransConfig: &cos.LiveTanscodeTransConfig{// HlsEncrypt: &cos.HlsEncrypt{// IsHlsEncrypt: true,// },InitialClipNum: "10",CosTag: "a=a&b=b",},},Watermark: []cos.Watermark{{Type: "Text",LocMode: "Absolute",Dx: "640",Pos: "TopLeft",Text: &cos.Text{Text: "helloworld",FontSize: "25",FontType: "simfang.ttf",FontColor: "0xff0000",Transparency: "100",},},},},}createJobRes, _, err := c.CI.CreateGeneratePlayListJob(context.Background(), createJobOpt)log_status(err)fmt.Printf("%+v\\n", createJobRes.JobsDetail)
获取边转边播播放地址
获取未加密场景的播放地址
type URLToken struct {SessionToken string `url:"x-cos-security-token,omitempty" header:"-"`}// https://github.com/tencentyun/cos-go-sdk-v5/blob/master/example/CI/media_process/livetranscode.gofunc GetCOSDomainURL(tak string, tsk string, token *URLToken, appId string, bucketId string, region string, objectKey string) string {u, _ := url.Parse("https://" + bucketId + ".cos." + region + ".myqcloud.com")b := &cos.BaseURL{BucketURL: u}c := cos.NewClient(b, &http.Client{Transport: &cos.AuthorizationTransport{SecretID: tak,SecretKey: tsk,SessionToken: token.SessionToken,},})ctx := context.Background()opt := &cos.PresignedURLOptions{Query: &url.Values{},Header: &http.Header{},}opt.Query.Add("ci-process", "getplaylist")opt.Query.Add("signType", "cos")opt.Query.Add("expires", "43200")// opt.Query.Add("exper", "30") 试看时长var signHost bool = true// 获取预签名presignedURL, err := c.Object.GetPresignedURL2(ctx, http.MethodGet, objectKey, time.Hour, opt, signHost)if err != nil {fmt.Printf("Error: %v\\n", err)return ""}resultUrl := presignedURL.String()return resultUrl}// CDN域名func GetCDNDomainURL(cdn string, objectKey string) string {url := cdn + "/" + objectKeyresultUrl := url + "?ci-process=getplaylist&signType=no"return resultUrl}func main() {// 替换成您的密钥tak := os.Getenv("COS_SECRETID")tsk := os.Getenv("COS_SECRETKEY")token := &URLToken{SessionToken: "",}// 替换成您的桶名称appId := "1250000000"// 替换成您的桶名称bucketId := "test-1250000000"// 替换成您桶所在的 regionregion := "ap-chongqing"// 替换成您需要播放的视频名称objectKey := "live/a.m3u8"playUrl := ""playUrl = GetCOSDomainURL(tak, tsk, token, appId, bucketId, region, objectKey)fmt.Println(playUrl)// 替换为自己 cdn 域名cdn := "http://abc.cdn.com"playUrl = GetCDNDomainURL(cdn, objectKey)fmt.Println(playUrl)}
获取加密场景的播放地址
type URLToken struct {SessionToken string `url:"x-cos-security-token,omitempty" header:"-"`}type JwtTokens struct {// base infoType string `json:"Type"`AppId string `json:"AppId"`BucketId string `json:"BucketId"`Object string `json:"Object"`Issuer string `json:"Issuer"`// time infoIssuedTimeStamp int64 `json:"IssuedTimeStamp"`ExpireTimeStamp int64 `json:"ExpireTimeStamp"`// other infoRandom int64 `json:"Random"`// times infoUsageLimit int `json:"UsageLimit"`// secret infoProtectSchema string `json:"ProtectSchema"`PublicKey string `json:"PublicKey"`ProtectContentKey int `json:"ProtectContentKey"`}func (token JwtTokens) Valid() error {return nil}// 生成jwtfunc GenerateToken(appId string, bucketId string, objectKey string, secret []byte) (string, error) {t := time.Now()now := t.Unix()payLoad := JwtTokens{// 固定为 CosCiToken, 必填参数Type: "CosCiToken",// app id,必填参数AppId: appId,// 播放文件所在的 BucketId, 必填参数BucketId: bucketId,// 播放文件名Object: url.QueryEscape(objectKey),// 固定为 client,必填参数Issuer: "client",// token 颁发时间戳,必填参数IssuedTimeStamp: now,// token 过期时间戳,非必填参数,默认1天过期ExpireTimeStamp: t.Add(time.Hour * 24 * 6).Unix(),// token 使用次数限制,非必填参数,默认限制100次UsageLimit: 20,// 保护模式,填写为 rsa1024 ,则表示使用 RSA 非对称加密的方式保护,公私钥对长度为1024 bitProtectSchema: "rsa1024",// 公钥。1024 bit 的 RSA 公钥,需使用 Base64进行编码PublicKey: "xxx",// 是否加密解密密钥(播放时解密 ts 视频流的密钥),1表示对解密密钥加密,0表示不对解密密钥加密。ProtectContentKey: 0,}//使用指定的签名方法创建签名对象token := jwt.NewWithClaims(jwt.SigningMethodHS256, payLoad)//使用指定的 secret 签名并获得完成的编码后的字符串 tokenreturn token.SignedString(secret)}// COS环境func GetCOSDomainVideoEncryptionURL(tak string, tsk string, token *URLToken, bucketId string, region string, objectKey string, jwtToken string) string {u, _ := url.Parse("https://" + bucketId + ".cos." + region + ".myqcloud.com")b := &cos.BaseURL{BucketURL: u}c := cos.NewClient(b, &http.Client{Transport: &cos.AuthorizationTransport{SecretID: tak,SecretKey: tsk,SessionToken: token.SessionToken,},})ctx := context.Background()opt := &cos.PresignedURLOptions{Query: &url.Values{},Header: &http.Header{},}opt.Query.Add("ci-process", "getplaylist")opt.Query.Add("signType", "cos")opt.Query.Add("expires", "43200")// opt.Query.Add("exper", "30") 试看时长opt.Query.Add("tokenType", "JwtToken")opt.Query.Add("token", jwtToken)var signHost bool = true// 获取预签名presignedURL, err := c.Object.GetPresignedURL2(ctx, http.MethodGet, objectKey, 10*time.Hour, opt, signHost)if err != nil {fmt.Printf("Error: %v\\n", err)return ""}resultUrl := presignedURL.String()return resultUrl}// CDN域名func GetCDNDomainVideoEncryptionURL(cdn string, objectKey string, jwtToken string) string {url := cdn + "/" + objectKeyresultUrl := url + "?ci-process=getplaylist&signType=no&expires=43200&&tokenType=JwtToken&token=" + jwtTokenreturn resultUrl}func main() {// 替换成您的密钥tak := os.Getenv("COS_SECRETID")tsk := os.Getenv("COS_SECRETKEY")token := &URLToken{SessionToken: "",}// 替换成您的桶名称appId := "1250000000"// 替换成您的桶名称bucketId := "test-1250000000"// 替换成您桶所在的 regionregion := "ap-chongqing"// 替换成您需要播放的视频名称objectKey := "live/a.m3u8"// 替换为自己 cdn 域名cdn := "http://abc.cdn.com"// 替换为自己播放密钥,控制台可以查询var playkey = []byte("aaaaaaaaaaa")// 生成tokenjwtToken, _ := GenerateToken(appId, bucketId, objectKey, playkey)playUrl := ""playUrl = GetCOSDomainVideoEncryptionURL(tak, tsk, token, bucketId, region, objectKey, jwtToken)fmt.Println(playUrl)playUrl = GetCDNDomainVideoEncryptionURL(cdn, objectKey, jwtToken)fmt.Println(playUrl)}
播放地址使用
SDK 代码完整示例
注意:
执行代码前建议执行以下命令安装最新的第三方依赖库:
go get -u github.com/golang-jwt/jwt/v5