调整创建直播流方法名称,新增查询直播流信息方法
This commit is contained in:
parent
a71d5d339f
commit
304c2f6ac2
|
|
@ -1,4 +1,4 @@
|
|||
import { QiniuZone } from '../../types/Qiniu';
|
||||
import { QiniuLiveStreamInfo, QiniuZone } from '../../types/Qiniu';
|
||||
export declare class QiniuCloudInstance {
|
||||
private accessKey;
|
||||
private secretKey;
|
||||
|
|
@ -17,40 +17,6 @@ export declare class QiniuCloudInstance {
|
|||
uploadHost: string;
|
||||
bucket: string;
|
||||
};
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, host: string, rawQuery?: string, contentType?: string, bodyStr?: string): string;
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
getLiveStream(hub: string, streamTitle: string, host: string, publishDomain: string, playDomainType: 'rtmp' | 'hls' | 'flv', playDomain: string, expireAt: number, publishSecurity: 'none' | 'static' | 'expiry' | 'expiry_sk', publishKey: string, playKey: string): Promise<{
|
||||
streamTitle: string;
|
||||
hub: string;
|
||||
rtmpPushUrl: string;
|
||||
playUrl: string;
|
||||
pcPushUrl: string;
|
||||
streamKey: string;
|
||||
expireAt: number;
|
||||
}>;
|
||||
/**
|
||||
* https://developer.qiniu.com/kodo/1308/stat
|
||||
* 文档里写的是GET方法,从nodejs-sdk里看是POST方法
|
||||
|
|
@ -95,6 +61,40 @@ export declare class QiniuCloudInstance {
|
|||
}>;
|
||||
moveKodoFile(srcBucket: string, zone: QiniuZone, srcKey: string, destBucket: string, destKey: string, force?: boolean, mockData?: any): Promise<void>;
|
||||
copyKodoFile(srcBucket: string, zone: QiniuZone, srcKey: string, destBucket: string, destKey: string, force?: boolean, mockData?: any): Promise<void>;
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, host: string, rawQuery?: string, contentType?: string, bodyStr?: string): string;
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
createLiveStream(hub: string, streamTitle: string, host: string, publishDomain: string, playDomainType: 'rtmp' | 'hls' | 'flv', playDomain: string, expireAt: number, publishSecurity: 'none' | 'static' | 'expiry' | 'expiry_sk', publishKey: string, playKey: string): Promise<{
|
||||
streamTitle: string;
|
||||
hub: string;
|
||||
rtmpPushUrl: string;
|
||||
playUrl: string;
|
||||
pcPushUrl: string;
|
||||
streamKey: string;
|
||||
expireAt: number;
|
||||
}>;
|
||||
/**
|
||||
* 计算直播流地址相关信息
|
||||
* @param hub
|
||||
|
|
@ -136,10 +136,21 @@ export declare class QiniuCloudInstance {
|
|||
* @param prefix
|
||||
* @param limit
|
||||
* @param marker
|
||||
* @returns 直播流名称
|
||||
* @returns
|
||||
*/
|
||||
getLiveStreamList(hub: string, host: string, liveOnly?: boolean, prefix?: string, limit?: number, //取值范围0~5000
|
||||
marker?: string): Promise<any>;
|
||||
marker?: string): Promise<{
|
||||
streamTitles: string[];
|
||||
marker: string;
|
||||
}>;
|
||||
/**
|
||||
* 查询直播流信息
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @returns
|
||||
*/
|
||||
getLiveStreamInfo(hub: string, streamTitle: string, host: string): Promise<QiniuLiveStreamInfo>;
|
||||
/**
|
||||
* 管理端访问七牛云服务器
|
||||
* @param path
|
||||
|
|
|
|||
|
|
@ -135,90 +135,6 @@ export class QiniuCloudInstance {
|
|||
throw err;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(method, path, host, rawQuery, contentType, bodyStr) {
|
||||
// 1. 添加 Path
|
||||
let data = `${method} ${path}`;
|
||||
if (rawQuery) {
|
||||
data += `?${rawQuery}`;
|
||||
}
|
||||
data += `\nHost: ${host}`;
|
||||
if (contentType) {
|
||||
data += `\nContent-Type: ${contentType}`;
|
||||
}
|
||||
data += '\n\n';
|
||||
if (bodyStr &&
|
||||
contentType &&
|
||||
contentType !== 'application/octet-stream') {
|
||||
data += bodyStr;
|
||||
}
|
||||
const sign = this.hmacSha1(data, this.secretKey);
|
||||
const encodedSign = this.base64ToUrlSafe(sign);
|
||||
const toke = 'Qiniu ' + this.accessKey + ':' + encodedSign;
|
||||
return toke;
|
||||
}
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
async getLiveStream(hub, streamTitle, host, publishDomain, playDomainType, playDomain, expireAt, publishSecurity, publishKey, playKey) {
|
||||
// 七牛创建直播流接口路径
|
||||
const path = `/v2/hubs/${hub}/streams`;
|
||||
// 如果用户没给streamTitle,那么随机生成一个
|
||||
let key = streamTitle;
|
||||
if (!key) {
|
||||
key = `class${new Date().getTime()}`;
|
||||
}
|
||||
const bodyStr = JSON.stringify({
|
||||
key,
|
||||
});
|
||||
const contentType = 'application/json';
|
||||
const token = this.getLiveToken('POST', path, host, undefined, contentType, bodyStr);
|
||||
const url = `https://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
|
||||
let response;
|
||||
try {
|
||||
response = await global.fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
// mode: 'no-cors',
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
throw new OakNetworkException();
|
||||
}
|
||||
if (response.status !== 200) {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
const obj = this.getStreamObj(hub, streamTitle, expireAt, publishDomain, playDomainType, playDomain, publishSecurity, publishKey, playKey);
|
||||
return obj;
|
||||
}
|
||||
/**
|
||||
* https://developer.qiniu.com/kodo/1308/stat
|
||||
* 文档里写的是GET方法,从nodejs-sdk里看是POST方法
|
||||
|
|
@ -298,6 +214,97 @@ export class QiniuCloudInstance {
|
|||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}, undefined, 'POST', undefined, mockData);
|
||||
}
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(method, path, host, rawQuery, contentType, bodyStr) {
|
||||
// 1. 添加 Path
|
||||
let data = `${method} ${path}`;
|
||||
if (rawQuery) {
|
||||
data += `?${rawQuery}`;
|
||||
}
|
||||
data += `\nHost: ${host}`;
|
||||
if (contentType) {
|
||||
data += `\nContent-Type: ${contentType}`;
|
||||
}
|
||||
data += '\n\n';
|
||||
if (bodyStr &&
|
||||
contentType &&
|
||||
contentType !== 'application/octet-stream') {
|
||||
data += bodyStr;
|
||||
}
|
||||
const sign = this.hmacSha1(data, this.secretKey);
|
||||
const encodedSign = this.base64ToUrlSafe(sign);
|
||||
const toke = 'Qiniu ' + this.accessKey + ':' + encodedSign;
|
||||
return toke;
|
||||
}
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
async createLiveStream(hub, streamTitle, host, publishDomain, playDomainType, playDomain, expireAt, publishSecurity, publishKey, playKey) {
|
||||
// 七牛创建直播流接口路径
|
||||
const path = `/v2/hubs/${hub}/streams`;
|
||||
// 如果用户没给streamTitle,那么随机生成一个
|
||||
let key = streamTitle;
|
||||
if (!key) {
|
||||
key = `class${new Date().getTime()}`;
|
||||
}
|
||||
const bodyStr = JSON.stringify({
|
||||
key,
|
||||
});
|
||||
const contentType = 'application/json';
|
||||
const token = this.getLiveToken('POST', path, host, undefined, contentType, bodyStr);
|
||||
const url = `https://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
|
||||
let response;
|
||||
try {
|
||||
response = await global.fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
// mode: 'no-cors',
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
throw new OakNetworkException();
|
||||
}
|
||||
if (response.status !== 200) {
|
||||
if (response.status === 614) {
|
||||
throw new OakExternalException('qiniu', response.status.toString(), '直播流名已存在', {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
else {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
const obj = this.getStreamObj(hub, streamTitle, expireAt, publishDomain, playDomainType, playDomain, publishSecurity, publishKey, playKey);
|
||||
return obj;
|
||||
}
|
||||
/**
|
||||
* 计算直播流地址相关信息
|
||||
* @param hub
|
||||
|
|
@ -440,7 +447,7 @@ export class QiniuCloudInstance {
|
|||
* @param prefix
|
||||
* @param limit
|
||||
* @param marker
|
||||
* @returns 直播流名称
|
||||
* @returns
|
||||
*/
|
||||
async getLiveStreamList(hub, host, liveOnly, prefix, limit, //取值范围0~5000
|
||||
marker) {
|
||||
|
|
@ -473,8 +480,59 @@ export class QiniuCloudInstance {
|
|||
catch (err) {
|
||||
throw new OakNetworkException();
|
||||
}
|
||||
if (response.status === 200) {
|
||||
const json = await response.json();
|
||||
return json.items.map((ele) => ele.key);
|
||||
const streamTitles = json.items?.map((ele) => ele.key);
|
||||
return {
|
||||
streamTitles,
|
||||
marker: json.marker,
|
||||
};
|
||||
}
|
||||
else {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 查询直播流信息
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @returns
|
||||
*/
|
||||
async getLiveStreamInfo(hub, streamTitle, host) {
|
||||
const encodedStreamTitle = this.urlSafeBase64Encode(streamTitle);
|
||||
const path = `/v2/hubs/${hub}/streams/${encodedStreamTitle}`;
|
||||
const contentType = 'application/x-www-form-urlencoded';
|
||||
const token = this.getLiveToken('GET', path, host, undefined, contentType);
|
||||
const url = `https://pili.qiniuapi.com${path}`;
|
||||
let response;
|
||||
try {
|
||||
response = await global.fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
throw new OakNetworkException();
|
||||
}
|
||||
if (response.status === 200) {
|
||||
const json = await response.json();
|
||||
return json;
|
||||
}
|
||||
else {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 管理端访问七牛云服务器
|
||||
|
|
|
|||
|
|
@ -1 +1,12 @@
|
|||
export type QiniuZone = 'z0' | 'cn-east-2' | 'z1' | 'z2' | 'na0' | 'as0';
|
||||
export type QiniuLiveStreamInfo = {
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
expireAt: number;
|
||||
disabledTill: number;
|
||||
converts: string[];
|
||||
watermark: boolean;
|
||||
publishSecurity: string;
|
||||
publishKey: string;
|
||||
nropEnable: boolean;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { QiniuZone } from '../../types/Qiniu';
|
||||
import { QiniuLiveStreamInfo, QiniuZone } from '../../types/Qiniu';
|
||||
export declare class QiniuCloudInstance {
|
||||
private accessKey;
|
||||
private secretKey;
|
||||
|
|
@ -17,40 +17,6 @@ export declare class QiniuCloudInstance {
|
|||
uploadHost: string;
|
||||
bucket: string;
|
||||
};
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, host: string, rawQuery?: string, contentType?: string, bodyStr?: string): string;
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
getLiveStream(hub: string, streamTitle: string, host: string, publishDomain: string, playDomainType: 'rtmp' | 'hls' | 'flv', playDomain: string, expireAt: number, publishSecurity: 'none' | 'static' | 'expiry' | 'expiry_sk', publishKey: string, playKey: string): Promise<{
|
||||
streamTitle: string;
|
||||
hub: string;
|
||||
rtmpPushUrl: string;
|
||||
playUrl: string;
|
||||
pcPushUrl: string;
|
||||
streamKey: string;
|
||||
expireAt: number;
|
||||
}>;
|
||||
/**
|
||||
* https://developer.qiniu.com/kodo/1308/stat
|
||||
* 文档里写的是GET方法,从nodejs-sdk里看是POST方法
|
||||
|
|
@ -95,6 +61,40 @@ export declare class QiniuCloudInstance {
|
|||
}>;
|
||||
moveKodoFile(srcBucket: string, zone: QiniuZone, srcKey: string, destBucket: string, destKey: string, force?: boolean, mockData?: any): Promise<void>;
|
||||
copyKodoFile(srcBucket: string, zone: QiniuZone, srcKey: string, destBucket: string, destKey: string, force?: boolean, mockData?: any): Promise<void>;
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(method: 'GET' | 'POST' | 'PUT' | 'DELETE', path: string, host: string, rawQuery?: string, contentType?: string, bodyStr?: string): string;
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
createLiveStream(hub: string, streamTitle: string, host: string, publishDomain: string, playDomainType: 'rtmp' | 'hls' | 'flv', playDomain: string, expireAt: number, publishSecurity: 'none' | 'static' | 'expiry' | 'expiry_sk', publishKey: string, playKey: string): Promise<{
|
||||
streamTitle: string;
|
||||
hub: string;
|
||||
rtmpPushUrl: string;
|
||||
playUrl: string;
|
||||
pcPushUrl: string;
|
||||
streamKey: string;
|
||||
expireAt: number;
|
||||
}>;
|
||||
/**
|
||||
* 计算直播流地址相关信息
|
||||
* @param hub
|
||||
|
|
@ -136,10 +136,21 @@ export declare class QiniuCloudInstance {
|
|||
* @param prefix
|
||||
* @param limit
|
||||
* @param marker
|
||||
* @returns 直播流名称
|
||||
* @returns
|
||||
*/
|
||||
getLiveStreamList(hub: string, host: string, liveOnly?: boolean, prefix?: string, limit?: number, //取值范围0~5000
|
||||
marker?: string): Promise<any>;
|
||||
marker?: string): Promise<{
|
||||
streamTitles: string[];
|
||||
marker: string;
|
||||
}>;
|
||||
/**
|
||||
* 查询直播流信息
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @returns
|
||||
*/
|
||||
getLiveStreamInfo(hub: string, streamTitle: string, host: string): Promise<QiniuLiveStreamInfo>;
|
||||
/**
|
||||
* 管理端访问七牛云服务器
|
||||
* @param path
|
||||
|
|
|
|||
|
|
@ -139,90 +139,6 @@ class QiniuCloudInstance {
|
|||
throw err;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(method, path, host, rawQuery, contentType, bodyStr) {
|
||||
// 1. 添加 Path
|
||||
let data = `${method} ${path}`;
|
||||
if (rawQuery) {
|
||||
data += `?${rawQuery}`;
|
||||
}
|
||||
data += `\nHost: ${host}`;
|
||||
if (contentType) {
|
||||
data += `\nContent-Type: ${contentType}`;
|
||||
}
|
||||
data += '\n\n';
|
||||
if (bodyStr &&
|
||||
contentType &&
|
||||
contentType !== 'application/octet-stream') {
|
||||
data += bodyStr;
|
||||
}
|
||||
const sign = this.hmacSha1(data, this.secretKey);
|
||||
const encodedSign = this.base64ToUrlSafe(sign);
|
||||
const toke = 'Qiniu ' + this.accessKey + ':' + encodedSign;
|
||||
return toke;
|
||||
}
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
async getLiveStream(hub, streamTitle, host, publishDomain, playDomainType, playDomain, expireAt, publishSecurity, publishKey, playKey) {
|
||||
// 七牛创建直播流接口路径
|
||||
const path = `/v2/hubs/${hub}/streams`;
|
||||
// 如果用户没给streamTitle,那么随机生成一个
|
||||
let key = streamTitle;
|
||||
if (!key) {
|
||||
key = `class${new Date().getTime()}`;
|
||||
}
|
||||
const bodyStr = JSON.stringify({
|
||||
key,
|
||||
});
|
||||
const contentType = 'application/json';
|
||||
const token = this.getLiveToken('POST', path, host, undefined, contentType, bodyStr);
|
||||
const url = `https://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
|
||||
let response;
|
||||
try {
|
||||
response = await global.fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
// mode: 'no-cors',
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
throw new Exception_1.OakNetworkException();
|
||||
}
|
||||
if (response.status !== 200) {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new Exception_1.OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
const obj = this.getStreamObj(hub, streamTitle, expireAt, publishDomain, playDomainType, playDomain, publishSecurity, publishKey, playKey);
|
||||
return obj;
|
||||
}
|
||||
/**
|
||||
* https://developer.qiniu.com/kodo/1308/stat
|
||||
* 文档里写的是GET方法,从nodejs-sdk里看是POST方法
|
||||
|
|
@ -302,6 +218,97 @@ class QiniuCloudInstance {
|
|||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
}, undefined, 'POST', undefined, mockData);
|
||||
}
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(method, path, host, rawQuery, contentType, bodyStr) {
|
||||
// 1. 添加 Path
|
||||
let data = `${method} ${path}`;
|
||||
if (rawQuery) {
|
||||
data += `?${rawQuery}`;
|
||||
}
|
||||
data += `\nHost: ${host}`;
|
||||
if (contentType) {
|
||||
data += `\nContent-Type: ${contentType}`;
|
||||
}
|
||||
data += '\n\n';
|
||||
if (bodyStr &&
|
||||
contentType &&
|
||||
contentType !== 'application/octet-stream') {
|
||||
data += bodyStr;
|
||||
}
|
||||
const sign = this.hmacSha1(data, this.secretKey);
|
||||
const encodedSign = this.base64ToUrlSafe(sign);
|
||||
const toke = 'Qiniu ' + this.accessKey + ':' + encodedSign;
|
||||
return toke;
|
||||
}
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
async createLiveStream(hub, streamTitle, host, publishDomain, playDomainType, playDomain, expireAt, publishSecurity, publishKey, playKey) {
|
||||
// 七牛创建直播流接口路径
|
||||
const path = `/v2/hubs/${hub}/streams`;
|
||||
// 如果用户没给streamTitle,那么随机生成一个
|
||||
let key = streamTitle;
|
||||
if (!key) {
|
||||
key = `class${new Date().getTime()}`;
|
||||
}
|
||||
const bodyStr = JSON.stringify({
|
||||
key,
|
||||
});
|
||||
const contentType = 'application/json';
|
||||
const token = this.getLiveToken('POST', path, host, undefined, contentType, bodyStr);
|
||||
const url = `https://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
|
||||
let response;
|
||||
try {
|
||||
response = await global.fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
// mode: 'no-cors',
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
throw new Exception_1.OakNetworkException();
|
||||
}
|
||||
if (response.status !== 200) {
|
||||
if (response.status === 614) {
|
||||
throw new Exception_1.OakExternalException('qiniu', response.status.toString(), '直播流名已存在', {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
else {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new Exception_1.OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
const obj = this.getStreamObj(hub, streamTitle, expireAt, publishDomain, playDomainType, playDomain, publishSecurity, publishKey, playKey);
|
||||
return obj;
|
||||
}
|
||||
/**
|
||||
* 计算直播流地址相关信息
|
||||
* @param hub
|
||||
|
|
@ -444,7 +451,7 @@ class QiniuCloudInstance {
|
|||
* @param prefix
|
||||
* @param limit
|
||||
* @param marker
|
||||
* @returns 直播流名称
|
||||
* @returns
|
||||
*/
|
||||
async getLiveStreamList(hub, host, liveOnly, prefix, limit, //取值范围0~5000
|
||||
marker) {
|
||||
|
|
@ -477,8 +484,59 @@ class QiniuCloudInstance {
|
|||
catch (err) {
|
||||
throw new Exception_1.OakNetworkException();
|
||||
}
|
||||
if (response.status === 200) {
|
||||
const json = await response.json();
|
||||
return json.items.map((ele) => ele.key);
|
||||
const streamTitles = json.items?.map((ele) => ele.key);
|
||||
return {
|
||||
streamTitles,
|
||||
marker: json.marker,
|
||||
};
|
||||
}
|
||||
else {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new Exception_1.OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 查询直播流信息
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @returns
|
||||
*/
|
||||
async getLiveStreamInfo(hub, streamTitle, host) {
|
||||
const encodedStreamTitle = this.urlSafeBase64Encode(streamTitle);
|
||||
const path = `/v2/hubs/${hub}/streams/${encodedStreamTitle}`;
|
||||
const contentType = 'application/x-www-form-urlencoded';
|
||||
const token = this.getLiveToken('GET', path, host, undefined, contentType);
|
||||
const url = `https://pili.qiniuapi.com${path}`;
|
||||
let response;
|
||||
try {
|
||||
response = await global.fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
throw new Exception_1.OakNetworkException();
|
||||
}
|
||||
if (response.status === 200) {
|
||||
const json = await response.json();
|
||||
return json;
|
||||
}
|
||||
else {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new Exception_1.OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 管理端访问七牛云服务器
|
||||
|
|
|
|||
|
|
@ -1 +1,12 @@
|
|||
export type QiniuZone = 'z0' | 'cn-east-2' | 'z1' | 'z2' | 'na0' | 'as0';
|
||||
export type QiniuLiveStreamInfo = {
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
expireAt: number;
|
||||
disabledTill: number;
|
||||
converts: string[];
|
||||
watermark: boolean;
|
||||
publishSecurity: string;
|
||||
publishKey: string;
|
||||
nropEnable: boolean;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
OakNetworkException,
|
||||
} from 'oak-domain/lib/types/Exception';
|
||||
import { url as URL, urlObject as UrlObject } from 'oak-domain/lib/utils/url';
|
||||
import { QiniuZone } from '../../types/Qiniu';
|
||||
import { QiniuLiveStreamInfo, QiniuZone } from '../../types/Qiniu';
|
||||
|
||||
/**
|
||||
* qiniu endpoint list
|
||||
|
|
@ -148,123 +148,6 @@ export class QiniuCloudInstance {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(
|
||||
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
|
||||
path: string,
|
||||
host: string,
|
||||
rawQuery?: string,
|
||||
contentType?: string,
|
||||
bodyStr?: string
|
||||
) {
|
||||
// 1. 添加 Path
|
||||
let data = `${method} ${path}`;
|
||||
if (rawQuery) {
|
||||
data += `?${rawQuery}`;
|
||||
}
|
||||
data += `\nHost: ${host}`;
|
||||
if (contentType) {
|
||||
data += `\nContent-Type: ${contentType}`;
|
||||
}
|
||||
data += '\n\n';
|
||||
if (
|
||||
bodyStr &&
|
||||
contentType &&
|
||||
contentType !== 'application/octet-stream'
|
||||
) {
|
||||
data += bodyStr;
|
||||
}
|
||||
const sign = this.hmacSha1(data, this.secretKey);
|
||||
const encodedSign = this.base64ToUrlSafe(sign);
|
||||
const toke = 'Qiniu ' + this.accessKey + ':' + encodedSign;
|
||||
return toke;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
async getLiveStream(
|
||||
hub: string,
|
||||
streamTitle: string,
|
||||
host: string,
|
||||
publishDomain: string,
|
||||
playDomainType: 'rtmp' | 'hls' | 'flv',
|
||||
playDomain: string,
|
||||
expireAt: number,
|
||||
publishSecurity: 'none' | 'static' | 'expiry' | 'expiry_sk',
|
||||
publishKey: string,
|
||||
playKey: string,
|
||||
) {
|
||||
// 七牛创建直播流接口路径
|
||||
const path = `/v2/hubs/${hub}/streams`;
|
||||
// 如果用户没给streamTitle,那么随机生成一个
|
||||
let key: string = streamTitle;
|
||||
if (!key) {
|
||||
key = `class${new Date().getTime()}`;
|
||||
}
|
||||
const bodyStr = JSON.stringify({
|
||||
key,
|
||||
});
|
||||
const contentType = 'application/json';
|
||||
const token = this.getLiveToken('POST', path, host, undefined, contentType, bodyStr);
|
||||
|
||||
const url = `https://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
|
||||
let response: Response;
|
||||
try {
|
||||
response = await global.fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
// mode: 'no-cors',
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
throw new OakNetworkException();
|
||||
}
|
||||
if (response.status !== 200) {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
const obj = this.getStreamObj(
|
||||
hub,
|
||||
streamTitle,
|
||||
expireAt,
|
||||
publishDomain,
|
||||
playDomainType,
|
||||
playDomain,
|
||||
publishSecurity,
|
||||
publishKey,
|
||||
playKey,
|
||||
);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* https://developer.qiniu.com/kodo/1308/stat
|
||||
* 文档里写的是GET方法,从nodejs-sdk里看是POST方法
|
||||
|
|
@ -451,6 +334,129 @@ export class QiniuCloudInstance {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算直播需要的token
|
||||
* @param method
|
||||
* @param path
|
||||
* @param host
|
||||
* @param rawQuery
|
||||
* @param contentType
|
||||
* @param bodyStr
|
||||
* @returns
|
||||
*/
|
||||
getLiveToken(
|
||||
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
|
||||
path: string,
|
||||
host: string,
|
||||
rawQuery?: string,
|
||||
contentType?: string,
|
||||
bodyStr?: string
|
||||
) {
|
||||
// 1. 添加 Path
|
||||
let data = `${method} ${path}`;
|
||||
if (rawQuery) {
|
||||
data += `?${rawQuery}`;
|
||||
}
|
||||
data += `\nHost: ${host}`;
|
||||
if (contentType) {
|
||||
data += `\nContent-Type: ${contentType}`;
|
||||
}
|
||||
data += '\n\n';
|
||||
if (
|
||||
bodyStr &&
|
||||
contentType &&
|
||||
contentType !== 'application/octet-stream'
|
||||
) {
|
||||
data += bodyStr;
|
||||
}
|
||||
const sign = this.hmacSha1(data, this.secretKey);
|
||||
const encodedSign = this.base64ToUrlSafe(sign);
|
||||
const toke = 'Qiniu ' + this.accessKey + ':' + encodedSign;
|
||||
return toke;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建直播流
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @param publishDomain
|
||||
* @param playDomainType
|
||||
* @param playDomain
|
||||
* @param expireAt
|
||||
* @param publishSecurity
|
||||
* @param publishKey
|
||||
* @param playKey
|
||||
* @returns
|
||||
*/
|
||||
async createLiveStream(
|
||||
hub: string,
|
||||
streamTitle: string,
|
||||
host: string,
|
||||
publishDomain: string,
|
||||
playDomainType: 'rtmp' | 'hls' | 'flv',
|
||||
playDomain: string,
|
||||
expireAt: number,
|
||||
publishSecurity: 'none' | 'static' | 'expiry' | 'expiry_sk',
|
||||
publishKey: string,
|
||||
playKey: string,
|
||||
) {
|
||||
// 七牛创建直播流接口路径
|
||||
const path = `/v2/hubs/${hub}/streams`;
|
||||
// 如果用户没给streamTitle,那么随机生成一个
|
||||
let key: string = streamTitle;
|
||||
if (!key) {
|
||||
key = `class${new Date().getTime()}`;
|
||||
}
|
||||
const bodyStr = JSON.stringify({
|
||||
key,
|
||||
});
|
||||
const contentType = 'application/json';
|
||||
const token = this.getLiveToken('POST', path, host, undefined, contentType, bodyStr);
|
||||
|
||||
const url = `https://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
|
||||
let response: Response;
|
||||
try {
|
||||
response = await global.fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: bodyStr,
|
||||
// mode: 'no-cors',
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
throw new OakNetworkException();
|
||||
}
|
||||
if (response.status !== 200) {
|
||||
if (response.status === 614) {
|
||||
throw new OakExternalException('qiniu', response.status.toString(), '直播流名已存在', {
|
||||
status: response.status,
|
||||
});
|
||||
} else {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
const obj = this.getStreamObj(
|
||||
hub,
|
||||
streamTitle,
|
||||
expireAt,
|
||||
publishDomain,
|
||||
playDomainType,
|
||||
playDomain,
|
||||
publishSecurity,
|
||||
publishKey,
|
||||
playKey,
|
||||
);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算直播流地址相关信息
|
||||
* @param hub
|
||||
|
|
@ -632,7 +638,7 @@ export class QiniuCloudInstance {
|
|||
* @param prefix
|
||||
* @param limit
|
||||
* @param marker
|
||||
* @returns 直播流名称
|
||||
* @returns
|
||||
*/
|
||||
async getLiveStreamList(
|
||||
hub: string,
|
||||
|
|
@ -676,8 +682,72 @@ export class QiniuCloudInstance {
|
|||
} catch (err) {
|
||||
throw new OakNetworkException();
|
||||
}
|
||||
if (response.status === 200) {
|
||||
const json = await response.json();
|
||||
return json.items.map((ele: any) => ele.key);
|
||||
const streamTitles = json.items?.map((ele: { key: string }) => ele.key);
|
||||
return {
|
||||
streamTitles,
|
||||
marker: json.marker,
|
||||
} as {
|
||||
streamTitles: string[];
|
||||
marker: string;
|
||||
};
|
||||
} else {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询直播流信息
|
||||
* @param hub
|
||||
* @param streamTitle
|
||||
* @param host
|
||||
* @returns
|
||||
*/
|
||||
async getLiveStreamInfo(
|
||||
hub: string,
|
||||
streamTitle: string,
|
||||
host: string,
|
||||
) {
|
||||
const encodedStreamTitle = this.urlSafeBase64Encode(streamTitle);
|
||||
const path = `/v2/hubs/${hub}/streams/${encodedStreamTitle}`;
|
||||
const contentType = 'application/x-www-form-urlencoded';
|
||||
const token = this.getLiveToken(
|
||||
'GET',
|
||||
path,
|
||||
host,
|
||||
undefined,
|
||||
contentType,
|
||||
);
|
||||
|
||||
const url = `https://pili.qiniuapi.com${path}`;
|
||||
let response: Response;
|
||||
try {
|
||||
response = await global.fetch(url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: token,
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
throw new OakNetworkException();
|
||||
}
|
||||
if (response.status === 200) {
|
||||
const json = await response.json();
|
||||
return json as QiniuLiveStreamInfo;
|
||||
} else {
|
||||
const json = await response.json();
|
||||
const { error } = json;
|
||||
throw new OakExternalException('qiniu', response.status.toString(), error, {
|
||||
status: response.status,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1 +1,13 @@
|
|||
export type QiniuZone = 'z0' | 'cn-east-2' | 'z1' | 'z2' | 'na0' | 'as0';
|
||||
|
||||
export type QiniuLiveStreamInfo = {
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
expireAt: number; //过期时间,一个流持续N天(设置的直播空间的存储过期时间)不推流回被自动清除
|
||||
disabledTill: number; //-1表示永久禁播
|
||||
converts: string[]; //转码配置
|
||||
watermark: boolean; //是否开启水印
|
||||
publishSecurity: string; //推流鉴权类型
|
||||
publishKey: string; //推流密钥
|
||||
nropEnable: boolean; //是否开启鉴黄
|
||||
}
|
||||
Loading…
Reference in New Issue