内网上传

最近更新时间:2025-08-04 21:19:11

我的收藏
本文主要提供专业版应用内网上传指引。

适用场景

开发者可通过腾讯云资源内网上传文件至同地域的专业版存储。
云点播专业版支持通过腾讯云内网访问存储文件。客户可使用腾讯云资源内网访问相同地域的云点播专业版存储;内网访问时,上传和下载文件均不会产生流量费用。

上传方式

内网上传支持方式如下:
上传方式
上传域名
上传凭证
支持操作
存储桶内网预置域名
[BucketId].vodsrc-internal.[存储地域].eovod.com
永久密钥
上传至指定存储桶

存储桶内网预置域名

专业版应用为每个存储桶预置了一个内网域名,客户可使用该域名在腾讯云服务器通过内网上传文件至相同地域的存储桶。

使用永久密钥通过 AWS S3 SDK 上传文件

下面介绍在常用的编程语言中,如何进行适配以上传文件至专业版应用的存储桶。
假设专业版应用 ID 为 1234567890 ,存储桶的存储地域为 ap-guangzhou,存储桶 ID 为 bucketid1
本实例使用的存储桶内网访问域名为: bucketid1.vodsrc-internal.ap-guangzhou.eovod.com

准备工作

1. 创建专业版应用和存储桶
云点播控制台 创建好专业版应用和存储桶,具体操作步骤参见 快速入门创建存储桶 文档。
2. 获取应用级别永久密钥对
从专业版应用的密钥管理中,获取密钥对 AccessKeyIdSecretAccessKey,具体操作步骤参见 密钥管理 文档。
3. 验证当前是否是内网访问
内网域名必须在与存储桶相同地域的腾讯云服务器上才能访问,否则会得到404响应码。可以尝试在服务器上使用 nslookups等指令进行域名解析,若得到形如 10.*.*.*100.*.*.*169.254.*.*等形式的 IP,则一般可以进行内网访问。

上传示例

常用语言初始化 S3 客户端并上传文件,代码实现如下所示:
GO
Java
C++
Python
// Package main
// 本示例基于 AWS SDK for Go v2 service/s3 v1.72.3 实现。
// AWS SDK for Go v2 service/s3 v1.73.0 及以后版本需禁用 S3 的默认完整性保护。
// 具体参考: https://github.com/aws/aws-sdk-go-v2/discussions/2960
package main

import (
"context"
"errors"
"fmt"
"log"
"net/url"
"os"

"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/feature/s3/manager"
"github.com/aws/aws-sdk-go-v2/service/s3"
smep "github.com/aws/smithy-go/endpoints"
"github.com/aws/smithy-go/logging"
)


// customEndpointResolverV2 自定义接入点
type customEndpointResolverV2 struct{}

// ResolveEndpoint 自定义接入点
func (r *customEndpointResolverV2) ResolveEndpoint(ctx context.Context,
params s3.EndpointParameters) (smep.Endpoint, error) {
if params.Bucket == nil || params.Region == nil {
return smep.Endpoint{}, errors.New("invalid endpoint param")
}
return smep.Endpoint{
URI: url.URL{
Scheme: "http",
Host: fmt.Sprintf("%s.vodsrc-internal.ap-guangzhou.eovod.com", *params.Bucket),
},
}, nil
}

func main() {
// new s3 client
s3cli := s3.New(s3.Options{
Credentials: credentials.NewStaticCredentialsProvider(
"AccessKeyId", // 填入密钥对中的 AccessKeyId
"SecretAccessKey", // 填入密钥对中的 SecretAccessKey
""), // 永久密钥无需填充 SessionToken
EndpointResolverV2: new(customEndpointResolverV2), // 自定义接入点
UsePathStyle: false, // 请求禁用 path style
Logger: logging.NewStandardLogger(os.Stdout), // 日志打印到标准输出流
ClientLogMode: aws.LogRequest | aws.LogResponse, // 打印请求头和响应头
Region: "auto", // 固定填写 auto
})

// 打开本地文件
file, err := os.Open("demo.mp4") // 本地文件路径
if err != nil {
log.Fatalf("failed to open file: %v", err)
return
}
defer file.Close()

// 上传文件到 S3
// 创建上传器
uploader := manager.NewUploader(s3cli, func(u *manager.Uploader) {
u.PartSize = 10 * 1024 * 1024 // 设置分片大小为 10MB
u.Concurrency = 5 // 设置并发上传的分片数
})
// 上传文件
result, err := uploader.Upload(context.TODO(), &s3.PutObjectInput{
Bucket: aws.String("bucketid1"), // Bucket 设置为点播专业版应用中的存储桶 ID
Key: aws.String("upload/demo.mp4"), // 媒体文件在存储桶中的路径
Body: file,
})

if err != nil {
log.Fatalf("failed to upload file: %v", err)
return
}
log.Printf("etag: %s", *result.ETag) // 获取上传文件 etag
}
// 本示例基于 AWS SDK for Java v2 service/s3 v2.31.35 实现。
// AWS SDK for Java 2.30.0 及以后版本需禁用 S3 的默认完整性保护。
// 具体参考: https://github.com/aws/aws-sdk-java-v2/issues/5801
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.S3Configuration;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.UploadFileRequest;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;
import software.amazon.awssdk.core.checksums.RequestChecksumCalculation;
import software.amazon.awssdk.core.checksums.ResponseChecksumValidation;

