This commit is contained in:
梁朝伟 2022-09-24 17:33:53 +08:00
parent 6907d88d1d
commit 03d0196768
12 changed files with 130 additions and 6 deletions

View File

@ -38,6 +38,11 @@ declare type GeneralAspectDict<ED extends EntityDict, Cxt extends RuntimeContext
streamTitle: string;
expireAt: number;
}, context: Cxt) => Promise<Pick<Livestream, 'streamTitle' | 'hub' | 'rtmpPushUrl' | 'rtmpPlayUrl' | 'pcPushUrl' | 'streamKey' | 'expireAt'>>;
getPlayBackUrl: (params: {
streamTitle: string;
start: number;
end: number;
}, context: Cxt) => Promise<string>;
sendCaptcha: (params: {
mobile: string;
env: WechatMpEnv | WebEnv;

View File

@ -1,6 +1,6 @@
import { loginByMobile, loginWechat, loginWechatMp, syncUserInfoWechatMp, sendCaptcha } from './token';
import { getUploadInfo } from './extraFile';
import { getLivestream, getLivestream2 } from './livestream';
import { getLivestream, getLivestream2, getPlayBackUrl } from './livestream';
export declare const aspectDict: {
loginByMobile: typeof loginByMobile;
loginWechat: typeof loginWechat;
@ -11,4 +11,5 @@ export declare const aspectDict: {
getApplication: typeof import("./application.dev").getApplication | typeof import("./application.prod").getApplication;
getLivestream: typeof getLivestream;
getLivestream2: typeof getLivestream2;
getPlayBackUrl: typeof getPlayBackUrl;
};

View File

@ -16,5 +16,6 @@ exports.aspectDict = {
getApplication: application_1.getApplication,
getLivestream: livestream_1.getLivestream,
getLivestream2: livestream_1.getLivestream2,
getPlayBackUrl: livestream_1.getPlayBackUrl,
};
// export type AspectDict<ED extends EntityDict & BaseEntityDict> = TokenAD<ED> & CrudAD<ED>;

View File

@ -23,3 +23,8 @@ export declare function getLivestream2<ED extends EntityDict, Cxt extends Runtim
streamTitle: string;
expireAt: number;
}, context: Cxt): Promise<Pick<Livestream, 'streamTitle' | 'hub' | 'rtmpPushUrl' | 'rtmpPlayUrl' | 'pcPushUrl' | 'streamKey' | 'expireAt'>>;
export declare function getPlayBackUrl<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(params: {
streamTitle: string;
start: number;
end: number;
}, context: Cxt): Promise<string>;

View File

@ -1,6 +1,6 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLivestream2 = exports.getLivestream = void 0;
exports.getPlayBackUrl = exports.getLivestream2 = exports.getLivestream = void 0;
var tslib_1 = require("tslib");
var qiniu_live_1 = tslib_1.__importDefault(require("../utils/externalUpload/qiniu_live"));
var sign_1 = require("../utils/sign");
@ -109,7 +109,7 @@ function getLivestream(params, context) {
})];
case 2:
token = (_a.sent()).token;
url = "http://pili.qiniuapi.com/v2/hubs/".concat(hub, "/streams");
url = "https://pili.qiniuapi.com/v2/hubs/".concat(hub, "/streams");
fetch(url, {
method: 'POST',
headers: {
@ -188,3 +188,54 @@ function getStreamObj(config, streamTitle, expireAt) {
});
});
}
// 生成直播回放
function getPlayBackUrl(params, context) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var streamTitle, start, end, config, hub, playBackDomain, encodeStreamTitle, path, bodyStr, contentType, token, url;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
streamTitle = params.streamTitle, start = params.start, end = params.end;
return [4 /*yield*/, getQiniuUploadInfo(context)];
case 1:
config = _a.sent();
hub = config.hub, playBackDomain = config.playBackDomain;
encodeStreamTitle = (0, sign_1.base64ToUrlSafe)(streamTitle);
path = "/v2/hubs/".concat(hub, "/streams/").concat(encodeStreamTitle, "/saveas");
bodyStr = JSON.stringify({
fname: streamTitle,
start: start,
end: end,
});
contentType = 'application/json';
return [4 /*yield*/, getQiniuToken(config, {
method: 'POST',
path: path,
contentType: contentType,
bodyStr: bodyStr,
})];
case 2:
token = (_a.sent()).token;
url = "https://pili.qiniuapi.com".concat(path);
fetch(url, {
method: 'POST',
headers: {
Authorization: token,
'Content-Type': contentType,
},
body: bodyStr,
mode: 'no-cors',
})
.then(function (res) {
console.log(res.json());
}).then(function (res) {
console.log(res);
}).catch(function (e) {
console.log(e);
});
return [2 /*return*/, "https://".concat(playBackDomain, "/").concat(streamTitle, ".m3u8")];
}
});
});
}
exports.getPlayBackUrl = getPlayBackUrl;

