返回 AiToEarn
media.service.ts
1 import type {
2 VodGetMediaInfosRequest,
3 VodGetMediaInfosResult,
4 VodGetPlayInfoRequest,
5 VodGetPlayInfoResult,
6 } from '@volcengine/openapi/lib/services/vod/types'
7 import * as crypto from 'node:crypto'
8 import { Injectable } from '@nestjs/common'
9 import { VolcengineConfig } from '../volcengine.config'
10 import { BaseService } from './base.service'
11
12 /**
13 * Volcengine 媒资服务
14 * 负责媒资查询、播放信息获取、鉴权 URL 构建
15 */
16 @Injectable()
17 export class MediaService extends BaseService {
18 constructor(config: VolcengineConfig) {
19 super(config)
20 }
21
22 /**
23 * 获取媒资信息
24 */
25 async getMediaInfos(
26 request: VodGetMediaInfosRequest,
27 ): Promise<VodGetMediaInfosResult> {
28 const options: VodGetMediaInfosRequest = {
29 ...request,
30 }
31
32 const response = await this.vodService.GetMediaInfos(options)
33 return response.Result!
34 }
35
36 /**
37 * 获取播放信息
38 */
39 async getPlayInfo(
40 request: VodGetPlayInfoRequest,
41 ): Promise<VodGetPlayInfoResult> {
42 const response = await this.vodService.GetPlayInfo(request)
43
44 if (response.ResponseMetadata?.Error) {
45 const error = response.ResponseMetadata.Error
46 this.logger.error({ vid: request.Vid, code: error.Code, message: error.Message }, '获取播放信息失败')
47 }
48
49 if (response.Result?.PlayInfoList) {
50 this.logger.debug({
51 vid: request.Vid,
52 count: response.Result.PlayInfoList.length,
53 mainPlayUrl: response.Result.PlayInfoList[0]?.MainPlayUrl,
54 }, '获取播放信息成功')
55 }
56
57 return response.Result!
58 }
59
60 /**
61 * 构建带鉴权的播放URL
62 * 使用A类型URL鉴权:MD5(自定义密钥 + 过期时间 + URI)
63 */
64 buildAuthenticatedPlayUrl(uri: string): string {
65 const playbackBaseUrl = this.config.playbackBaseUrl
66 const authKey = this.config.urlAuthPrimaryKey
67
68 // URL鉴权参数
69 const expirationTime = Math.floor(Date.now() / 1000) + 3600 // 1小时后过期
70 const timestamp = expirationTime.toString(16) // 转换为16进制
71
72 // 生成签名:MD5(密钥 + 时间戳 + URI)
73 const uriPath = uri.startsWith('/') ? uri : `/${uri}`
74 const signString = `${authKey}${timestamp}${uriPath}`
75 const md5Hash = crypto.createHash('md5').update(signString).digest('hex')
76
77 // 构建URL:域名/URI?auth_key=时间戳-md5值
78 const authParam = `${timestamp}-${md5Hash}`
79 const fullUrl = `${playbackBaseUrl}${uriPath}?auth_key=${authParam}`
80
81 this.logger.debug({ uri, timestamp, fullUrl }, '构建带鉴权URL成功')
82 return fullUrl
83 }
84 }
85
85 lines TYPESCRIPT