import java.io.File;
import java.net.URI;
import java.util.concurrent.CompletableFuture;

public class Main {
public static void main(String[] args) {
S3AsyncClient s3AsyncClient = null;
S3TransferManager transferManager = null;

try {
// 专业版应用永久密钥 AccessKeyId
AwsBasicCredentials credentials = AwsBasicCredentials.create(
"AccessKeyId", // 专业版应用永久密钥 AccessKeyId
"SecretAccessKey" // 专业版应用永久密钥 SecretAccessKey
);
String region = "ap-guangzhou"; // 专业版应用存储桶地域
String bucketId = "bucketid1"; // 专业版应用存储桶ID
String filePath = "demo.mp4"; // 本地文件路径
String key = "upload/demo.mp4"; // 文件在存储桶中的路径
String endpointUrl = String.format("http://vodsrc-internal.%s.eovod.com", region); // 桶级别预置域名端点

// 使用自定义端点构建S3异步客户端
s3AsyncClient = S3AsyncClient.builder()
.credentialsProvider(StaticCredentialsProvider.create(credentials)) // 设置凭证提供者
.endpointOverride(URI.create(endpointUrl)) // 设置端点
.region(Region.of("auto")) // 设置区域 auto 自动选择
.httpClient(NettyNioAsyncHttpClient.builder().build()) // 设置HTTP客户端
.serviceConfiguration(S3Configuration.builder()
.pathStyleAccessEnabled(false) // 设置路径样式访问, 桶级别需明确禁用 PathStyle 模式
.build())
.requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED)
.responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED)
.build();

// 使用S3异步客户端创建S3TransferManager
transferManager = S3TransferManager.builder()
.s3Client(s3AsyncClient)
.build();

File fileToUpload = new File(filePath);

// 创建上传请求并添加传输监听器用于进度跟踪
UploadFileRequest uploadRequest = UploadFileRequest.builder()
.putObjectRequest(builder -> builder
.bucket(bucketId)
.key(key))
.addTransferListener(LoggingTransferListener.create())
.source(fileToUpload)
.build();

// 开始上传
CompletableFuture<Void> future = transferManager.uploadFile(uploadRequest)
.completionFuture()
.thenAccept(response -> {
System.out.println("上传成功! ETag: " + response.response().eTag());
});

// 等待上传完成
future.join();

System.out.println("上传任务完成");
} catch (Exception e) {
System.err.println("上传失败: " + e.getMessage());
e.printStackTrace();
} finally {
// 资源释放
try {
if (transferManager != null) {
transferManager.close();
}
if (s3AsyncClient != null) {
s3AsyncClient.close();
}
System.out.println("资源已释放");
} catch (Exception e) {
System.err.println("关闭资源时发生错误: " + e.getMessage());
}
}
}
}
// 本示例基于 AWS SDK for C++ v1.11.560 实现。
// AWS SDK for C++ v1.11.486 及以后版本需禁用 S3 的默认完整性保护。
// 具体参考: https://github.com/aws/aws-sdk-cpp/issues/3253
#include <aws/core/Aws.h>
#include <aws/core/auth/AWSCredentials.h>
#include <aws/core/client/ClientConfiguration.h>
#include <aws/s3/S3Client.h>
#include <aws/transfer/TransferManager.h>
#include <iostream>

