前期准备
开始操作前,确保您已经完成了 SDK 初始化。如果您还没有初始化 SDK,请先参考快速入门文档完成。
注意:
媒体与 HLS 相关接口需要 space_admin 或 admin 权限。
视频转码(createTranscodeTask)为异步任务,返回 taskId,需通过任务管理接口轮询执行结果。
m3u8 上传采用「准备 → 上传分片 → 确认 → (可选)续期/追加」的多步流程,请按本文档说明的顺序编排。
查询媒体文件元信息
功能说明
getMediaFileInfo 用于查询媒体文件的元信息,包括分辨率、码率、时长和可用的转码模板。使用示例
import com.tencent.cloud.smh.ApiException;import com.tencent.cloud.smh.ApiResponse;import com.tencent.cloud.smh.api.HlsApi;import com.tencent.cloud.smh.model.GetMediaFileInfo200Response;import java.math.BigDecimal;try {HlsApi.APIGetMediaFileInfoRequest request = HlsApi.APIGetMediaFileInfoRequest.newBuilder().libraryId("your-library-id").spaceId("your-space-id").filePath("/videos/movie.mp4").info(1).accessToken("your-access-token").build();ApiResponse<Object> apiResponse = client.hls().getMediaFileInfoWithHttpInfo(request);if (apiResponse.getStatusCode() == 200) {GetMediaFileInfo200Response result = (GetMediaFileInfo200Response) apiResponse.getData();System.out.println("Resolution: " + result.getWidth() + "x" + result.getHeight());System.out.println("Bitrate: " + result.getBitrate() + " kbps");System.out.println("Duration: " + result.getDuration() + " s");System.out.println("Allowed templates: " + result.getAllowedTranscodingTemplates());}} catch (ApiException e) {System.err.println("Error: " + e.getCode() + " - " + e.getMessage());}
参数说明
参数名 | 参数描述 | 类型 | 是否必填 |
libraryId | 媒体库 ID | String | 是 |
spaceId | 空间 ID,如果媒体库为单租户模式,则该参数固定为连字符(-);如果媒体库为多租户模式,则必须指定该参数 | String | 是 |
filePath | 媒体文件路径 | String | 是 |
info | 固定值1,表示查询媒体文件元信息 | BigDecimal | 是 |
accessToken | 访问令牌;对于公有读媒体库或租户空间可不指定,否则需通过本参数传入或提前调用 client.withToken() 注入,二者取一 | String | 否 |
返回值说明
HTTP 状态码:200,查询成功。
字段 | 说明 | 类型 |
width | 视频宽度,单位 px,字符串格式 | String |
height | 视频高度,单位 px,字符串格式 | String |
bitrate | 码率,单位 kbps,字符串格式 | String |
duration | 时长,单位秒,字符串格式 | String |
allowedTranscodingTemplates | 允许使用的转码模板列表 | List<String> |
视频转码
功能说明
createTranscodeTask 用于发起视频转码任务,将视频转码为指定分辨率的 HLS 格式。转码为异步任务,返回 taskId,需通过任务管理接口轮询执行结果。使用示例
import com.tencent.cloud.smh.ApiException;import com.tencent.cloud.smh.ApiResponse;import com.tencent.cloud.smh.api.HlsApi;import com.tencent.cloud.smh.model.CreateTranscodeTaskRequest;import com.tencent.cloud.smh.model.CreateTranscodeTask200Response;import java.math.BigDecimal;CreateTranscodeTaskRequest transcodeBody = new CreateTranscodeTaskRequest().transcodingTemplateId(CreateTranscodeTaskRequest.TranscodingTemplateIdEnum.H264_720P);try {HlsApi.APICreateTranscodeTaskRequest request = HlsApi.APICreateTranscodeTaskRequest.newBuilder().libraryId("your-library-id").spaceId("your-space-id").filePath("/videos/movie.mp4").transcode(1).accessToken("your-access-token").createTranscodeTaskRequest(transcodeBody).build();ApiResponse<Object> apiResponse = client.hls().createTranscodeTaskWithHttpInfo(request);if (apiResponse.getStatusCode() == 200) {CreateTranscodeTask200Response result = (CreateTranscodeTask200Response) apiResponse.getData();System.out.println("Transcode task submitted, taskId: " + result.getTaskId());// 通过任务管理接口轮询转码结果}} catch (ApiException e) {System.err.println("Error: " + e.getCode() + " - " + e.getMessage());}
参数说明
参数名 | 参数描述 | 类型 | 是否必填 |
libraryId | 媒体库 ID | String | 是 |
spaceId | 空间 ID | String | 是 |
filePath | 源视频文件路径 | String | 是 |
transcode | 固定值1,表示视频转码 | BigDecimal | 是 |
createTranscodeTaskRequest | 转码请求对象 | CreateTranscodeTaskRequest | 是 |
accessToken | 访问令牌;对于公有读媒体库或租户空间可不指定,否则需通过本参数传入或提前调用 client.withToken() 注入,二者取一 | String | 否 |
CreateTranscodeTaskRequest 对象说明
字段 | 参数描述 | 类型 | 是否必填 |
transcodingTemplateId | 转码模板:h264_360p(流畅)、h264_480p(低清)、h264_720p(高清)、h264_1080p(超清)、h264_2K、h264_4K;不允许大于原视频分辨率 | String | 是 |
返回值说明
HTTP 状态码:200,转码任务已提交。
字段 | 说明 | 类型 |
taskId | 异步转码任务 ID | Long |
实时转码(边转边播)
功能说明
liveTranscodeMediaFile 用于实时转码并获取播放列表,服务端通过 HTTP 302 重定向到真实的 m3u8 播放地址,可实现边转边播。默认情况下 SDK 自动跟随重定向。如需获取 Location 中的 URL 而非跟随跳转,请先调用 client.setFollowRedirects(HttpClient.Redirect.NEVER),再从 ApiException 的响应头中读取(302 按非 2xx 抛出)。仅支持将非 HLS 源文件转为 HLS 播放,不支持符号链接和历史版本。使用示例
import com.tencent.cloud.smh.ApiException;import com.tencent.cloud.smh.ApiResponse;import com.tencent.cloud.smh.api.HlsApi;import java.math.BigDecimal;try {HlsApi.APILiveTranscodeMediaFileRequest request = HlsApi.APILiveTranscodeMediaFileRequest.newBuilder().libraryId("your-library-id").spaceId("your-space-id").filePath("/videos/movie.mp4").liveTranscode(1).transcodingTemplateId("h264_720p").accessToken("your-access-token").build();// 302 重定向到真实 m3u8 地址,SDK 返回 voidApiResponse<Object> apiResponse = client.hls().liveTranscodeMediaFileWithHttpInfo(request);System.out.println("Status code: " + apiResponse.getStatusCode());} catch (ApiException e) {System.err.println("Error: " + e.getCode() + " - " + e.getMessage());}
参数说明
参数名 | 参数描述 | 类型 | 是否必填 |
libraryId | 媒体库 ID | String | 是 |
spaceId | 空间 ID | String | 是 |
filePath | 源视频文件路径 | String | 是 |
liveTranscode | 固定值1,表示实时转码 | BigDecimal | 是 |
transcodingTemplateId | 转码模板,同视频转码接口 | String | 是 |
accessToken | 访问令牌;对于公有读媒体库或租户空间可不指定,否则需通过本参数传入或提前调用 client.withToken() 注入,二者取一 | String | 否 |
下载转码后的视频
功能说明
downloadTranscodedVideo 用于下载转码后的视频。如果 m3u8 转封装未完成会返回 FileConverting 错误;如果转码任务未完成,会返回原始视频的下载链接。本接口在 FileApi 中。默认情况下 SDK 自动跟随重定向。如需获取 Location 中的 URL 而非跟随跳转,请先调用 client.setFollowRedirects(HttpClient.Redirect.NEVER),再从 ApiException 的响应头中读取(302 按非 2xx 抛出)。使用示例
import com.tencent.cloud.smh.ApiException;import com.tencent.cloud.smh.ApiResponse;import com.tencent.cloud.smh.api.FileApi;try {FileApi.APIDownloadTranscodedVideoRequest request = FileApi.APIDownloadTranscodedVideoRequest.newBuilder().libraryId("your-library-id").spaceId("your-space-id").filePath("/videos/movie.mp4").transcodingTemplateId("h264_720p").accessToken("your-access-token").build();// 302 重定向到下载地址,SDK 返回 voidApiResponse<Object> apiResponse = client.file().downloadTranscodedVideoWithHttpInfo(request);System.out.println("Status code: " + apiResponse.getStatusCode());} catch (ApiException e) {System.err.println("Error: " + e.getCode() + " - " + e.getMessage());}
参数说明
参数名 | 参数描述 | 类型 | 是否必填 |
libraryId | 媒体库 ID | String | 是 |
spaceId | 空间 ID | String | 是 |
filePath | 视频文件路径 | String | 是 |
transcodingTemplateId | 转码模板:h264_360p、h264_480p、h264_720p、h264_1080p、h264_2K、h264_4K | String | 是 |
accessToken | 访问令牌;对于公有读媒体库或租户空间可不指定,否则需通过本参数传入或提前调用 client.withToken() 注入,二者取一 | String | 否 |
m3u8 上传
m3u8 上传用于将已切片好的 HLS 资源(m3u8 播放列表 + ts 分片)上传到 SMH,采用多步流程:
1. 上传准备(
prepareM3u8Upload):提交播放列表与分片清单,获取 confirmKey 与各文件的预签名上传信息;命中秒传时直接完成。2. 上传分片:客户端按返回的预签名信息,将 playlist 和各 segment 直传 COS。
3. 上传完成(
confirmM3u8Upload):分片上传完成后提交 CRC64 校验值确认,分批确认时最后确认 playlist。4. 上传续期(
renewM3u8Upload,可选):预签名信息过期(expiration)前续期。5. 分片重传与追加(
modifyM3u8Segments):分片失败重传或追加分片(分片数超过单次上限 100 个时分批追加,带密钥时上限 101 个)。上传准备
功能说明
prepareM3u8Upload(PUT + body),返回 201 表示需继续上传(含 confirmKey 和预签名信息),返回 200 表示秒传命中直接完成。使用示例
import com.tencent.cloud.smh.ApiException;import com.tencent.cloud.smh.ApiResponse;import com.tencent.cloud.smh.api.HlsApi;import com.tencent.cloud.smh.model.PrepareM3u8UploadRequest;import com.tencent.cloud.smh.model.PrepareM3u8UploadRequestSegmentsInner;import com.tencent.cloud.smh.model.PrepareM3u8Upload201Response;import java.util.List;PrepareM3u8UploadRequest prepareBody = new PrepareM3u8UploadRequest().segments(List.of(new PrepareM3u8UploadRequestSegmentsInner().path("1.ts"),new PrepareM3u8UploadRequestSegmentsInner().path("2.ts")));try {HlsApi.APIPrepareM3u8UploadRequest request = HlsApi.APIPrepareM3u8UploadRequest.newBuilder().libraryId("your-library-id").spaceId("your-space-id").filePath("/videos/hls/movie.m3u8").conflictResolutionStrategy("rename").accessToken("your-access-token").prepareM3u8UploadRequest(prepareBody).build();ApiResponse<Object> apiResponse = client.hls().prepareM3u8UploadWithHttpInfo(request);if (apiResponse.getStatusCode() == 201) {PrepareM3u8Upload201Response result = (PrepareM3u8Upload201Response) apiResponse.getData();System.out.println("ConfirmKey: " + result.getConfirmKey());// 按 result.getPlaylist() 与 result.getSegments() 中的预签名信息直传 COS} else if (apiResponse.getStatusCode() == 200) {System.out.println("Rapid upload succeeded");}} catch (ApiException e) {System.err.println("Error: " + e.getCode() + " - " + e.getMessage());}
PrepareM3u8UploadRequest 对象说明
字段 | 参数描述 | 类型 | 是否必填 |
playlist | m3u8 播放列表内容(media playlist,固定简单上传) | Object | 否 |
segments | 分片清单,最多100个(带密钥101个),超出部分通过分片重传与追加接口分批上传 | List<PrepareM3u8UploadRequestSegmentsInner> | 否 |
sampleHash | 秒传抽样哈希,与 segmentsCount 捆绑使用 | String | 否 |
segmentsCount | 分片总数,与 sampleHash 捆绑使用 | String | 否 |
SegmentsInner 对象说明:path(分片相对路径,如 1.ts 或 abc/def/1.ts,必填)、uploadMethod(上传方式:simple 默认 / multipart,可选)。
201 响应说明:confirmKey(上传确认标识);playlist 与 segments(Map,key 为分片路径)中均含 domain、path、headers、expiration(过期时间,失效前需通过续期接口续期);segments 的 uploadId 仅分块上传时返回。
上传完成
功能说明
confirmM3u8Upload(POST + confirm=1 + confirmKey),提交各分片与播放列表的 CRC64 校验值完成上传。分片较多时可分批确认,最后一批或单独最后确认 playlist。使用示例
import com.tencent.cloud.smh.ApiException;import com.tencent.cloud.smh.ApiResponse;import com.tencent.cloud.smh.api.HlsApi;import com.tencent.cloud.smh.model.ConfirmM3u8UploadRequest;import com.tencent.cloud.smh.model.ConfirmM3u8UploadRequestSegmentsInner;import com.tencent.cloud.smh.model.ConfirmM3u8Upload200Response;import java.math.BigDecimal;import java.util.List;ConfirmM3u8UploadRequest confirmBody = new ConfirmM3u8UploadRequest().segments(List.of(new ConfirmM3u8UploadRequestSegmentsInner().path("1.ts").crc64("crc64-of-segment-1"),new ConfirmM3u8UploadRequestSegmentsInner().path("2.ts").crc64("crc64-of-segment-2")));// playlist 的 crc64 与最后一批 segments 同传,或单独最后提交try {HlsApi.APIConfirmM3u8UploadRequest request = HlsApi.APIConfirmM3u8UploadRequest.newBuilder().libraryId("your-library-id").spaceId("your-space-id").confirmKey("confirm-key-from-prepare").confirm(1).accessToken("your-access-token").confirmM3u8UploadRequest(confirmBody).build();ApiResponse<Object> apiResponse = client.hls().confirmM3u8UploadWithHttpInfo(request);if (apiResponse.getStatusCode() == 200) {ConfirmM3u8Upload200Response result = (ConfirmM3u8Upload200Response) apiResponse.getData();System.out.println("Playlist path: " + result.getPlaylist().getPath());}} catch (ApiException e) {System.err.println("Error: " + e.getCode() + " - " + e.getMessage());}
上传续期与分片重传追加
功能说明
renewM3u8Upload(POST + renew=1 + confirmKey):续期 playlist 和/或指定分片的预签名上传信息,body 中 playlist(固定 m3u8)与 segments(路径数组,最多 100/101 个)按需传入。modifyM3u8Segments(POST + modify=1 + confirmKey):重传失败分片或追加分片,body 的 segments 结构同上传准备接口。使用示例
import com.tencent.cloud.smh.ApiException;import com.tencent.cloud.smh.ApiResponse;import com.tencent.cloud.smh.api.HlsApi;import com.tencent.cloud.smh.model.RenewM3u8UploadRequest;import com.tencent.cloud.smh.model.RenewM3u8Upload200Response;import java.math.BigDecimal;import java.util.List;RenewM3u8UploadRequest renewBody = new RenewM3u8UploadRequest().segments(List.of("1.ts", "2.ts"));try {HlsApi.APIRenewM3u8UploadRequest request = HlsApi.APIRenewM3u8UploadRequest.newBuilder().libraryId("your-library-id").spaceId("your-space-id").confirmKey("confirm-key-from-prepare").renew(1).accessToken("your-access-token").renewM3u8UploadRequest(renewBody).build();ApiResponse<Object> apiResponse = client.hls().renewM3u8UploadWithHttpInfo(request);if (apiResponse.getStatusCode() == 200) {RenewM3u8Upload200Response result = (RenewM3u8Upload200Response) apiResponse.getData();// 使用新的预签名信息继续上传System.out.println("Renewed, segments: " + result.getSegments().keySet());}} catch (ApiException e) {System.err.println("Error: " + e.getCode() + " - " + e.getMessage());}