From 908c3eb936be1e4d29f33c19becf07c0cad1d36f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=86=E3=81=95=E3=81=BF=E3=82=87=E3=82=93=28myon2019?= =?UTF-8?q?=29/mtripg6666tdr?= <56076195+mtripg6666tdr@users.noreply.github.com> Date: Fri, 26 Aug 2022 16:45:40 +0900 Subject: [PATCH] Feat: calculate total transforming cost --- src/AudioSource/audiosource.ts | 15 ++++++++++++--- src/Commands/systeminfo.ts | 1 + src/Component/PlayManager.ts | 8 +++++++- src/Component/streams/index.ts | 31 ++++++++++++++++++++++--------- src/botBase.ts | 7 +++++++ 5 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/AudioSource/audiosource.ts b/src/AudioSource/audiosource.ts index edb1418e9..e763210ef 100644 --- a/src/AudioSource/audiosource.ts +++ b/src/AudioSource/audiosource.ts @@ -3,7 +3,7 @@ import type { exportableCustom } from "./custom"; import type { EmbedField } from "eris"; import type { Readable } from "stream"; -type StreamType = +export type StreamType = | "dca" | "ogg" | "webm" @@ -57,5 +57,14 @@ export abstract class AudioSource { } export type StreamInfo = ReadableStreamInfo|UrlStreamInfo; -export type ReadableStreamInfo = {type:"readable", stream:Readable, streamType?:StreamType}; -export type UrlStreamInfo = {type:"url", url:string, streamType?:StreamType, userAgent?:string}; +export type ReadableStreamInfo = { + type:"readable", + stream:Readable, + streamType?:StreamType, +}; +export type UrlStreamInfo = { + type:"url", + url:string, + streamType?:StreamType, + userAgent?:string, +}; diff --git a/src/Commands/systeminfo.ts b/src/Commands/systeminfo.ts index d9bad5eae..28e509415 100644 --- a/src/Commands/systeminfo.ts +++ b/src/Commands/systeminfo.ts @@ -51,6 +51,7 @@ export default class SystemInfo extends BaseCommand { .addField("Version (commit hash)", `\`${options.bot.version}\``, true) .addField("Managed embed toggles", `\`${options.embedPageToggle.length}\``, true) .addField("Guilds that have modified data", `\`${options.bot.queueModifiedGuilds.length}\``, true) + .addField("Current total transforming costs", `\`${options.bot.totalTransformingCost}\``) .setColor(getColor("UPTIME")) .toEris() ); diff --git a/src/Component/PlayManager.ts b/src/Component/PlayManager.ts index e6bfbdfac..816008324 100644 --- a/src/Component/PlayManager.ts +++ b/src/Component/PlayManager.ts @@ -24,6 +24,7 @@ export class PlayManager extends ManagerBase { private _errorUrl = ""; private _preparing = false; private _currentAudioInfo = null as AudioSource; + private _cost = 0; get preparing(){ return this._preparing; @@ -42,6 +43,10 @@ export class PlayManager extends ManagerBase { else return ""; } + get cost(){ + return this._cost; + } + /** * 接続され、再生途中にあるか(たとえ一時停止されていても) */ @@ -148,7 +153,7 @@ export class PlayManager extends ManagerBase { // QueueContentからストリーム情報を取得 const rawStream = await this.currentAudioInfo.fetch(time > 0); // 情報からストリームを作成 - const { stream, streamType } = resolveStreamToPlayable(rawStream, getFFmpegEffectArgs(this.server), this._seek, this.volume !== 100); + const { stream, streamType, cost } = resolveStreamToPlayable(rawStream, getFFmpegEffectArgs(this.server), this._seek, this.volume !== 100); // ストリームがまだ利用できない場合待機 let errorWhileWaiting = null as Error; stream.once("error", e => errorWhileWaiting = e || new Error("An error occurred in stream")); @@ -164,6 +169,7 @@ export class PlayManager extends ManagerBase { } // 各種準備 this._errorReportChannel = mes.channel as TextChannel; + this._cost = cost; const connection = this.server.connection; t.end(); // 再生 diff --git a/src/Component/streams/index.ts b/src/Component/streams/index.ts index 3ecf4770a..fdfda3941 100644 --- a/src/Component/streams/index.ts +++ b/src/Component/streams/index.ts @@ -1,4 +1,4 @@ -import type { ReadableStreamInfo, StreamInfo, UrlStreamInfo } from "../../AudioSource"; +import type { StreamInfo, StreamType, UrlStreamInfo } from "../../AudioSource"; import type { Readable, TransformOptions } from "stream"; import { opus } from "prism-media"; @@ -7,6 +7,15 @@ import Util from "../../Util"; import { InitPassThrough } from "../../Util/general"; import { transformThroughFFmpeg } from "./ffmpeg"; +type PlayableStreamInfo = PartialPlayableStream & { + cost:number, +}; + +type PartialPlayableStream = { + stream:Readable, + streamType:StreamType, +}; + /* Convertion cost: FFmpeg:2 @@ -26,7 +35,7 @@ Refer at: https://github.com/discordjs/discord.js/blob/13baf75cae395353f0528804f * @param volumeTransform whether volume transform is required * @returns if volume transform is required, this will return a stream info that represents Ogg/Webm Opus, otherwise return a stream info represents PCM Opus. */ -export function resolveStreamToPlayable(streamInfo:StreamInfo, effects:string[], seek:number, volumeTransform:boolean):ReadableStreamInfo{ +export function resolveStreamToPlayable(streamInfo:StreamInfo, effects:string[], seek:number, volumeTransform:boolean):PlayableStreamInfo{ const effectEnabled = effects.length !== 0; if((streamInfo.streamType === "webm" || streamInfo.streamType === "ogg") && seek <= 0 && !effectEnabled && !volumeTransform){ // 1. effect is off, volume is off, stream is webm or ogg @@ -34,7 +43,12 @@ export function resolveStreamToPlayable(streamInfo:StreamInfo, effects:string[], // 1 // Total: 1 Util.logger.log(`[StreamResolver] stream edges: raw(${streamInfo.streamType}) (no convertion/cost: 1)`); - return streamInfo.type === "url" ? convertUrlStreamInfoToReadableStreamInfo(streamInfo) : streamInfo; + const info = streamInfo.type === "url" ? convertUrlStreamInfoToReadableStreamInfo(streamInfo) : streamInfo; + return { + stream: info.stream, + streamType: info.streamType, + cost: 1, + }; }else if(!volumeTransform){ // 2. volume is off and stream is any // Unknown --(FFmpeg)--> Ogg/Opus --(Demuxer)--> Opus @@ -49,9 +63,9 @@ export function resolveStreamToPlayable(streamInfo:StreamInfo, effects:string[], .on("close", () => destroyStream(ffmpeg)) ; return { - type: "readable", stream: passThrough, streamType: "ogg", + cost: 3, }; }else if((streamInfo.streamType === "webm" || streamInfo.streamType === "ogg") && !effectEnabled){ // 3. volume is on and stream is webm or ogg @@ -80,9 +94,9 @@ export function resolveStreamToPlayable(streamInfo:StreamInfo, effects:string[], .on("close", () => destroyStream(decoder)) ; return { - type: "readable", stream: passThrough, - streamType: "pcm" + streamType: "pcm", + cost: 4.5, }; }else{ // 4. volume is on and stream is unknown @@ -98,16 +112,15 @@ export function resolveStreamToPlayable(streamInfo:StreamInfo, effects:string[], .on("close", () => destroyStream(ffmpegPCM)) ; return { - type: "readable", stream: passThrough, streamType: "pcm", + cost: 5, }; } } -function convertUrlStreamInfoToReadableStreamInfo(streamInfo:UrlStreamInfo):ReadableStreamInfo{ +function convertUrlStreamInfoToReadableStreamInfo(streamInfo:UrlStreamInfo):PartialPlayableStream{ return { - type: "readable", stream: Util.web.DownloadAsReadable(streamInfo.url, streamInfo.userAgent ? { headers: { "User-Agent": streamInfo.userAgent diff --git a/src/botBase.ts b/src/botBase.ts index 524077be6..8f4b599bc 100644 --- a/src/botBase.ts +++ b/src/botBase.ts @@ -58,6 +58,13 @@ export abstract class MusicBotBase extends LogEmitter { return Object.keys(this.data).length; } + get totalTransformingCost(){ + return Object.keys(this.data) + .map(id => this.data[id].player.cost) + .reduce((prev, current) => prev + current, 0) + ; + } + constructor(protected readonly maintenance:boolean = false){ super(); this.SetTag("Main");