int main()
{
// AWS SDK 初始化
Aws::SDKOptions options;
options.loggingOptions.logLevel = Aws::Utils::Logging::LogLevel::Info;
Aws::InitAPI(options);

{
// 定义认证和端点信息
const Aws::String accessKeyId = "AccessKeyId"; // 填入点播专业版密钥对中的 AccessKeyId
const Aws::String secretAccessKey = "SecretAccessKey"; // 填入点播专业版密钥对中的 SecretAccessKey
const Aws::String region = "ap-guangzhou"; // 存储桶所在地域
const Aws::String bucketId = "bucketid1"; // 点播专业版应用中的存储桶 ID
const Aws::String keyName = "upload/demo.mp4"; // 文件在存储桶中的路径
const Aws::String filePath = "demo.mp4"; // 本地文件路径

// 配置客户端
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region = "auto"; // 固定填写 auto
clientConfig.scheme = Aws::Http::Scheme::HTTP; // 协议使用 HTTP
clientConfig.enableEndpointDiscovery = false; // 禁用 endpoint discovery
clientConfig.verifySSL = true; // 启用 SSL 证书验证
clientConfig.endpointOverride = "vodsrc-internal." + region + ".eovod.com"; // 桶级别预置域名
// 禁用完整性校验
clientConfig.checksumConfig.requestChecksumCalculation = Aws::Client::RequestChecksumCalculation::WHEN_REQUIRED;
clientConfig.checksumConfig.responseChecksumValidation = Aws::Client::ResponseChecksumValidation::WHEN_REQUIRED;

// 设置认证信息
Aws::Auth::AWSCredentials credentials(accessKeyId, secretAccessKey); // 填入点播专业版永久密钥

// 创建 S3 客户端
auto s3Client = Aws::MakeShared<Aws::S3::S3Client>(
"S3Client",
credentials,
clientConfig,
Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never, // 禁用 payload signing
true // 桶级别预置域名需明确使用 VirtualAddressing
);

// 创建线程池执行器
auto executor = Aws::MakeShared<Aws::Utils::Threading::PooledThreadExecutor>("executor", 10);

// 配置 TransferManager
Aws::Transfer::TransferManagerConfiguration transferConfig(executor.get());
transferConfig.s3Client = s3Client;

// 设置分片大小为 10MB
transferConfig.bufferSize = 10 * 1024 * 1024;

// 创建 TransferManager
auto transferManager = Aws::Transfer::TransferManager::Create(transferConfig);

std::cout << "Starting file upload: " << filePath << " to " << bucketId << "/" << keyName << std::endl;

// 执行上传
auto uploadHandle = transferManager->UploadFile(
filePath, // 本地文件路径
bucketId, // 存储桶ID
keyName, // 对象键(存储路径)
"application/octet-stream", // 内容类型
Aws::Map<Aws::String, Aws::String>() // 元数据
);

// 等待上传完成
uploadHandle->WaitUntilFinished();

// 检查上传状态
if (uploadHandle->GetStatus() == Aws::Transfer::TransferStatus::COMPLETED)
{
std::cout << "File upload completed successfully!" << std::endl;
}
else
{
auto lastError = uploadHandle->GetLastError();
std::cerr << "File upload failed: " << lastError.GetMessage() << std::endl;
}
}

// 清理SDK资源
Aws::ShutdownAPI(options);
return 0;
}
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
本示例基于 AWS SDK for Python v1.38.7 实现。
Boto3 的 AWS SDK for Python v1.36.0 及以后版本需禁用 S3 的默认完整性保护。
具体参考: https://github.com/boto/boto3/issues/4392
"""

import boto3
from botocore.config import Config
from botocore.exceptions import ClientError

# 常量定义
REGION = "ap-guangzhou" # 存储桶地域
BUCKET_ID = "bucketid1" # 填入点播专业版应用中的存储桶 ID
FILE_PATH = "demo.mp4" # 本地文件路径
OBJECT_KEY = "upload/demo.mp4" # 文件在存储桶中的路径

# 创建 S3 客户端
s3_client = boto3.client(
"s3",
aws_access_key_id="AccessKeyId", # 填入密钥对中的 AccessKeyId
aws_secret_access_key="SecretAccessKey", # 填入密钥对中的 SecretAccessKey
endpoint_url=f"http://vodsrc-internal.{REGION}.eovod.com", # 桶级别预置上传域名
config=Config(
s3={"addressing_style": "virtual"}, # 使用 virtual hosted-style
request_checksum_calculation="when_required", # Boto3 的 AWS SDK for Python v1.36.0 及以后版本需禁用 S3 的默认完整性保护。
response_checksum_validation="when_required", # Boto3 的 AWS SDK for Python v1.36.0 及以后版本需禁用 S3 的默认完整性保护。
),
)

try:
# 上传文件
response = s3_client.upload_file(
Bucket=BUCKET_ID, # 填入点播专业版应用中的存储桶 ID
Key=OBJECT_KEY, # 文件在存储桶中的路径
Filename=FILE_PATH, # 本地文件路径
)
print(response)
except ClientError as e:
print(f"Error: {e}")
注意:
使用 AWS SDK 请确认数据完整性保护特性,详情请参考 AWS SDK 的相关文档 Data Integrity Protections for Amazon S3。
使用存储桶预置公网域名,路径必须为 VirtualStyle 格式。