View File

@ -76,7 +76,7 @@ var BackendRuntimeContext = /** @class */ (function (_super) {
}, this, {})];
case 3:
result = (_b.sent()).result;
(0, assert_1.default)(result.length > 0, "\u6784\u5EFABackendRuntimeContext\u5BF9\u5E94tokenValue\u300C".concat(tokenValue, "user"));
(0, assert_1.default)(result.length > 0, "\u6784\u5EFABackendRuntimeContext\u5BF9\u5E94tokenValue\u300C".concat(tokenValue, "\u627E\u4E0D\u5230\u76F8\u5173\u7684user"));
token = result[0];
if (token.ableState === 'disabled') {
throw new Exceptions_1.OakTokenExpiredException();

View File

@ -9,6 +9,7 @@ export declare type SystemConfig = {
liveHost?: string;
puhlishDomain?: string;
playDomain?: string;
playBackDomain?: string;
hub?: string;
publisthKey?: string;
playKey?: string;

View File

@ -17,6 +17,7 @@ export declare type SystemConfig = {
liveHost?: string;
puhlishDomain?: string;
playDomain?: string;
playBackDomain?: string;
hub?: string;
publisthKey?: string;
playKey?: string;

View File

@ -95,6 +95,14 @@ type GeneralAspectDict<
| 'expireAt'
>
>;
getPlayBackUrl: (
params: {
streamTitle: string,
start: number,
end: number,
},
context: Cxt
) => Promise<string>;
sendCaptcha: (params: {
mobile: string;
env: WechatMpEnv | WebEnv;

View File

@ -7,7 +7,7 @@ import {
} from './token';
import { getUploadInfo } from './extraFile';
import { getApplication } from './application';
import { getLivestream, getLivestream2 } from './livestream';
import { getLivestream, getLivestream2, getPlayBackUrl } from './livestream';
// import commonAspectDict from 'oak-common-aspect';
export const aspectDict = {
@ -20,6 +20,7 @@ export const aspectDict = {
getApplication,
getLivestream,
getLivestream2,
getPlayBackUrl,
};
// export type AspectDict<ED extends EntityDict & BaseEntityDict> = TokenAD<ED> & CrudAD<ED>;

View File

@ -110,7 +110,7 @@ export async function getLivestream<ED extends EntityDict, Cxt extends RuntimeCo
bodyStr,
});
const url = `http://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
const url = `https://pili.qiniuapi.com/v2/hubs/${hub}/streams`;
fetch(url, {
method: 'POST',
headers: {
@ -207,4 +207,53 @@ async function getStreamObj(
streamKey,
expireAt,
};
}
// 生成直播回放
export async function getPlayBackUrl<ED extends EntityDict, Cxt extends RuntimeContext<ED>>(
params: {
streamTitle: string,
start: number,
end: number,
},
context: Cxt
) {
const { streamTitle, start, end } = params;
// 获取七牛直播云信息
const config = await getQiniuUploadInfo<ED, Cxt>(context);
const { hub, playBackDomain } = config;
// 七牛创建直播流接口路径
const encodeStreamTitle = base64ToUrlSafe(streamTitle);
const path = `/v2/hubs/${hub}/streams/${encodeStreamTitle}/saveas`;
const bodyStr = JSON.stringify({
fname: streamTitle,
start,
end,
})
const contentType = 'application/json';
const { token } = await getQiniuToken(config, {
method: 'POST',
path,
contentType,
bodyStr,
});
const url = `https://pili.qiniuapi.com${path}`;
fetch(url, {
method: 'POST',
headers: {
Authorization: token,
'Content-Type': contentType,
},
body: bodyStr,
mode: 'no-cors',
})
.then((res) => {
console.log(res.json());
}).then((res) => {
console.log(res);
}).catch((e) => {
console.log(e);
})
return `https://${playBackDomain}/${streamTitle}.m3u8`;
}

View File

@ -11,6 +11,7 @@ export type SystemConfig = {
liveHost?: string; // 七牛直播云接口域名
puhlishDomain?: string; // 推流域名
playDomain?: string; // 拉流域名
playBackDomain?: string; // 直播回放存储域名
hub?: string; // 直播空间名,
publisthKey?: string; // 直播空间限时鉴权密钥
playKey?: string; // 拉流密钥