云点播 客户端上传指引(客户端上传)

这篇说说腾讯云点播专业版应用客户端上传指引,推荐使用临时凭证通过预置域名上传,并详细说明服务端申请凭证流程及多语言SDK代码示例。 上传方式:支持存储桶预置域名和应用预置域名两种方式,均使用临时凭证。 服务端流程:调用申请上传临时凭证接口,为客户端派发临时凭证。 客户端上传:使用获取的临时凭证,通过VOD SDK将文件上传至专业版存储。

相关产品
云点播 产品页,含版本规格、价格与购买入口。

这篇主要提供专业版应用客户端上传指引。

一、适用场景

终端用户将客户端本地视频上传到云点播,适用于 UGC、PGC 等场景。

二、上传方式

客户端对密钥安全性要求较高,我们推荐通过专业版预置域名使用临时凭证上传,支持方式如下:

上传方式 上传域名 上传凭证 支持操作
存储桶预置域名 [BucketId].vodpro.[存储地域].eovod.com 临时凭证 上传至指定存储桶
应用预置域名 [SubAppId].vodpro-upload.com 临时凭证 上传至指定存储桶就近上传至应用内某区域的存储桶

三、使用临时凭证上传文件

临时凭证通常用于对密钥安全性要求较高的场景。客户端使用临时凭证上传文件至专业版存储整体流程如下:

1. 申请上传临时凭证

1.1 客户端向 App 后台申请上传临时凭证。

1.2 服务端调用云点播专业版服务 申请上传临时凭证。

2. 上传文件

客户端使用临时凭证上传文件至云点播专业版存储。

四、准备工作

1. 创建专业版应用和存储桶

在 云点播控制台 创建好专业版应用和存储桶,具体操作步骤参见 快速入门 和 创建存储桶 文档。

2. 获取腾讯云账号永久密钥对

2.1 登录腾讯云控制台,选择访问管理 > 访问密钥 > API 密钥管理,进入“API 密钥管理” 页面。

2.2 获取云 API 密钥。如果你尚未创建密钥,则单击新建密钥即可创建一对 SecretId 和 SecretKey。

五、服务端申请上传临时凭证

客户服务端使用 SecretId 和 SecretKey调用 申请上传临时凭证 接口,获取到上传临时凭证后派发给客户端使用。

假设专业版应用 ID 为 1234567890 ,存储桶的存储地域为 ap-guangzhou,存储桶 ID 为 bucketid1。

服务端申请 bucketid1存储桶上传 upload/demo.mp4的临时凭证,实现如下:

GOJavaC++Python// Package mainpackage mainimport ( "context" "encoding/json" "fmt" "log" "net/url" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" vod20240718 "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vod/v20240718")const ( appId = 251000000 // 腾讯云账号 APPID subAppId = 1234567890 // 云点播专业版应用 APPID bucketId = "bucketid1" // 云点播专业版应用存储桶的 ID fileKey = "upload/demo.mp4" // 上传到存储后的文件 KEY,包含完整路径和文件名,例如 upload/demo.mp4)// createStorageCredentialsPolicy 创建存储凭证策略type createStorageCredentialsPolicy struct { Statement []policyStatement `json:"statement"` Version string `json:"version"`}// policyStatement 策略语句type policyStatement struct { Action []string `json:"action"` Effect string `json:"effect"` Resource []string `json:"resource"`}// cred 临时凭证type cred struct { AccessKeyId string SecretAccessKey string SessionToken string}// getCredential 获取临时凭证func getCredential(context.Context) (*cred, error) { // 1. 获取临时凭证 // 1.1 初始化调用腾讯云 API 对象 credential := common.NewCredential( "SecretId", // 腾讯云账号 SecretId "SecretKey", // 腾讯云账号 SecretKey ) prof := profile.NewClientProfile() vodClient, err := vod20240718.NewClient(credential, "ap-guangzhou", prof) if err != nil { log.Fatalf("create VOD client fail: %+v", err) return nil, fmt.Errorf("create VOD client fail: %w", err) } // 1.2 构造申请上传临时凭证请求 policy := createStorageCredentialsPolicy{ Statement: []policyStatement{{ Action: []string{ // 当前仅支持如下 action,可以只申请其中一部分 "name/vod:PutObject", "name/vod:ListParts", "name/vod:PostObject", "name/vod:CreateMultipartUpload", "name/vod:UploadPart", "name/vod:CompleteMultipartUpload", "name/vod:AbortMultipartUpload", "name/vod:ListMultipartUploads", }, Effect: "allow", Resource: []string{ fmt.Sprintf("qcs::vod:%s:uid/%d:prefix//%d/%s/%s", "ap-guangzhou", // 存储桶所在地域 appId, // 腾讯云账号 APPID subAppId, // 云点播专业版应用 APPID bucketId, // 云点播专业版应用存储桶的 ID fileKey, // 上传到存储后的文件 KEY,包含完整路径和文件名,例如 upload/demo.mp4 ), }, }}, Version: "2.0", } req := vod20240718.NewCreateStorageCredentialsRequest() req.SubAppId = common.Uint64Ptr(subAppId) policyStr, _ := json.Marshal(policy) req.Policy = common.StringPtr(url.QueryEscape(string(policyStr))) // 1.3 申请上传临时凭证 resp, err := vodClient.CreateStorageCredentials(req) if err != nil { log.Fatalf("create storage credentials fail: %+v", err) return nil, fmt.Errorf("create storage credentials fail: %w", err) } log.Printf("create storage credentials success: %+v", resp) creds := resp.Response.Credentials return &cred{ AccessKeyId: *creds.AccessKeyId, SecretAccessKey: *creds.SecretAccessKey, SessionToken: *creds.SessionToken, }, nil}import com.tencentcloudapi.common.Credential;import com.tencentcloudapi.common.exception.TencentCloudSDKException;import com.tencentcloudapi.common.profile.ClientProfile;import com.tencentcloudapi.vod.v20240718.VodClient;import com.tencentcloudapi.vod.v20240718.models.CreateStorageCredentialsRequest;import com.tencentcloudapi.vod.v20240718.models.CreateStorageCredentialsResponse;import org.json.JSONArray;import org.json.JSONObject;import java.net.URLEncoder;import java.nio.charset.StandardCharsets;/** * 凭证辅助类,负责获取临时存储凭证 */public class CredentialHelper { // 常量定义 private static final long APP_ID = 251000000; // 腾讯云账号 APPID private static final long SUB_APP_ID = 1234567890; // 云点播专业版应用 APPID private static final String BUCKET_ID = "bucketid1"; // 云点播专业版应用存储桶的 ID private static final String FILE_KEY = "upload/demo.mp4"; // 上传到存储后的文件 KEY private static final String REGION = "ap-guangzhou"; // 存储桶所在地域 /** * 凭证对象,存储临时凭证信息 */ public static class Cred { private final String accessKeyId; private final String secretAccessKey; private final String sessionToken; public Cred(String accessKeyId, String secretAccessKey, String sessionToken) { this.accessKeyId = accessKeyId; this.secretAccessKey = secretAccessKey; this.sessionToken = sessionToken; } public String getAccessKeyId() { return accessKeyId; } public String getSecretAccessKey() { return secretAccessKey; } public String getSessionToken() { return sessionToken; } } /** * 获取临时凭证 * * @return 临时凭证对象 * @throws Exception 如果获取凭证失败 */ public static Cred getCredential() throws Exception { try { // 1. 初始化腾讯云 API 客户端 Credential credential = new Credential("SecretId", "SecretKey"); // 腾讯云账号 SecretId 和 SecretKey ClientProfile clientProfile = new ClientProfile(); // 客户端配置 VodClient vodClient = new VodClient(credential, "ap-guangzhou", clientProfile); // 创建 VodClient 对象 // 2. 构造并编码策略 String policyJson = createPolicyJson(); String encodedPolicy = URLEncoder.encode(policyJson, StandardCharsets.UTF_8.name()); // 3. 创建并发送请求 CreateStorageCredentialsRequest req = new CreateStorageCredentialsRequest(); req.setSubAppId(SUB_APP_ID); // 云点播专业版应用 APPID req.setPolicy(encodedPolicy); // 策略 // 4. 获取响应并返回凭证 CreateStorageCredentialsResponse resp = vodClient.CreateStorageCredentials(req); return new Cred( resp.getCredentials().getAccessKeyId(), resp.getCredentials().getSecretAccessKey(), resp.getCredentials().getSessionToken()); } catch (TencentCloudSDKException e) { System.err.println("获取存储凭证失败: " + e.getMessage()); throw new Exception("获取存储凭证失败", e); } } /** * 创建策略JSON字符串,使用 org.json 库 * * @return 策略JSON字符串 */ private static String createPolicyJson() { // 构建资源路径 String resource = String.format( "qcs::vod:%s:uid/%d:prefix//%d/%s/%s", REGION, APP_ID, SUB_APP_ID, BUCKET_ID, FILE_KEY); // 构建操作列表 String[] actions = { "name/vod:PutObject", "name/vod:ListParts", "name/vod:PostObject", "name/vod:CreateMultipartUpload", "name/vod:UploadPart", "name/vod:CompleteMultipartUpload", "name/vod:AbortMultipartUpload", "name/vod:ListMultipartUploads" }; // 使用 JSONObject 构建 JSON JSONObject policy = new JSONObject(); policy.put("version", "2.0"); JSONArray statements = new JSONArray(); JSONObject statement = new JSONObject(); JSONArray actionArray = new JSONArray(); for (String action : actions) { actionArray.put(action); } statement.put("action", actionArray); statement.put("effect", "allow"); JSONArray resources = new JSONArray(); resources.put(resource); statement.put("resource", resources); statements.put(statement); policy.put("statement", statements); return policy.toString(); }}#include <tencentcloud/core/TencentCloud.h>#include <tencentcloud/core/profile/ClientProfile.h>#include <tencentcloud/core/profile/HttpProfile.h>#include <tencentcloud/core/Credential.h>#include <tencentcloud/vod/v20240718/VodClient.h>#include <tencentcloud/vod/v20240718/model/CreateStorageCredentialsRequest.h>#include <tencentcloud/vod/v20240718/model/CreateStorageCredentialsResponse.h>#include <string>#include <sstream>#include <iomanip>#include <iostream>#include <nlohmann/json.hpp>using json = nlohmann::json;const uint64_t APP_ID = 251000000; // 腾讯云账号 APPIDconst uint64_t SUB_APP_ID = 1234567890; // 云点播专业版应用 APPIDconst std::string BUCKET_ID = "bucketid1"; // 云点播专业版应用存储桶的 IDconst std::string REGION = "ap-guangzhou"; // 云点播专业版应用存储桶地域const std::string OBJECT_KEY = "upload/demo.mp4"; // 申请权限的存储文件 KEY// 凭证结构体struct Credential{ std::string accessKeyId; std::string secretAccessKey; std::string sessionToken;};// URL 编码函数std::string UrlEncode(const std::string &value){ std::ostringstream escaped; escaped.fill('0'); escaped << std::hex; for (char c : value) { if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { escaped << c; } else { escaped << std::uppercase; escaped << '%' << std::setw(2) << int((unsigned char)c); escaped << std::nouppercase; } } return escaped.str();}// 获取临时凭证Credential GetCredential(){ // 初始化腾讯云 SDK TencentCloud::InitAPI(); // 创建 VOD 客户端 TencentCloud::Credential credential("SecretId", "SecretKey"); // 填入腾讯云账号 SecretId 和 SecretKey TencentCloud::HttpProfile httpProfile; TencentCloud::ClientProfile clientProfile; clientProfile.SetHttpProfile(httpProfile); TencentCloud::Vod::V20240718::VodClient client(credential, "ap-guangzhou", clientProfile); // 构建策略 json policy_json = { {"statement", {{{"action", {"name/vod:PutObject", "name/vod:ListParts", "name/vod:PostObject", "name/vod:CreateMultipartUpload", "name/vod:UploadPart", "name/vod:CompleteMultipartUpload", "name/vod:AbortMultipartUpload", "name/vod:ListMultipartUploads"}}, {"effect", "allow"}, {"resource", {"qcs::vod:" + REGION + ":uid/" + std::to_string(APP_ID) + ":prefix//" + std::to_string(SUB_APP_ID) + "/" + BUCKET_ID + "/" + OBJECT_KEY}}}}}, {"version", "2.0"}}; std::string policy = policy_json.dump(); // 创建请求对象 TencentCloud::Vod::V20240718::Model::CreateStorageCredentialsRequest req; req.SetSubAppId(SUB_APP_ID); req.SetPolicy(UrlEncode(policy)); // 发送请求 auto outcome = client.CreateStorageCredentials(req); if (!outcome.IsSuccess()) { std::cerr << "Failed to get storage credentials: " << outcome.GetError().GetErrorMessage() << std::endl; TencentCloud::ShutdownAPI(); exit(1); } // 提取凭证 auto response = outcome.GetResult(); auto creds = response.GetCredentials(); Credential result; result.accessKeyId = creds.GetAccessKeyId(); result.secretAccessKey = creds.GetSecretAccessKey(); result.sessionToken = creds.GetSessionToken(); // 清理腾讯云 SDK TencentCloud::ShutdownAPI(); return result;}#!/usr/bin/env python3# -*- coding: utf-8 -*-import jsonimport urllib.parsefrom typing import NamedTuplefrom tencentcloud.common import credentialfrom tencentcloud.common.profile import client_profilefrom tencentcloud.vod.v20240718 import vod_client, models# 常量定义APP_ID = 251000000 # 腾讯云账号 APPIDSUB_APP_ID = 1234567890 # 云点播专业版应用 APPIDBUCKET_ID = "bucketid1" # 云点播专业版应用存储桶的 IDOBJECT_KEY = "upload/demo.mp4" # 上传到存储后的文件 KEYREGION = "ap-guangzhou" # 地域class Credential(NamedTuple): """临时凭证""" access_key_id: str secret_access_key: str session_token: strdef get_credential() -> Credential: """获取临时凭证""" # 1. 初始化调用腾讯云 API 对象 cred = credential.Credential( "SecretId", # 腾讯云账号 SecretId "SecretKey", # 腾讯云账号 SecretKey ) prof = client_profile.ClientProfile() vod_cli = vod_client.VodClient(cred, "ap-guangzhou", prof) # 2. 构造申请上传临时凭证请求 policy = { "statement": [ { "action": [ "name/vod:PutObject", "name/vod:ListParts", "name/vod:PostObject", "name/vod:CreateMultipartUpload", "name/vod:UploadPart", "name/vod:CompleteMultipartUpload", "name/vod:AbortMultipartUpload", "name/vod:ListMultipartUploads", ], "effect": "allow", "resource": [f"qcs::vod:{REGION}:uid/{APP_ID}:prefix//{SUB_APP_ID}/{BUCKET_ID}/{OBJECT_KEY}"], } ], "version": "2.0", } req = models.CreateStorageCredentialsRequest() req.SubAppId = SUB_APP_ID req.Policy = urllib.parse.quote(json.dumps(policy)) # 3. 申请上传临时凭证 resp = vod_cli.CreateStorageCredentials(req) creds = resp.Credentials return Credential( access_key_id=creds.AccessKeyId, secret_access_key=creds.SecretAccessKey, session_token=creds.SessionToken, )

六、使用 SDK 上传文件

下面介绍在常用的客户端 SDK 中,如何进行适配以上传文件至专业版应用的存储桶。

七、域名

专业版为每个应用预置了一个上传加速域名,应用下所有存储桶均可使用该域名进行上传。

示例使用的应用上传加速域名均为:1234567890.vodpro-upload.com。

八、使用 VOD SDK 上传文件

App 客户端使用获取到的临时凭证,将文件上传至云点播专业版存储,详情参见:Flutter 上传 SDK。

赞 (0)
上一篇 4天前
下一篇 4天前