@soga/file-encoder 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +133 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/package.json +51 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import * as _soga_node_types from '@soga/node-types';
|
|
2
|
+
import { UploadInputItem, EncodePrepareResult, SubtitleTrackInfo, AudioTrackConfig, AudioTrackInfo, VideoTrackInfo, CoverInfo, VideoThumbnailInfo, SourceResult, GrouperResult, TxtResult, ImgResult, EncodeResult, PartItem, EncodeWorkerMessage, UploadProgress } from '@soga/node-types';
|
|
3
|
+
import { RecordType, RecordFtype, HostType, ManifestInputMetaInfo, CacheInfo } from '@soga/types';
|
|
4
|
+
import { LowType } from '@soga/lowdb';
|
|
5
|
+
import { MessagePort } from 'node:worker_threads';
|
|
6
|
+
import * as lowdb_lib from 'lowdb/lib';
|
|
7
|
+
|
|
8
|
+
interface Params {
|
|
9
|
+
id: number;
|
|
10
|
+
input: UploadInputItem;
|
|
11
|
+
type: RecordType;
|
|
12
|
+
ftype?: RecordFtype;
|
|
13
|
+
ffmpegPath: string;
|
|
14
|
+
keepPreview: boolean;
|
|
15
|
+
keepSource: boolean;
|
|
16
|
+
outputRoot: string;
|
|
17
|
+
hosts: HostType[];
|
|
18
|
+
subtitles?: string[];
|
|
19
|
+
debug?: boolean;
|
|
20
|
+
port?: MessagePort;
|
|
21
|
+
}
|
|
22
|
+
interface EncoderParams extends Params {
|
|
23
|
+
db: LowType;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class Common {
|
|
27
|
+
protected segmentNames: Record<string, string>;
|
|
28
|
+
protected readonly params: EncoderParams;
|
|
29
|
+
protected readonly id: number;
|
|
30
|
+
protected readonly port: MessagePort | null;
|
|
31
|
+
protected readonly db: LowType;
|
|
32
|
+
protected get lowData(): LowData;
|
|
33
|
+
get isVideo(): boolean;
|
|
34
|
+
get isAudio(): boolean;
|
|
35
|
+
get isMedia(): boolean;
|
|
36
|
+
get isTxt(): boolean;
|
|
37
|
+
get isImg(): boolean;
|
|
38
|
+
protected getSizeLimit(host_type: HostType): number;
|
|
39
|
+
getFilesize(): number;
|
|
40
|
+
constructor(params: EncoderParams);
|
|
41
|
+
protected getPartInfo({ host_type, filepath, start, end, filename, index, }: {
|
|
42
|
+
host_type?: HostType;
|
|
43
|
+
filepath: string;
|
|
44
|
+
start: number;
|
|
45
|
+
end: number;
|
|
46
|
+
filename: string;
|
|
47
|
+
index?: number;
|
|
48
|
+
}, final?: boolean): Promise<PartItem>;
|
|
49
|
+
protected getStore(jsonFileName: string): Promise<lowdb_lib.Low<Record<string, unknown>>>;
|
|
50
|
+
postProgress(progress: {
|
|
51
|
+
type: string;
|
|
52
|
+
percent: number;
|
|
53
|
+
}): Promise<void>;
|
|
54
|
+
protected postMessage(data: EncodeWorkerMessage): Promise<void>;
|
|
55
|
+
protected setKeeps(keeps: {
|
|
56
|
+
preview: boolean;
|
|
57
|
+
source: boolean;
|
|
58
|
+
}): Promise<void>;
|
|
59
|
+
get keeps(): {
|
|
60
|
+
preview: boolean;
|
|
61
|
+
source: boolean;
|
|
62
|
+
};
|
|
63
|
+
protected setMeta(meta: ManifestInputMetaInfo): Promise<void>;
|
|
64
|
+
get meta(): ManifestInputMetaInfo;
|
|
65
|
+
protected setSourceResult(data: SourceResult): Promise<void>;
|
|
66
|
+
get sourceResult(): SourceResult;
|
|
67
|
+
protected setPrepareResult(result: EncodePrepareResult): Promise<void>;
|
|
68
|
+
get prepareResult(): Partial<Record<UploadProgress, {
|
|
69
|
+
weight: number;
|
|
70
|
+
percent: number;
|
|
71
|
+
}>>;
|
|
72
|
+
protected setMd5(md5: string): Promise<void>;
|
|
73
|
+
get md5(): string;
|
|
74
|
+
protected setSubtitleEncoderResult(data: SubtitleTrackInfo[]): Promise<void>;
|
|
75
|
+
get subtitleEncoderResult(): SubtitleTrackInfo[];
|
|
76
|
+
protected setAudioSeparatorResult(data: AudioTrackConfig[]): Promise<void>;
|
|
77
|
+
get audioSeparatorResult(): AudioTrackConfig[];
|
|
78
|
+
protected setAudioTranscoderResult(data: AudioTrackInfo[]): Promise<void>;
|
|
79
|
+
get audioTranscoderResult(): AudioTrackInfo[];
|
|
80
|
+
protected setCoverResult(data: CoverInfo): Promise<void>;
|
|
81
|
+
get coverResult(): CoverInfo;
|
|
82
|
+
protected setVideoTranscoderResult(data: VideoTrackInfo): Promise<void>;
|
|
83
|
+
get videoTranscoderResult(): VideoTrackInfo;
|
|
84
|
+
protected setVideoThumbnailerResult(data: VideoThumbnailInfo): Promise<void>;
|
|
85
|
+
get videoThumbnailerResult(): VideoThumbnailInfo;
|
|
86
|
+
protected setGrouperResult(data: GrouperResult): Promise<void>;
|
|
87
|
+
get grouperResult(): GrouperResult;
|
|
88
|
+
protected setImgResult(data: ImgResult): Promise<void>;
|
|
89
|
+
get imgResult(): ImgResult;
|
|
90
|
+
protected setTxtResult(data: TxtResult): Promise<void>;
|
|
91
|
+
get txtResult(): TxtResult;
|
|
92
|
+
protected setResult(data: EncodeResult): Promise<void>;
|
|
93
|
+
get result(): EncodeResult;
|
|
94
|
+
protected _syncGetId({ file, start, end }: IdKeyParams, type: TypeParams): string;
|
|
95
|
+
protected _syncSetIdMap({ id, file, start, end }: CacheInfo, type: TypeParams, host_type: HostType): void;
|
|
96
|
+
}
|
|
97
|
+
type TypeParams = 'preview' | 'source';
|
|
98
|
+
type IdKeyParams = {
|
|
99
|
+
file: string;
|
|
100
|
+
start?: number;
|
|
101
|
+
end?: number;
|
|
102
|
+
};
|
|
103
|
+
type LowData = {
|
|
104
|
+
keeps: {
|
|
105
|
+
preview: boolean;
|
|
106
|
+
source: boolean;
|
|
107
|
+
};
|
|
108
|
+
meta: ManifestInputMetaInfo;
|
|
109
|
+
prepare_result: EncodePrepareResult;
|
|
110
|
+
subtitle_encoder_result: SubtitleTrackInfo[];
|
|
111
|
+
audio_separator_result: AudioTrackConfig[];
|
|
112
|
+
audio_transcoder_result: AudioTrackInfo[];
|
|
113
|
+
video_transcoder_result: VideoTrackInfo;
|
|
114
|
+
cover_result: CoverInfo;
|
|
115
|
+
video_thumbnailer_result: VideoThumbnailInfo;
|
|
116
|
+
source_result: SourceResult;
|
|
117
|
+
grouper_result: GrouperResult;
|
|
118
|
+
txt_result: TxtResult;
|
|
119
|
+
img_result: ImgResult;
|
|
120
|
+
result: EncodeResult;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
declare class Prepare extends Common {
|
|
124
|
+
start(): Promise<void>;
|
|
125
|
+
private checkStorage;
|
|
126
|
+
private calculateMeta;
|
|
127
|
+
private calculateProgress;
|
|
128
|
+
}
|
|
129
|
+
declare const getPrepare: (params: Params) => Promise<Prepare>;
|
|
130
|
+
|
|
131
|
+
declare const encode: (params: Params) => Promise<_soga_node_types.EncodeResult>;
|
|
132
|
+
|
|
133
|
+
export { encode, getPrepare };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import * as _soga_node_types from '@soga/node-types';
|
|
2
|
+
import { UploadInputItem, EncodePrepareResult, SubtitleTrackInfo, AudioTrackConfig, AudioTrackInfo, VideoTrackInfo, CoverInfo, VideoThumbnailInfo, SourceResult, GrouperResult, TxtResult, ImgResult, EncodeResult, PartItem, EncodeWorkerMessage, UploadProgress } from '@soga/node-types';
|
|
3
|
+
import { RecordType, RecordFtype, HostType, ManifestInputMetaInfo, CacheInfo } from '@soga/types';
|
|
4
|
+
import { LowType } from '@soga/lowdb';
|
|
5
|
+
import { MessagePort } from 'node:worker_threads';
|
|
6
|
+
import * as lowdb_lib from 'lowdb/lib';
|
|
7
|
+
|
|
8
|
+
interface Params {
|
|
9
|
+
id: number;
|
|
10
|
+
input: UploadInputItem;
|
|
11
|
+
type: RecordType;
|
|
12
|
+
ftype?: RecordFtype;
|
|
13
|
+
ffmpegPath: string;
|
|
14
|
+
keepPreview: boolean;
|
|
15
|
+
keepSource: boolean;
|
|
16
|
+
outputRoot: string;
|
|
17
|
+
hosts: HostType[];
|
|
18
|
+
subtitles?: string[];
|
|
19
|
+
debug?: boolean;
|
|
20
|
+
port?: MessagePort;
|
|
21
|
+
}
|
|
22
|
+
interface EncoderParams extends Params {
|
|
23
|
+
db: LowType;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class Common {
|
|
27
|
+
protected segmentNames: Record<string, string>;
|
|
28
|
+
protected readonly params: EncoderParams;
|
|
29
|
+
protected readonly id: number;
|
|
30
|
+
protected readonly port: MessagePort | null;
|
|
31
|
+
protected readonly db: LowType;
|
|
32
|
+
protected get lowData(): LowData;
|
|
33
|
+
get isVideo(): boolean;
|
|
34
|
+
get isAudio(): boolean;
|
|
35
|
+
get isMedia(): boolean;
|
|
36
|
+
get isTxt(): boolean;
|
|
37
|
+
get isImg(): boolean;
|
|
38
|
+
protected getSizeLimit(host_type: HostType): number;
|
|
39
|
+
getFilesize(): number;
|
|
40
|
+
constructor(params: EncoderParams);
|
|
41
|
+
protected getPartInfo({ host_type, filepath, start, end, filename, index, }: {
|
|
42
|
+
host_type?: HostType;
|
|
43
|
+
filepath: string;
|
|
44
|
+
start: number;
|
|
45
|
+
end: number;
|
|
46
|
+
filename: string;
|
|
47
|
+
index?: number;
|
|
48
|
+
}, final?: boolean): Promise<PartItem>;
|
|
49
|
+
protected getStore(jsonFileName: string): Promise<lowdb_lib.Low<Record<string, unknown>>>;
|
|
50
|
+
postProgress(progress: {
|
|
51
|
+
type: string;
|
|
52
|
+
percent: number;
|
|
53
|
+
}): Promise<void>;
|
|
54
|
+
protected postMessage(data: EncodeWorkerMessage): Promise<void>;
|
|
55
|
+
protected setKeeps(keeps: {
|
|
56
|
+
preview: boolean;
|
|
57
|
+
source: boolean;
|
|
58
|
+
}): Promise<void>;
|
|
59
|
+
get keeps(): {
|
|
60
|
+
preview: boolean;
|
|
61
|
+
source: boolean;
|
|
62
|
+
};
|
|
63
|
+
protected setMeta(meta: ManifestInputMetaInfo): Promise<void>;
|
|
64
|
+
get meta(): ManifestInputMetaInfo;
|
|
65
|
+
protected setSourceResult(data: SourceResult): Promise<void>;
|
|
66
|
+
get sourceResult(): SourceResult;
|
|
67
|
+
protected setPrepareResult(result: EncodePrepareResult): Promise<void>;
|
|
68
|
+
get prepareResult(): Partial<Record<UploadProgress, {
|
|
69
|
+
weight: number;
|
|
70
|
+
percent: number;
|
|
71
|
+
}>>;
|
|
72
|
+
protected setMd5(md5: string): Promise<void>;
|
|
73
|
+
get md5(): string;
|
|
74
|
+
protected setSubtitleEncoderResult(data: SubtitleTrackInfo[]): Promise<void>;
|
|
75
|
+
get subtitleEncoderResult(): SubtitleTrackInfo[];
|
|
76
|
+
protected setAudioSeparatorResult(data: AudioTrackConfig[]): Promise<void>;
|
|
77
|
+
get audioSeparatorResult(): AudioTrackConfig[];
|
|
78
|
+
protected setAudioTranscoderResult(data: AudioTrackInfo[]): Promise<void>;
|
|
79
|
+
get audioTranscoderResult(): AudioTrackInfo[];
|
|
80
|
+
protected setCoverResult(data: CoverInfo): Promise<void>;
|
|
81
|
+
get coverResult(): CoverInfo;
|
|
82
|
+
protected setVideoTranscoderResult(data: VideoTrackInfo): Promise<void>;
|
|
83
|
+
get videoTranscoderResult(): VideoTrackInfo;
|
|
84
|
+
protected setVideoThumbnailerResult(data: VideoThumbnailInfo): Promise<void>;
|
|
85
|
+
get videoThumbnailerResult(): VideoThumbnailInfo;
|
|
86
|
+
protected setGrouperResult(data: GrouperResult): Promise<void>;
|
|
87
|
+
get grouperResult(): GrouperResult;
|
|
88
|
+
protected setImgResult(data: ImgResult): Promise<void>;
|
|
89
|
+
get imgResult(): ImgResult;
|
|
90
|
+
protected setTxtResult(data: TxtResult): Promise<void>;
|
|
91
|
+
get txtResult(): TxtResult;
|
|
92
|
+
protected setResult(data: EncodeResult): Promise<void>;
|
|
93
|
+
get result(): EncodeResult;
|
|
94
|
+
protected _syncGetId({ file, start, end }: IdKeyParams, type: TypeParams): string;
|
|
95
|
+
protected _syncSetIdMap({ id, file, start, end }: CacheInfo, type: TypeParams, host_type: HostType): void;
|
|
96
|
+
}
|
|
97
|
+
type TypeParams = 'preview' | 'source';
|
|
98
|
+
type IdKeyParams = {
|
|
99
|
+
file: string;
|
|
100
|
+
start?: number;
|
|
101
|
+
end?: number;
|
|
102
|
+
};
|
|
103
|
+
type LowData = {
|
|
104
|
+
keeps: {
|
|
105
|
+
preview: boolean;
|
|
106
|
+
source: boolean;
|
|
107
|
+
};
|
|
108
|
+
meta: ManifestInputMetaInfo;
|
|
109
|
+
prepare_result: EncodePrepareResult;
|
|
110
|
+
subtitle_encoder_result: SubtitleTrackInfo[];
|
|
111
|
+
audio_separator_result: AudioTrackConfig[];
|
|
112
|
+
audio_transcoder_result: AudioTrackInfo[];
|
|
113
|
+
video_transcoder_result: VideoTrackInfo;
|
|
114
|
+
cover_result: CoverInfo;
|
|
115
|
+
video_thumbnailer_result: VideoThumbnailInfo;
|
|
116
|
+
source_result: SourceResult;
|
|
117
|
+
grouper_result: GrouperResult;
|
|
118
|
+
txt_result: TxtResult;
|
|
119
|
+
img_result: ImgResult;
|
|
120
|
+
result: EncodeResult;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
declare class Prepare extends Common {
|
|
124
|
+
start(): Promise<void>;
|
|
125
|
+
private checkStorage;
|
|
126
|
+
private calculateMeta;
|
|
127
|
+
private calculateProgress;
|
|
128
|
+
}
|
|
129
|
+
declare const getPrepare: (params: Params) => Promise<Prepare>;
|
|
130
|
+
|
|
131
|
+
declare const encode: (params: Params) => Promise<_soga_node_types.EncodeResult>;
|
|
132
|
+
|
|
133
|
+
export { encode, getPrepare };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var t,e=Object.create,a=Object.defineProperty,i=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,r=Object.getPrototypeOf,o=Object.prototype.hasOwnProperty,n=(t,e,r,n)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let h of s(e))o.call(t,h)||h===r||a(t,h,{get:()=>e[h],enumerable:!(n=i(e,h))||n.enumerable});return t},h=(t,i,s)=>(s=null!=t?e(r(t)):{},n(!i&&t&&t.__esModule?s:a(s,"default",{value:t,enumerable:!0}),t)),d={};((t,e)=>{for(var i in e)a(t,i,{get:e[i],enumerable:!0})})(d,{encode:()=>ke,getPrepare:()=>De}),module.exports=(t=d,n(a({},"__esModule",{value:!0}),t));var c=require("@soga/error"),l=require("@soga/lowdb"),u=require("crypto"),p=require("fs-extra"),g=require("fs/promises"),w=require("path"),m=require("stream/promises");function f(t){const e=(0,u.createHash)("md5");return e.update(`${t}`),e.digest("hex")}async function _(t){await new Promise((e,a)=>{(async()=>{const i=(0,w.resolve)(t.outputRoot,t.filename);await(0,p.remove)(i);let s=!1;const r=(0,p.createWriteStream)(i);r.on("open",()=>{s=!0}).on("error",async t=>{s&&r.close(),await(0,p.remove)(i),a(t)});const{length:o}=t.files,n=async(e=0)=>{if(e<o){const a=t.files[e],o=t.files.length;await new Promise((t,e)=>{const n=(0,p.createReadStream)(a);n.pipe(r,{end:!o}),n.on("end",()=>{n.close(),t(!0)}),n.on("error",async t=>{n.destroy(),s&&r.close(),await(0,p.remove)(i),e(t)})}),await n(e+1)}};await n(0),s&&r.end(),e(!0)})()})}async function y(t,e){const a=f(JSON.stringify({...t,dbName:e})),i="db_unique_key",s=(0,w.resolve)(t.outputRoot,e),r=await(0,l.getDb)(s,{});return r.data[i]?r.data[i]!=a&&(r.data={[i]:a},await r.write()):(r.data[i]=a,await r.write()),r}async function b(t){return await y({file_id:t.id,input:{filepath:t.input.filepath,filesize:t.input.filesize},outputRoot:t.outputRoot},"encoder_store.json")}async function v({input_path:t,target_path:e,start:a,end:i}){const s=(0,p.createReadStream)(t,{start:a,end:i,highWaterMark:65536}),r=(0,p.createWriteStream)(e);try{await(0,m.pipeline)(s,r)}catch(t){try{(0,p.existsSync)(e)&&await(0,p.remove)(e)}catch(t){console.warn("Failed to clean up incomplete file:",t.message)}throw t}}var P=require("path"),x=require("@soga/utils"),z=require("@soga/fileutils"),T=require("@soga/error"),R=require("@soga/node-types"),S=require("fs-extra"),D=require("@soga/types"),M=2097152,I={[D.HostType.BAIDU]:52428800,[D.HostType.ALI]:2147483648},F=(D.HostType.BAIDU,D.HostType.ALI,require("@soga/types")),$=require("@soga/utils"),k=require("worker_threads"),q=class{segmentNames={};params;id;port=null;db;get lowData(){return this.db.data}get isVideo(){return this.params.type==F.RecordType.VIDEO}get isAudio(){return this.params.type==F.RecordType.AUDIO}get isMedia(){return this.isAudio||this.isVideo}get isTxt(){return this.params.type==F.RecordType.DOC&&this.params.ftype==F.RecordFtype.DOC_TXT}get isImg(){return this.params.type==F.RecordType.IMAGE}getSizeLimit(t){return I[t]||52428800}getFilesize(){return this.params.input.filesize}constructor(t){this.params=t,this.id=t.id,this.port=t.port??null,this.db=t.db}async getPartInfo({host_type:t,filepath:e,start:a,end:i,filename:s,index:r},o=!0){const n={start:a,end:i,size:i-a+1,path:e,index:r,file:s,md5:o?await(0,$.calculateMd5)({file:e,start:a,end:i}):""};if(o){if(t===F.HostType.BAIDU){const t=await(0,$.calculateMd4)({file:e,start:a,end:i});n.md4=t}if(t===F.HostType.ALI){const t=await(0,$.calculateSha1)({file:e,start:a,end:i});n.sha1=t}}return n}async getStore(t){const{id:e,input:a,outputRoot:i}=this.params;return await y({file_id:e,input:{filepath:a.filepath,filesize:a.filesize},outputRoot:i},t)}async postProgress(t){const e={step:t.type,percent:t.percent};await this.postMessage({id:this.id,type:"percent",data:e})}async postMessage(t){this.port?this.port.postMessage(t):k.parentPort&&k.parentPort.postMessage(t)}async setKeeps(t){this.lowData.keeps=t,await this.db.write()}get keeps(){return this.lowData.keeps}async setMeta(t){this.lowData.meta=t,await this.db.write()}get meta(){return this.lowData.meta}async setSourceResult(t){this.lowData.source_result=t,await this.db.write()}get sourceResult(){return this.lowData.source_result}async setPrepareResult(t){this.lowData.prepare_result=t,await this.db.write()}get prepareResult(){return this.lowData.prepare_result}async setMd5(t){this.lowData.meta.md5=t,await this.db.write()}get md5(){return this.lowData.meta.md5}async setSubtitleEncoderResult(t){this.lowData.subtitle_encoder_result=t,await this.db.write()}get subtitleEncoderResult(){return this.lowData.subtitle_encoder_result}async setAudioSeparatorResult(t){this.lowData.audio_separator_result=t,await this.db.write()}get audioSeparatorResult(){return this.lowData.audio_separator_result}async setAudioTranscoderResult(t){this.lowData.audio_transcoder_result=t,await this.db.write()}get audioTranscoderResult(){return this.lowData.audio_transcoder_result}async setCoverResult(t){this.lowData.cover_result=t,await this.db.write()}get coverResult(){return this.lowData.cover_result}async setVideoTranscoderResult(t){this.lowData.video_transcoder_result=t,await this.db.write()}get videoTranscoderResult(){return this.lowData.video_transcoder_result}async setVideoThumbnailerResult(t){this.lowData.video_thumbnailer_result=t,await this.db.write()}get videoThumbnailerResult(){return this.lowData.video_thumbnailer_result}async setGrouperResult(t){this.lowData.grouper_result=t,await this.db.write()}get grouperResult(){return this.lowData.grouper_result}async setImgResult(t){this.lowData.img_result=t,await this.db.write()}get imgResult(){return this.lowData.img_result}async setTxtResult(t){this.lowData.txt_result=t,await this.db.write()}get txtResult(){return this.lowData.txt_result}async setResult(t){this.lowData.result=t,await this.db.write()}get result(){return this.lowData.result}_syncGetId({file:t,start:e,end:a},i){const s=`${i}_key_index`,r=`${i}_key_map`,o=`${t}_${e||0}_${a||0}`,n=this.db.data[r]||{};if(n[o])return n[o];this.db.data[s]=this.db.data[s]||0,this.db.data[r]=this.db.data[r]||{};const h=this.db.data[s]+1,d=`id_${h}`;return this.db.data[r][o]=d,this.db.data[s]=h,d}_syncSetIdMap({id:t,file:e,start:a,end:i},s,r){const o=`${s}_${r}_id_map`;this.db.data[o]=this.db.data[o]||{},this.db.data[o][t]={f:e,s:a,e:i}}},E=class extends q{syncGetSourceId(t){return this._syncGetId(t,"source")}async getSourceId(t){const e=this.syncGetSourceId(t);return await this.db.write(),e}getSourceIdMap(t){return this.db.data[`source_${t}_id_map`]||{}}syncSetSourceIdMap(t,e){this._syncSetIdMap(t,"source",e)}async setSourceIdMap(t,e){this.syncSetSourceIdMap(t,e),await this.db.write()}getSourceSegmentName=(t,e)=>{const a=`source_${e}_${t}`;if(this.segmentNames[a])return this.segmentNames[a];const i=`s-${f(`source-${e}-${this.md5}-${t}`)}`;return this.segmentNames[a]=i,i}},N=class extends E{head_size=32;getZipFilePath(){return(0,P.resolve)(this.params.outputRoot,"souce_zip.bin")}getDownloadListFileName(t){return`source_${t}_download_list.json`}getPartName(t,e){return this.getSourceSegmentName(e,t)}getPartPath(t,e){return(0,P.resolve)(this.params.outputRoot,this.getPartName(t,e))}get dbData(){return this.db.data}async setPartList(t,e){const a=`source_${t}_part_list`;this.dbData[a]=e,await this.params.db.write()}getPartList(t){const e=`source_${t}_part_list`;return this.dbData[e]}async setDownloadMap(t,e){const a=`source_${t}_download_map`;this.dbData[a]=e,await this.params.db.write()}getDownloadMap(t){const e=`source_${t}_download_map`;return this.dbData[e]}async sendProgress(t){await this.postProgress({type:R.UploadProgress.transcode_source,percent:t})}async setDownloadList(t,e){const a=`source_${t}_download_list`;this.dbData[a]=e,await this.params.db.write()}getDownloadList(t){const e=`source_${t}_download_list`;return this.dbData[e]}async start(){try{if(this.sourceResult)return await this.sendProgress(1),this.sourceResult;await this.gzip();const{length:t}=this.params.hosts;for(let e=0;e<t;e++){const t=this.params.hosts[e];await this.calculatePartList(t),await this.processDownloadMap(t)}await this.sendProgress(.9);const e=await this.getResult();return await this.sendProgress(1),e}catch(t){throw(0,T.buildDError)(t,{message:"Error occurred during source encoding",detail:`Error occurred during source encoding: ${this.params.input.filepath}`})}}async gzip(){if(this.dbData.source_gziped)return;const t=this.params.input.filepath,e=this.getZipFilePath();await(0,x.gzip)(t,e,async({percent:t})=>{await this.sendProgress(.6*t)}),this.dbData.source_gziped=!0,await this.params.db.write()}async getResult(){if(this.sourceResult)return this.sourceResult;const t={meta:await this.getMetaData(),data:{}},{length:e}=this.params.hosts;for(let a=0;a<e;a++){const e=this.params.hosts[a],i=this.getPartList(e),s=this.getDownloadMap(e);t.data[e]={download:s,parts:i}}return await this.setSourceResult(t),t}async getMetaData(){const t="source_meta",e=this.dbData[t];if(e)return e;const a=this.getZipFilePath(),i=await(0,z.getFileSize)(a),s={path:a,start:0,end:0},{head_size:r}=this;s.end=i<=r?i-1:r-1;const o={head:(await(0,x.getFileBufferSlice)(s.path,s.start,s.end)).toString("base64")};return this.dbData[t]=o,await this.params.db.write(),o}async writeDownloadListFile(t,e){const a=this.getDownloadListFileName(t),i=(0,P.resolve)(this.params.outputRoot,a);await(0,S.writeFile)(i,e,"utf-8");return{file_path:i,size:await(0,z.getFileSize)(i)}}async processDownloadMap(t){const e=this.getDownloadMap(t);if(e)return e;const a=this.getDownloadList(t);let i;const{file_path:s,size:r}=await this.writeDownloadListFile(t,JSON.stringify(a)),o=this.getSizeLimit(t),n=this.getPartList(t);if(n.length){const e=n[n.length-1],{path:a,size:h,file:d,index:c,end:l,start:u}=e,g=(0,P.resolve)(this.params.outputRoot,d);if(h+r<=o){await async function({source1:t,source2:e,target:a}){const i=(0,p.createReadStream)(t.filepath,{start:t.start,end:t.end}),s=(0,p.createWriteStream)(a);await(0,m.pipeline)(i,s);const r=(0,p.createReadStream)(e),o=(0,p.createWriteStream)(a,{flags:"a"});await(0,m.pipeline)(r,o)}({source1:{filepath:a,start:u,end:l},source2:s,target:g});const e=(await(0,S.stat)(g)).size,o=e-1,h=e-r,w=await this.getPartInfo({host_type:t,filepath:g,start:0,end:e-1,filename:d,index:c});n[n.length-1]=w;i={id:await this.getSourceId({file:d,start:h,end:o}),file:d,start:h,end:o}}else{const e=c+1,a=this.getPartName(t,e),o=this.getPartPath(t,e);await(0,S.rename)(s,o);const h=await this.getSourceId({file:a,start:0,end:r-1}),d=await this.getPartInfo({host_type:t,filepath:o,start:0,end:r-1,filename:a,index:e});n.push(d),i={id:h,file:a,start:0,end:r-1}}return await this.setPartList(t,n),await this.setDownloadMap(t,i),i}}async calculatePartList(t){const e=`source_${t}_list_calculated`;if(this.dbData[e])return;const a=this.getZipFilePath(),i=await(0,z.getFileSize)(a),s=[],r=this.getSizeLimit(t),{head_size:o}=this,n=[];if(i>o){let e=0;for(let h=o;h<=i-1;h+=r){const o=Math.min(h+r-1,i-1),d=this.getPartName(t,e),c=await this.getPartInfo({host_type:t,filepath:a,start:h,end:o,filename:d,index:e});let l=0;for(let t=h;t<o;t+=M){const e=Math.min(t+M-1,o),a=e-t+1,i=l+a-1,s=await this.getSourceId({file:"source_zip",start:t,end:e});n.push({id:s,file:d,start:l,end:i}),l+=a}s.push(c),e++}}await this.setPartList(t,s),await this.setDownloadList(t,n),this.dbData[e]=!0,await this.db.write()}},U=require("path"),L=require("fs-extra"),C=require("@soga/utils"),A=h(require("zlib")),O=require("@soga/utils"),V=require("@soga/error"),G=require("@soga/node-types"),B=require("path"),j=require("@soga/fileutils"),X=require("fs-extra"),H=class extends q{get preview_common_db_data(){return this.db.data}async getCurrentFileIndex(t){const e=this.db.data[`preview_${t}_current_index`];return"number"!=typeof e?(this.db.data[`preview_${t}_current_index`]=0,await this.db.write(),0):e}async increaseCurrentFileIndex(t){const e=await this.getCurrentFileIndex(t)+1;return this.db.data[`preview_${t}_current_index`]=e,await this.db.write(),e}getPartName(t,e){return this.getPreviewSegmentName(e,t)}getPartPath(t,e){return(0,B.resolve)(this.params.outputRoot,this.getPartName(t,e))}syncGetPreviewId(t){return this._syncGetId(t,"preview")}async getPreviewId(t){const e=this.syncGetPreviewId(t);return await this.db.write(),e}getPreviewIdMap(t){return this.db.data[`preview_${t}_id_map`]||{}}syncSetPreviewIdMap(t,e){this._syncSetIdMap(t,"preview",e)}async setPreviewIdMap(t,e){this.syncSetPreviewIdMap(t,e),await this.db.write()}getPreviewSegmentName=(t,e)=>{const a=`preview_${e}_${t}`;if(this.segmentNames[a])return this.segmentNames[a];const i=`p-${f(`preview-${e}-${this.md5}-${t}`)}`;return this.segmentNames[a]=i,i};async calculatePartList(t,e){const a=[],i=await this.getCurrentFileIndex(t);for(let s=0;s<i+1;s++){const i=this.getPartName(t,s),r=this.getPartPath(t,s),o=await(0,j.getFileSize)(r),n=await this.getPartInfo({host_type:t,filename:i,filepath:r,index:s,start:0,end:o-1},e);a.push(n)}return a}getPartListKey(t){return`preview_${t}_part_list`}async completePartList(t){const e=await this.getPartList(t);if(e){const a=[];for(const i of e)if(i.md5)a.push(i);else{const e=await this.getPartInfo({filename:i.file,filepath:i.path,start:i.start,end:i.end,host_type:t,index:i.index},!0);a.push(e)}await this.setPartList(t,a)}}async getPartList(t){const e=this.getPartListKey(t),a=this.preview_common_db_data[e];if(a)return a}async setPartList(t,e){const a=this.getPartListKey(t);this.preview_common_db_data[a]=e,await this.db.write()}async attachCacheData(){const{hosts:t}=this.params;for(const e of t)await this.attachHostCacheData(e),await this.completePartList(e)}getCacheInfo(t){const e=`preview_${t}_cache_info`;return this.preview_common_db_data[e]}async writeCacheFile(t,e){const a=`preview_${t}_cache_info.txt`,i=(0,B.resolve)(this.params.outputRoot,a);await(0,X.writeFile)(i,e,"utf-8");return{file_path:i,size:await(0,j.getFileSize)(i)}}async setCacheInfo(t,e){const a=`preview_${t}_cache_info`;this.preview_common_db_data[a]=e,await this.db.write()}async attachHostCacheData(t){if(this.getCacheInfo(t))return;const e=await this.getPartList(t),a=this.getPreviewIdMap(t),{file_path:i,size:s}=await this.writeCacheFile(t,JSON.stringify(a)),r=this.getSizeLimit(t);if(e.length){const a=e[e.length-1],{path:o,size:n,file:h,index:d,end:c}=a;let l;if(n+s<=r){await async function({filepath:t,size:e},a){(await(0,p.stat)(t)).size>e&&await(0,g.truncate)(t,e);const i=(0,p.createReadStream)(a),s=(0,p.createWriteStream)(t,{flags:"a"});await(0,m.pipeline)(i,s)}({filepath:o,size:n},i);const a=await(0,j.getFileSize)(o),r=await this.getPartInfo({host_type:t,filename:h,filepath:o,index:d,start:0,end:a-1});e[e.length-1]=r;const u=c+1,w=c+s;l={id:await this.getPreviewId({file:h,start:u,end:w}),file:h,start:u,end:w}}else{const a=d+1,r=this.getPartName(t,a),o=this.getPartPath(t,a);await(0,X.copy)(i,o);const n=await this.getPreviewId({file:r,start:0,end:s-1}),h=await this.getPartInfo({host_type:t,filename:r,filepath:o,index:a,start:0,end:s-1},!1);e.push(h),await this.setPartList(t,e),l={id:n,file:r,start:0,end:s-1}}l&&await this.setCacheInfo(t,l)}}},W=class extends H{content_size_1=81920;content_size_2=102400;totalPage=1;hashBuffer=Buffer.from("dpan");get hashBufferLength(){return this.hashBuffer.length}getU8FileName(){return`text_utf8_${this.params.id}.txt`}getU8FilePath(){return(0,U.resolve)(this.params.outputRoot,this.getU8FileName())}async sendProgress(t){await this.postProgress({type:G.UploadProgress.transcode_txt,percent:t})}get dbData(){return this.db.data}async start(){try{if(this.dbData.txt_result)return await this.sendProgress(1),this.dbData.txt_result;await this.txtConvertToUtf8File(),await this.sendProgress(.2);const{length:t}=this.params.hosts;for(let e=0;e<t;e++){const a=this.params.hosts[e];await this.txtConvertToGzipFile(a),await this.sendProgress(.2+(e+1)/t*.6)}await this.attachCacheData();const e=await this.getResult();return await this.clean(),await this.sendProgress(1),e}catch(t){throw(0,V.buildDError)(t,{message:"Error occurred during txt encoding",detail:`Error occurred during txt encoding: ${this.params.input.filepath}`})}}async getResult(){if(this.txtResult)return this.txtResult;const t={meta:{pad:this.hashBufferLength,pages:this.totalPage},data:{}};for(const e of this.params.hosts)t.data[e]={cache:this.getCacheInfo(e),parts:await this.getPartList(e),entrance:await this.getEntranceInfo(e)};return await this.setTxtResult(t),t}async clean(){try{if(this.params.debug)return;const t=this.getU8FilePath();await(0,L.remove)(t)}catch(t){}}async setEntranceInfo(t,e){const a=`txt_${t}_entrance`;this.dbData[a]=e,await this.db.write()}async getEntranceInfo(t){const e=`txt_${t}_entrance`,a=this.dbData[e];if(a)return a}async txtConvertToUtf8File(){if(this.dbData.txt_utf8_converted)return;const t=this.params.input.filepath,e=this.getU8FilePath();await(0,O.saveFileAsUtf8)(t,e),this.dbData.txt_utf8_converted=!0,await this.db.write()}async txtConvertToGzipFile(t){if(await this.getEntranceInfo(t))return;const e=this.getSizeLimit(t),a=this.getU8FilePath(),i=await this.calculateSlice(),{length:s}=i,r={};let o=0,n=(0,L.createWriteStream)(this.getPartPath(t,await this.getCurrentFileIndex(t)));for(let h=0;h<s;h++){const d=h==s-1?0:h+1,c=i[d],{index:l,start:u,end:p}=c,g={page:l+1,text:(await(0,C.getFileBufferSlice)(a,u,p)).toString("utf8")},w=JSON.stringify(g);let m=Buffer.from(w,"utf8");if(0==d){const t={...g,map:r};m=Buffer.from(JSON.stringify(t),"utf8")}const f=await this.getPreviewId({file:"u8zip",start:u,end:p});await new Promise((a,i)=>{A.default.gzip(m,async(s,h)=>{if(s)return i(s);const c=h.length<this.hashBufferLength?this.hashBuffer:h.subarray(0,this.hashBufferLength),l=Buffer.concat([c,h]),u=l.length;if(o+u>e){n.end();const e=await this.increaseCurrentFileIndex(t);n=(0,L.createWriteStream)(this.getPartPath(t,e)),o=0}const p=o,g=o+u-1;if(n.write(l),o+=u,0==d){n.end();const e={id:f,start:p,end:g,file:this.getPartName(t,await this.getCurrentFileIndex(t))};await this.setEntranceInfo(t,e)}else r[`p_${d+1}`]={id:f,f:this.getPartName(t,await this.getCurrentFileIndex(t)),s:p,e:g};this.syncSetPreviewIdMap({id:f,file:this.getPartName(t,await this.getCurrentFileIndex(t)),start:p,end:g},t),a(!0)})})}await this.db.write();const h=await this.calculatePartList(t,!1);await this.setPartList(t,h)}async calculateSlice(){if(this.dbData.txt_slice_list)return this.dbData.txt_slice_list;const t=this.getU8FilePath(),e=await new Promise((e,a)=>{(0,L.readFile)(t,"utf8",(t,i)=>{if(t)return void a(t);const s=this.content_size_1,r=this.content_size_2,o=[];let n=0,h=0,d=0;for(;h<i.length;){let t=Math.min(h+r,i.length);const e=Math.min(h+s,i.length),a=i.slice(e,t-1).indexOf("#");-1!==a&&(t=e+a);const c=i.slice(h,t),l=Buffer.byteLength(c);o.push({index:n++,start:d,end:d+l-1}),this.totalPage=n,h=t,d+=l}e(o)})});return this.dbData.txt_slice_list=e,await this.db.write(),e}},K=require("path"),J=require("@soga/imgutils"),Q=require("@soga/utils"),Z=require("@soga/fileutils"),Y=require("@soga/error"),tt=require("@soga/node-types"),et=require("fs-extra"),at=class extends H{getCompressFileName(){return"img_compress.jpg"}getCompressFilePath(){return(0,K.resolve)(this.params.outputRoot,this.getCompressFileName())}getGzFileName(){return"compressed_img.zip"}getGzFilePath(){return(0,K.resolve)(this.params.outputRoot,this.getGzFileName())}async sendProgress(t){await this.postProgress({type:tt.UploadProgress.transcode_img,percent:t})}get dbData(){return this.db.data}async start(){try{if(this.imgResult)return await this.sendProgress(1),this.imgResult;await this.compress(),await this.sendProgress(.1),await this.gzip(),await this.sendProgress(.4);const{hosts:t}=this.params,{length:e}=t;for(let a=0;a<e;a++){const e=t[a];await this.splitFile(e),await this.calculatePartList(e,!1)}await this.attachCacheData(),await this.sendProgress(.9);const a=await this.getResult();return await this.clean(),await this.sendProgress(1),a}catch(t){throw(0,Y.buildDError)(t,{message:"Error occurred during image encoding",detail:`Error occurred during image encoding: ${this.params.input.filepath}`})}}getCacheInfoFileName(t){return`img_${t}_cache.json`}async getResult(){if(this.imgResult)return this.imgResult;const{input:t}=this.params,e=t.filepath,{width:a,height:i}=await(0,J.getMetadata)(e),s=this.getCompressFilePath(),{width:r,height:o}=await(0,J.getMetadata)(s),n=await(0,Z.getFileSize)(s),h={meta:{width:a,height:i,size:t.filesize,t_width:r,t_height:o,t_size:n},data:{}},{length:d}=this.params.hosts;for(let t=0;t<d;t++){const e=this.params.hosts[t],a=await this.getPartList(e),i=this.getPreviewList(e);h.data[e]={img:{preview:i},cache:this.getCacheInfo(e),parts:a}}return await this.setImgResult(h),h}async clean(){try{if(this.params.debug)return;const t=this.getCompressFilePath();await(0,et.remove)(t)}catch(t){}}async compress(){if(this.dbData.img_compressed)return;const t=this.getCompressFilePath();await(0,J.compress)({ffmpeg_path:this.params.ffmpegPath,input_path:this.params.input.filepath,output_path:t}),this.dbData.img_compressed=!0,await this.db.write()}async gzip(){if(this.dbData.img_gziped)return;const t=this.getCompressFilePath(),e=this.getGzFilePath();await(0,Q.gzip)(t,e),this.dbData.img_gziped=!0,await this.db.write()}async setPreviewList(t,e){const a=`img_${t}_preview_list`;this.dbData[a]=e,await this.db.write()}getPreviewList(t){const e=`img_${t}_preview_list`;return this.dbData[e]}async splitFile(t){if(this.getPreviewList(t))return;const e=this.getGzFilePath(),a=await(0,Z.getFileSize)(e),i=this.getSizeLimit(t),s=[],r=[];for(let o=0;o<=a-1;o+=i){0!=o&&await this.increaseCurrentFileIndex(t);const n=Math.min(o+i-1,a-1),h=await this.getCurrentFileIndex(t),d=this.getPartName(t,h),c=this.getPartPath(t,h);await v({input_path:e,target_path:c,start:o,end:n});const l=0,u=n-o,p=await this.getPartInfo({host_type:t,filepath:c,filename:d,start:l,end:u,index:h},!1);s.push(p);const g=await this.getPreviewId({file:d,start:l,end:u});r.push({id:g,file:d,start:l,end:u}),await this.setPreviewIdMap({id:g,file:d,start:l,end:u},t)}await this.setPartList(t,s),await this.setPreviewList(t,r)}},it=h(require("fluent-ffmpeg")),st=require("child_process"),rt=require("@soga/mediainfo"),ot=class extends H{async getMediainfo(){const{mediainfo:t}=this.db.data;if(t)return t;const e=this.params.input.filepath,a=await(0,rt.parseMediaInfo)(e);return this.db.data.mediainfo=a,await this.params.db.write(),a}constructor(t){super(t),it.default.setFfmpegPath(t.ffmpegPath)}getFluent(){return(0,it.default)()}async ffmpeg(t,e){const a=this.params.ffmpegPath;return await new Promise((i,s)=>{const r=(0,st.spawn)(a,t,Object.assign({stdio:"ignore"},e));r.on("close",t=>{i(t)}),r.on("error",t=>{s(t)})})}},nt=require("path"),ht=require("@soga/fileutils"),dt=require("@soga/node-types"),ct=require("@soga/error"),lt=({type:t,track_order:e,quality:a})=>`audio-${e}-${a}-${t}.${"manifest"===t?"m3u8":"mp4"}`,ut=({width:t,height:e})=>`video-formatted-${t}-${e}.mp4`,pt=t=>`grouper_result_${t}`,gt=t=>{let e=0,a=0,i=0;t.segments.forEach(t=>{a+=t.duration,e+=t.size;const s=8*t.size/t.duration;s>i&&(i=s)});const s=8*e/a;return{bandwidth:Math.ceil(i),average_bandwidth:Math.ceil(s)}},wt=(t,e)=>{if("number"==typeof t.percent)return t.percent/100;return function(t){const e=t.split(":").map(parseFloat),[a=0,i=0,s=0]=e.reverse();return 3600*s+60*i+a}(t.timemark)/e};var mt=class extends ot{async start(){try{await this.separateVideo(),await this.postProgress({type:dt.UploadProgress.separate_video,percent:1})}catch(t){throw(0,ct.buildDError)(t,{message:"Error occurred during video separation",detail:`Error occurred during video separation: ${this.params.input.filepath}`})}}async separateVideo(){const t="video_separated";if(this.db.data[t])return;const e=await this.getMediainfo();if(!e?.video?.length)return;const a=e.video[0],i=ut({width:a.width,height:a.height}),s=(0,nt.resolve)(this.params.outputRoot,i),r=(0,ht.isVideoSupport)(a.codec),o=["-sn","-an","-map","0:v:0"];let n="copy";r||(n=a.width*a.height>=2073600?"libx265":"libx264","libx265"==n&&o.push("-pix_fmt","yuv420p")),o.push("-c:v",n);const h=a.duration;o.push("-y"),await new Promise((t,e)=>{const a=this.getFluent().input(this.params.input.filepath).outputOptions(o).on("progress",async t=>{if(!r&&t.frames){const e=wt(t,h);await this.postProgress({type:dt.UploadProgress.separate_video,percent:e})}}).on("end",async()=>{t("end"),a.kill("SIGKILL")}).on("error",async t=>{e(t)}).output(s);a.run()});if(!await(0,ht.isValidFile)(s))throw new Error("Separate Video track failed");this.db.data[t]=!0,await this.params.db.write()}},ft=require("path"),_t=require("@soga/fileutils"),yt=require("@soga/node-types"),bt=require("@soga/error"),vt=class extends ot{async start(){try{await this.separateTracks(),await this.postProgress({type:yt.UploadProgress.separate_audio,percent:1})}catch(t){throw(0,bt.buildDError)(t,{message:"Error occurred during audio separation",detail:`Error occurred during audio separation: ${this.params.input.filepath}`})}}async separateTracks(){if(this.audioSeparatorResult)return;const t=await this.getMediainfo();if(!t?.audio?.length)return;const{audio:e}=t,a=e.length,i=[];for(let t=0;t<a;t++){const s=e[t],{codec:r,channels:o,lossless:n}=s,h={adapt:{need:!0,codec:"",channels:Math.min(o,2)},high:{need:!1,codec:"flac",channels:0}};(0,_t.isAudioAdapt)(r)?o>2?(h.high.need=!0,h.high.codec="copy",h.adapt.codec=r,h.adapt.need=!0):(h.adapt.need=!0,h.adapt.codec="copy",h.adapt.channels=0):(0,_t.isAudioHigh)(r)?(h.high.need=!0,h.high.codec="copy",h.adapt.need=!0,h.adapt.codec="aac"):(h.adapt.need=!0,h.adapt.codec="aac",n&&(h.high.need=!0,h.high.codec="flac")),h.adapt.need&&await this.separateAudioTrack(t,{type:"adapt",codec:h.adapt.codec,tracks:a,channels:h.adapt.channels,need_adapt:!0,need_high:h.high.need}),h.high.need&&await this.separateAudioTrack(t,{type:"high",codec:h.high.codec,tracks:a,channels:h.high.channels,need_adapt:h.adapt.need,need_high:!0}),i.push(h)}await this.setAudioSeparatorResult(i)}async separateAudioTrack(t,e){const a=`audio_separated_${t}_${e.type}`;if(this.db.data[a])return;const i=await this.getMediainfo();if(!i?.audio?.length)return;const s=i.audio[t];if(!s)return;const r=s?.duration??i.general?.duration,o=lt({type:"formatted",track_order:t,quality:e.type}),n=(0,ft.resolve)(this.params.outputRoot,o),h=["-sn","-vn","-map",`0:a:${t}`];e.codec&&h.push("-c:a",e.codec),e.channels&&h.push("-ac",e.channels.toString()),h.push("-y"),await new Promise((a,i)=>{const s=this.getFluent().input(this.params.input.filepath).outputOptions(h).on("progress",async a=>{if("copy"!=e.codec){const i=wt(a,r);let s=t;"adapt"==e.type?e.need_high?s+=1/3*i:s+=i:e.need_adapt?(s+=1/3,s+=2/3*i):s+=i;const o=s/e.tracks;await this.postProgress({type:yt.UploadProgress.separate_audio,percent:o})}}).on("end",async()=>{a("end"),s.kill("SIGKILL")}).on("error",async t=>{i(t)}).output(n);s.run()});if(!await(0,_t.isValidFile)(n))throw new Error(`Separate audio track failed: [track_order:${t}, track_quality ${e.type}] `);if("copy"==e.codec){let a=t;"adapt"==e.type&&e.need_high?a+=1/3:a+=1;const i=a/e.tracks;await this.postProgress({type:yt.UploadProgress.separate_audio,percent:i})}this.db.data[a]=!0,await this.params.db.write()}},Pt=require("path"),xt=require("@soga/mediainfo"),zt=require("@soga/mp4box"),Tt=require("@soga/m3u8"),Rt=require("@soga/node-types"),St=require("@soga/fileutils"),Dt=require("fs-extra"),Mt=require("@soga/error"),It=class extends ot{getVideoInitName({width:t,height:e}){return`video-init-${t}-${e}.mp4`}getVideoManifestName({width:t,height:e}){return`video-hls-${t}-${e}.m3u8`}async start(){try{await this.transcodeVideo(),await this.saveData(),await this.postProgress({type:Rt.UploadProgress.transcode_video,percent:1})}catch(t){throw(0,Mt.buildDError)(t,{message:"Error occurred during video transcoding",detail:`Error occurred during video transcoding: ${this.params.input.filepath}`})}}async saveData(){const t=await this.getMediainfo();if(!t?.video?.length)return;if(this.videoTranscoderResult)return;const{width:e,height:a}=t.video[0],i=ut({width:e,height:a}),s=(0,Pt.resolve)(this.params.outputRoot,i),r=this.getVideoManifestName({width:e,height:a}),o=(0,Pt.resolve)(this.params.outputRoot,r),n=await(0,Tt.parseM3U8)(o),{videos:h}=await(0,zt.getMp4boxInfo)(s),{codec:d}=h[0],{bandwidth:c,average_bandwidth:l}=gt(n),u=(await(0,xt.parseMediaInfo)(s)).video[0],p=(0,St.getStandardInfo)(e,a),g={m3u8:n,m3u8_path:o,codec:d,width:e,height:a,bandwidth:c,average_bandwidth:l,bitdepth:u?.bitdepth,bitrate:u?.bitrate,codec_name:u?.codec??"",framerate:u?.framerate,label:p?.label??"unknown"};await this.setVideoTranscoderResult(g),this.params.debug||await(0,Dt.remove)(s)}async transcodeVideo(){const t="video_transcode_state";if(this.db.data[t])return;const e=await this.getMediainfo();if(!e?.video?.length)return;const a=e.video[0],i={width:a.width,height:a.height},s=ut(i),r=this.getVideoInitName(i),o=this.getVideoManifestName({width:a.width,height:a.height}),n=["-i",s,"-an","-sn","-c:v","copy","-hls_list_size","0","-hls_time","6","-hls_segment_type","fmp4","-hls_fmp4_init_filename",r,"-y",o];await this.ffmpeg(n,{cwd:this.params.outputRoot});const h=(0,Pt.resolve)(this.params.outputRoot,o);if(!await(0,St.isValidFile)(h))throw new Error("Transcode video track failed");this.db.data[t]=!0,await this.db.write()}},Ft=require("path"),$t=require("@soga/fileutils"),kt=require("@soga/mp4box"),qt=require("@soga/m3u8"),Et=require("@soga/mediainfo"),Nt=require("fs-extra"),Ut=require("@soga/error"),Lt=require("@soga/node-types"),Ct=class extends ot{async start(){try{await this.transcodeAudios(),await this.saveData()}catch(t){throw(0,Ut.buildDError)(t,{message:"Error occurred during audio transcoding",detail:`Error occurred during audio transcoding: ${this.params.input.filepath}`})}}async saveData(){if(this.audioTranscoderResult)return;const t=await this.getMediainfo();if(!t?.audio?.length)return;const e=t.audio.length,a=this.audioSeparatorResult,i=[],s={};for(let t=0;t<e;t++){const e=a[t];e.adapt.need&&(s.adapt=await this.getQualityData({track_order:t,quality:"adapt"})),e.high.need&&(s.high=await this.getQualityData({track_order:t,quality:"high"})),i.push(s)}await this.setAudioTranscoderResult(i);try{if(this.params.debug)return;for(let t=0;t<e;t++){const e=a[t];if(e.adapt.need){const e=lt({type:"formatted",track_order:t,quality:"adapt"}),a=(0,Ft.resolve)(this.params.outputRoot,e);await(0,Nt.remove)(a)}if(e.high.need){const e=lt({type:"formatted",track_order:t,quality:"high"}),a=(0,Ft.resolve)(this.params.outputRoot,e);await(0,Nt.remove)(a)}}}catch(t){}}async getQualityData({track_order:t,quality:e}){const a=lt({type:"formatted",track_order:t,quality:e}),i=(0,Ft.resolve)(this.params.outputRoot,a),s=await(0,Et.parseMediaInfo)(i);if(!s.audio?.length)throw new Error("parse mediainfo failed!");const r=s.audio[0],o=lt({type:"manifest",track_order:t,quality:e}),n=await(0,$t.getFileSize)(i),h=(0,Ft.resolve)(this.params.outputRoot,o),d=await(0,kt.getMp4boxInfo)(i),{audios:c}=d,{language:l,codec:u}=c[0],p=l&&!l.startsWith("un")?{language:l}:void 0,g=await(0,qt.parseM3U8)(h),{bandwidth:w,average_bandwidth:m}=gt(g);return{m3u8:g,m3u8_path:h,codec:u,codec_name:r.codec,...p,order:t,lossless:r.lossless,channels:r.channels,bandwidth:w,size:n,average_bandwidth:m}}async transcodeAudios(){const t="audio_transcoded";if(this.db.data[t])return;const e=await this.getMediainfo();if(!e?.audio?.length)return;const a=e.audio.length,i=this.audioSeparatorResult;for(let t=0;t<a;t++){const e=i[t];e.adapt.need&&await this.transcodeAudio(t,{...e.adapt,type:"adapt"}),e.high.need&&await this.transcodeAudio(t,{...e.high,type:"high"});const s=(t+1)/a;await this.postProgress({type:Lt.UploadProgress.transcode_audio,percent:s})}await this.postProgress({type:Lt.UploadProgress.transcode_audio,percent:1}),this.db.data[t]=!0,await this.db.write()}async transcodeAudio(t,e){const a=`audio-transcoded-${t}-${e.type}`;if(this.db.data[a])return;const i=lt({type:"formatted",track_order:t,quality:e.type}),s=lt({type:"init",track_order:t,quality:e.type}),r=lt({type:"manifest",track_order:t,quality:e.type}),o=["-i",i,"-vn","-sn","-c:a","copy","-hls_list_size","0","-hls_time","6","-hls_segment_type","fmp4","-hls_fmp4_init_filename",s,"-y",r];await this.ffmpeg(o,{cwd:this.params.outputRoot});const n=(0,Ft.resolve)(this.params.outputRoot,r);if(!await(0,$t.isValidFile)(n))throw new Error(`Transcode audio track failed: [track_order:${t}, track_quality ${e.type}] `);this.db.data[a]=!0,await this.db.write()}},At=require("path"),Ot=require("@soga/fileutils"),Vt=require("@soga/imgutils"),Gt=require("fs-extra"),Bt=require("@soga/node-types"),jt=require("@soga/error"),Xt=class extends ot{m3u8_data=null;thumbnail_duration=30;thumbnail_group=[];row=8;col=8;screenshot_width=480;screenshot_height=270;getScreenshotName(t){return`video_screenshot_${t}.jpg`}getTileName(t){return`video_tile_${t}.jpg`}getCoverName(){return"video_cover.jpg"}async updateImagePercent(t,e){const a="screenshot"==e?6*t/7:t/7+6/7;await this.postProgress({type:Bt.UploadProgress.transcode_thumbnail,percent:a})}store;async initStore(){this.store=await this.getStore("thumbnail_store.json")}async start(){if(!this.videoThumbnailerResult)try{const t=await this.getMediainfo();if(!t?.video?.length)return;if(await this.init(),!this.m3u8_data)return;await this.generateScreenshots(),await this.generateTiles(),await this.saveCoverInfo(),await this.saveThumbnailInfo()}catch(t){throw(0,jt.buildDError)(t,{message:"Error occurred during video thumbnail generation",detail:`Error occurred during video thumbnail generation: ${this.params.input.filepath}`})}}async init(){await this.initStore(),await this.initScreenshotSize(),await this.initM3U8Data(),await this.initThumbnailDuration(),await this.initThumbnailGroup()}async saveThumbnailInfo(){if(this.videoThumbnailerResult)return;const{col:t,row:e,thumbnail_group:a,screenshot_width:i,screenshot_height:s}=this,r=a.length,o=[],n=[];for(let h=0;h<r;h++){const r=a[h],d=r.start_time,c=r.end_time,l=Math.floor(h/(e*t)),u=h%e*i,p=Math.floor(h%(t*e)/e)*s,g=this.getTileName(l);n.push(g),o.push({file:g,st:d,et:c,x:u,y:p,w:i,h:s})}const h=[...new Set(n)],d=h.length,c=[];for(let t=0;t<d;t++){const e=h[t],a=(0,At.resolve)(this.params.outputRoot,e),i=await(0,Ot.getFileSize)(a);c.push({file:e,file_path:a,size:i})}const l={width:this.screenshot_width,height:this.screenshot_height,row:this.row,col:this.col,tile_list:c,sprite_list:o};await this.setVideoThumbnailerResult(l)}async saveCoverInfo(){if(this.coverResult)return;const t=this.store.data.thumbnail_screenshot_largest,e=t?.index||0,{screenshot_width:a,screenshot_height:i}=this,s=this.getScreenshotName(e),r=(0,At.resolve)(this.params.outputRoot,s),o=this.getCoverName(),n=(0,At.resolve)(this.params.outputRoot,o);await(0,Gt.copy)(r,n);const h={file:o,path:n,size:await(0,Ot.getFileSize)(n),width:a,height:i};await this.setCoverResult(h)}async generateTiles(){const t=this.store.data.thumbnail_tile_index||0,{length:e}=this.thumbnail_group,a=this.col*this.row,i=Math.ceil(e/a);for(let e=t;e<i;e++)await this.generateOneTile(e),await this.updateImagePercent((e+1)/i,"tile")}async generateOneTile(t){const{col:e,row:a}=this,i=this.thumbnail_group.length,s=a*e,r=t*s,o=Math.min(s,i-r),n=[];for(let t=0;t<o;t++){const e=this.getScreenshotName(r+t),a=(0,At.resolve)(this.params.outputRoot,e);n.push(a)}const h=this.getTileName(t),d=(0,At.resolve)(this.params.outputRoot,h);await this.createSpriteSheet(n,d),this.store.data.thumbnail_tile_index=t+1,await this.store.write()}async createSpriteSheet(t,e){await(0,Vt.combine)({col:this.col,inputs:t,output_path:e,width:this.screenshot_width,height:this.screenshot_height})}getKeyFrameParams(t,e=0){if(t<1)return["-vframes","1"];{const a=Math.max(t-e-.3,.1);if(a<1)return["-vframes","1"];return["-ss",`${a.toFixed(3)}`,"-vframes","1"]}}async generateScreenshots(){if(this.store.data.thumbnail_screenshot_state)return;this.store.data.thumbnail_screenshot_index||=0;const t=this.store.data.thumbnail_screenshot_index,e=this.store.data.thumbnail_screenshot_largest,a={index:0,size:0};if(e){const t=e;a.index=t.index,a.size=t.size}const{segments:i}=this.m3u8_data,{thumbnail_group:s,screenshot_width:r}=this,{length:o}=s,n=async(t,{errorTimes:e,fixedSeconds:o})=>{const h=s[t].item.index,d=i[h];try{const e=this.getScreenshotName(t),i=`concat:${d.init_uri}|${d.uri}`,s=this.getKeyFrameParams(d.duration,o),n=r>this.screenshot_height?`${r}:-2`:`-2:${this.screenshot_height}`,h=["-i",i,...s,"-vf",`scale=${n}:flags=lanczos`,"-y",e];await this.ffmpeg(h,{cwd:this.params.outputRoot});const c=(0,At.resolve)(this.params.outputRoot,e),l=await(0,Ot.getFileSize)(c);if(0===l)throw new Error(`Generate video thumbnail error: [index: ${t}, start_time: ${d.start_time}, end_time: ${d.end_time}]`);l>=a.size&&(a.index=t,a.size=l,this.store.data.thumbnail_screenshot_largest=a,await this.store.write()),this.store.data.thumbnail_screenshot_index=t+1,await this.store.write()}catch(a){const i=Math.max(10,d.duration);if(!(e<3))throw a;await n(t,{errorTimes:e+1,fixedSeconds:o+i/5})}};for(let e=t;e<o;e++)await n(e,{errorTimes:0,fixedSeconds:0}),await this.updateImagePercent((e+1)/o,"screenshot");this.store.data.thumbnail_screenshot_state=!0,await this.store.write()}async initScreenshotSize(){const{thumbnail_screenshot_size:t}=this.store.data;if(t)return this.screenshot_width=t.width,void(this.screenshot_height=t.height);const e=await this.getMediainfo();if(!e?.video?.length)return;const a=e.video[0],{width:i,height:s}=a,r=i>s?480:270;this.screenshot_width=2*Math.floor(Math.min(r,i)/2),this.screenshot_height=2*Math.floor(this.screenshot_width*(s/i)/2),this.store.data.thumbnail_screenshot_size={width:this.screenshot_width,height:this.screenshot_height}}async initThumbnailGroup(){if(this.store.data.thumbnail_group)return void(this.thumbnail_group=this.store.data.thumbnail_group);const t=[],{segments:e}=this.m3u8_data,{length:a}=e,i=this.thumbnail_duration;let s=0,r=[];for(let o=0;o<a;o++){const n=e[o];if(s+=n.duration,r.push(n),s>=i||o===a-1){const e=r.length,a=r[0],i=r[e-1];t.push({duration:s,start_time:a.start_time,end_time:i.end_time,items:r,item:i}),s=0,r=[]}}if(t.length>1){if(t[t.length-1].duration<1){const e=t.pop(),a=t[t.length-2];a.duration=a.duration+e.duration,a.end_time=e.end_time,a.items=a.items.concat(e.items),a.item=e.item,e.items}}t.forEach(t=>{const{items:e}=t;for(let a=e.length-1;a>=0;a--)if(e[a].duration>1){t.item=e[a];break}}),this.thumbnail_group=t,this.store.data.thumbnail_group=t,await this.store.write()}getVideoM3U8Info(){return this.videoTranscoderResult?.m3u8}async initM3U8Data(){this.m3u8_data=this.getVideoM3U8Info()}async initThumbnailDuration(){if(this.store.data.thumbnail_duration)return this.thumbnail_duration=this.store.data.thumbnail_duration,this.thumbnail_duration;let t=30;const e=await this.getMediainfo(),a=e?.video;if(!a?.length)return t;const i=a[0],s=i.duration||e?.general?.duration,{width:r,height:o}=i;r*o>=518400&&(t=10),r*o>=921600&&(t=20),r*o>=2073600&&(t=30),r*o>=3686400&&(t=40),r*o>=8294400&&(t=60);const n=s??0;if(n&&(n<60&&(t=0),n<300&&(t=Math.ceil(t/4)),n<600&&(t=Math.ceil(t/2)),n>3600)){const e=n/3600;t=Math.ceil(t*e)}return t=Math.min(60,t),this.thumbnail_duration=t,this.store.data.thumbnail_duration=t,await this.store.write(),t}},Ht=require("path"),Wt=require("fs-extra"),Kt=require("@soga/imgutils"),Jt=require("@soga/fileutils"),Qt=require("@soga/node-types"),Zt=require("@soga/error"),Yt=class extends ot{get cover_name(){return"audio_cover.png"}async start(){try{await this.generateCover(),this.isAudio&&await this.postProgress({type:Qt.UploadProgress.transcode_thumbnail,percent:1})}catch(t){throw(0,Zt.buildDError)(t,{message:"Error occurred during audio cover generation",detail:`Error occurred during audio cover generation: ${this.params.input.filepath}`})}}async generateCover(){const t=await this.getMediainfo();if(t.video?.length)return;const e="audio-covered";try{if(this.coverResult)return this.coverResult;if(this.db.data[e])return;const{cover_name:t}=this,a=["-i",this.params.input.filepath,"-map","0:v","-y",t];await this.ffmpeg(a,{cwd:this.params.outputRoot});const i=(0,Ht.resolve)(this.params.outputRoot,t),s=await(0,Wt.pathExists)(i),r=await(0,Kt.getMetadata)(i);if(s){const e={file:t,path:i,size:await(0,Jt.getFileSize)(i),width:r.width??0,height:r.height??0};await this.setCoverResult(e)}}catch(t){throw t}finally{this.db.data[e]=!0,await this.db.write()}}},te=require("path"),ee=require("@soga/utils"),ae=require("@soga/fileutils"),ie=require("fs-extra"),se=require("@soga/error"),re=require("@soga/node-types"),oe=class extends ot{builtin_tracks=0;external_tracks=0;get tracks(){return this.builtin_tracks+this.external_tracks}async sendProgress(t){await this.postProgress({type:re.UploadProgress.separate_subtitle,percent:t})}get dbData(){return this.db.data}async start(){try{if(this.subtitleEncoderResult)return;const t=await this.getMediainfo();if(this.builtin_tracks=t?.text?.length||0,this.external_tracks=this.params.subtitles?.length||0,!this.tracks)return await this.setSubtitleEncoderResult([]),void await this.sendProgress(1);const e=await this.parseBuiltinTextTracks();await this.sendProgress(this.builtin_tracks/this.tracks);const a=await this.parseExternalTextTracks(),i=[...e,...a];await this.setSubtitleEncoderResult(i),await this.sendProgress(1)}catch(t){throw(0,se.buildDError)(t,{message:"Error occurred while process subtitle track",detail:`Error occurred while process subtitle track: ${this.params.input.filepath}`})}}async parseBuiltinTextTracks(){const t=await this.getMediainfo(),e=t?.text;if(!e?.length)return[];const{subtitle_builtin_tracks:a}=this.dbData;if(a)return a;const i=e.length,s=[];for(let t=0;t<i;t++){const e=await this.parseBuiltinTextTrack(t);e&&s.push(e),await this.sendProgress((t+1)/this.tracks)}return this.dbData.subtitle_builtin_tracks=s,await this.params.db.write(),s}async parseBuiltinTextTrack(t){const e=this.params.outputRoot,a=`subtitle-builtin-${t}.zip`,i=(0,te.resolve)(e,a),s=`subtitle-temp-${t}.vtt`,r=(0,te.resolve)(e,s),o=`subtitle-builtin-u8-${t}.vtt`,n=(0,te.resolve)(e,o),h=["-i",this.params.input.filepath,"-vn","-an","-map",`0:s:${t}`,"-c","webvtt","-y",s];await this.ffmpeg(h,{cwd:this.params.outputRoot});if(await(0,ae.isValidFile)(r)){if(await(0,ee.isUtf8File)(r))await(0,ie.copy)(r,n);else{await(0,ee.saveFileAsUtf8)(r,n);await(0,ae.isValidFile)(n)||await(0,ie.copy)(r,n)}const e=await(0,ee.getFileLanguage)(n),{label:s,lang:o}=e;await(0,ee.gzip)(n,i);return{file:a,file_path:i,size:await(0,ae.getFileSize)(i),lang:o,name:s||`builtin_${t+1}`,title:s||`builtin_${t+1}`,builtin:!0,source:null}}return!1}async parseExternalTextTracks(){const{subtitles:t}=this.params;if(!t?.length)return[];const{subtitle_external_tracks:e}=this.dbData;if(e)return e;const a=[],i=t.length;for(let e=0;e<i;e++){const i=await this.parseExternalTextTrack(e,t[e]);i&&a.push(i),await this.sendProgress((this.builtin_tracks+(e+1))/this.tracks)}return this.dbData.subtitle_external_tracks=a,await this.params.db.write(),a}async parseExternalTextTrack(t,e){const{ext:a}=(0,te.parse)(e),i=this.params.outputRoot,s=`subtitle-external-${t}.vtt`,r=(0,te.resolve)(i,s),o=`subtitle-external-${t}.zip`,n=(0,te.resolve)(i,o),h=`subtitle-external-u8-${t}${a}`,d=(0,te.resolve)(i,h),c=`subtitle-external-source-${t}.zip`,l=(0,te.resolve)(i,c);if(!await(0,ae.isValidPath)(e))return!1;if(await(0,ee.isUtf8File)(e))await(0,ie.copy)(e,d);else{await(0,ee.saveFileAsUtf8)(e,d);if(!await(0,ae.isValidFile)(d))return!1}const u=["-i",d,"-c","webvtt","-y",s];await this.ffmpeg(u,{cwd:this.params.outputRoot});if(await(0,ae.isValidFile)(r)){const i=await(0,ee.getFileLanguage)(r),{label:s,lang:h}=i;await(0,ee.gzip)(e,l),await(0,ee.gzip)(r,n);const d=await(0,ae.getFileSize)(l);return{file:o,size:await(0,ae.getFileSize)(n),file_path:n,lang:h,name:s||`external_${t+1}`,title:s||`external_${t+1}`,builtin:!1,source:{file:c,file_path:l,size:d,ext:a}}}return!1}},ne=require("@soga/error"),he=require("path"),de=require("fs-extra"),ce=require("@soga/node-types"),le=require("@soga/fileutils"),ue=require("@soga/utils"),pe=require("@soga/error"),ge=require("path"),we=require("@soga/fileutils"),me=class extends ot{hostType;safe_index=0;file_map={};completed_percent=0;total_percent=0;store;async initStore(t){this.store=await this.getStore(`${t}_grouper_store.json`)}getFileName=t=>this.getPreviewSegmentName(t,this.hostType);getGroupedVideoManifestName(t){return`grouper_video_${this.hostType}_${t}.m3u8`}getAudioManifestName(t,e){return`grouper_audio_${this.hostType}_${e}_${t}.m3u8`}getThumbnailInfoFilename(){return`grouper_thumbnail_${this.hostType}.json`}getCacheInfoFilename(){return`grouper_cache_${this.hostType}.json`}constructor(t){super(t),this.hostType=t.host_type,this.completed_percent=t.completed_percent,this.total_percent=1/t.hosts.length}async generateSafeFile(t){return await async function(t){const e=`safe_${t.type}_${t.file_index}.txt`,a=f(t.filesize),i=(0,w.resolve)(t.outputRoot,e);return await(0,p.writeFile)(i,a),{file_path:i,size:a.length}}({type:t,file_index:this.safe_index++,outputRoot:this.params.outputRoot,filesize:this.params.input.filesize})}readAudioTracks(){return this.audioTranscoderResult??[]}readVideoTracks(){return this.videoTranscoderResult?[this.videoTranscoderResult]:[]}readThumbnailInfo(){return this.videoThumbnailerResult}readCoverInfo(){return this.coverResult}readSubtitleInfo(){return this.subtitleEncoderResult}async getPartData(){const t=this.store.data.grouper_part_names??[],e=[];for(let a=0;a<t.length;a++){const i=t[a],s=(0,ge.resolve)(this.params.outputRoot,i),r=await(0,we.getFileSize)(s),o=await this.getPartInfo({host_type:this.hostType,filepath:s,start:0,end:r-1,filename:i});e.push(o)}return e}async getAudioData(){const t=this.readAudioTracks();if(!t?.length)return;const e=[];for(let a=0;a<t.length;a++){const i=t[a];if(i.adapt){const{average_bandwidth:t,bandwidth:s,channels:r,codec:o,codec_name:n,language:h,order:d}=i.adapt,c=this.getAudioManifestName("adapt",a),l=this.file_map[c],{file_index:u,start:p,end:g,size:w,hash:m}=l,f=this.getFileName(u),_=await this.getPreviewId({file:c});await this.setPreviewIdMap({id:_,file:f,start:p,end:g},this.hostType);const y={id:_,average_band:t,band:s,channels:r,codec:o,codec_name:n,language:h,order:d,file:f,start:p,end:g,size:w,hash:m};if(i.high){const{average_bandwidth:t,bandwidth:e,channels:s,codec:r,codec_name:o,language:n,order:h}=i.high,d=this.getAudioManifestName("high",a),c=this.file_map[d],{file_index:l,start:u,end:p,size:g,hash:w}=c,m=this.getFileName(l),f=await this.getPreviewId({file:d});await this.setPreviewIdMap({id:f,file:m,start:u,end:p},this.hostType),y.high={id:f,average_band:t,band:e,channels:s,codec:r,codec_name:o,language:n,order:h,file:m,start:u,end:p,size:g,hash:w}}e.push(y)}}return e}async getVideoData(){const t=this.readVideoTracks();if(!t?.length)return;const e=[];for(let a=0;a<t.length;a++){const i=t[a],s=this.getGroupedVideoManifestName(a),r=await this.getPreviewId({file:s}),o=this.file_map[s],{file_index:n,start:h,end:d,size:c,hash:l}=o,u=this.getFileName(n);await this.setPreviewIdMap({id:r,file:u,start:h,end:d},this.hostType);const{average_bandwidth:p,bandwidth:g,codec:w,width:m,height:f,label:_,codec_name:y,bitdepth:b,framerate:v}=i,P={id:r,average_band:p,band:g,codec:w,codec_name:y,bitdepth:b,framerate:Math.round(v),width:m,height:f,file:u,start:h,end:d,size:c,label:_,hash:l};e.push(P)}return e}async getSubtitleData(){const t=this.readSubtitleInfo();if(!t?.length)return;const e=[],{length:a}=t;for(let i=0;i<a;i++){const a=t[i],{builtin:s,file:r,lang:o,title:n,name:h,source:d}=a,c=this.file_map[r],{file_index:l,start:u,end:p,size:g}=c,w=this.getFileName(l),m={uuid:await this.getPreviewId({file:r,start:u,end:p}),builtin:s,lang:o,name:h,title:n,file:w,start:u,end:p,size:g};if(d){const{file:t,ext:e}=d,a=this.file_map[t],{file_index:i,start:s,end:r,size:o}=a,n=this.getFileName(i);m.source={size:o,file:n,start:s,end:r,ext:e}}e.push(m)}return e}async getThumbnailData(){const t=this.readThumbnailInfo();if(!t)return;const{row:e,col:a,width:i,height:s}=t,r=this.getThumbnailInfoFilename(),o=this.file_map[r],{file_index:n,start:h,end:d,size:c}=o,l=this.getFileName(n),u=await this.getPreviewId({file:r});await this.setPreviewIdMap({id:u,file:l,start:h,end:d},this.hostType);return{id:u,row:e,col:a,width:i,height:s,file:l,start:h,end:d,size:c}}async getCoverData(){const t=this.readCoverInfo();if(!t)return;const e=t,{file:a,width:i,height:s}=e,r=this.file_map[a],{file_index:o,start:n,end:h,size:d}=r,c=this.getFileName(o),l=await this.getPreviewId({file:e.path});await this.setPreviewIdMap({id:l,file:c,start:n,end:h},this.hostType);return{id:l,width:i,height:s,file:c,start:n,end:h,size:d}}async getCacheData(){const t=this.getCacheInfoFilename(),e=await this.getPreviewId({file:t}),a=this.file_map[t],{file_index:i,start:s,end:r,size:o}=a,n=this.getFileName(i);await this.setPreviewIdMap({id:e,file:n,start:s,end:r},this.hostType);return{id:e,file:n,start:s,end:r}}async saveData(){const t=pt(this.hostType);if(this.db.data[t])return;const e={},a=await this.getAudioData();a&&(e.audios=a);const i=await this.getVideoData();i&&(e.videos=i);const s=await this.getSubtitleData();s&&(e.subtitles=s);const r=await this.getThumbnailData();r&&(e.thumbnail=r);const o=await this.getCoverData();o&&(e.cover=o),e.parts=await this.getPartData(),e.cache=await this.getCacheData(),this.db.data[t]=e,await this.db.write()}},fe=class extends me{current_position=0;current_index=0;group_data=[];async start(){const t=pt(this.hostType);if(this.db.data[t])return this.db.data[t];try{return await this.initStore(this.hostType),await this.calculateData(),await this.postProgress({type:ce.UploadProgress.group_media,percent:this.completed_percent+.5*this.total_percent}),await this.processGroups(),await this.postProgress({type:ce.UploadProgress.group_media,percent:this.completed_percent+.9*this.total_percent}),await this.saveData(),await this.postProgress({type:ce.UploadProgress.group_media,percent:this.completed_percent+this.total_percent}),this.db.data[t]}catch(t){throw(0,pe.buildDError)(t,{message:`Error occurred during media grouping ${this.hostType}`,detail:`Error occurred during media grouping ${this.hostType}: ${this.params.input.filepath}`})}}async processGroups(){const t="grouper_process_state";if(this.store.data[t])return;this.store.data.grouper_process_map||={},this.store.data.grouper_process_index||=0;const{length:e}=this.group_data;for(let t=0;t<e;t++){const a=this.group_data[t];this.store.data.grouper_process_map[a.filename]||(await _({outputRoot:this.params.outputRoot,files:a.files,filename:a.filename}),this.store.data.grouper_process_map[a.filename]=!0,await this.store.write(),await this.postProgress({type:ce.UploadProgress.group_media,percent:this.completed_percent+.5*this.total_percent+this.total_percent*(.4*(t+1)/e)}))}this.store.data[t]=!0,await this.store.write()}async insertSafeFile(){const t=await this.generateSafeFile(this.hostType);this.addOne(t,!0)}async calculateData(){this.store.data.grouper_group_list||=[],this.store.data.grouper_file_map||={},await this.insertSafeFile(),await this.calculateMediaTracks(),await this.calculateThumbnails(),await this.calculateCovers(),await this.calculateCaches(),this.current_index+=1,this.current_position=0,await this.calculateSubtitles(),this.store.data.grouper_group_list=this.group_data,this.store.data.grouper_file_map=this.file_map;const t=this.group_data.map(t=>t.filename);this.store.data.grouper_part_names=t,this.store.data.grouper_calculate_state=!0,await this.store.write()}async calculateSubtitles(){const t=this.readSubtitleInfo();if(!t?.length)return;await this.insertSafeFile();const{length:e}=t;for(let a=0;a<e;a++){const e=t[a],{file:i,file_path:s,size:r}=e,o=this.addOne({file_path:s,size:r});if(this.file_map[i]=o,e.source){const{file:t,file_path:a,size:i}=e.source,s=this.addOne({file_path:a,size:i});this.file_map[t]=s}}}async calculateCaches(){await this.getAudioData(),await this.getVideoData(),await this.getThumbnailData(),await this.getCoverData();const t=this.getPreviewIdMap(this.hostType),e=this.getCacheInfoFilename(),a=await this.writeText(e,JSON.stringify(t));this.file_map[e]=a}async calculateCovers(){const t=this.readCoverInfo();if(!t)return;const{file:e,path:a,size:i}=t,s=this.addOne({file_path:a,size:i});this.file_map[e]=s}async calculateMediaTracks(){const t=this.readAudioTracks(),e=this.readVideoTracks(),a=t?.length;for(let e=0;e<a;e++){const i=t[e];if(i.adapt){const t=await this.calculateOneTrack(i.adapt.m3u8),a=this.getAudioManifestName("adapt",e),s=await this.writeTrackText(a,t);this.file_map[a]=s}if(i.high){const t=await this.calculateOneTrack(i.high.m3u8),a=this.getAudioManifestName("high",e),s=await this.writeTrackText(a,t);this.file_map[a]=s}await this.postProgress({type:ce.UploadProgress.group_media,percent:this.completed_percent+.4*this.total_percent*((e+1)/a)})}const i=e.length;for(let t=0;t<i;t++){const a=e[t],s=await this.calculateOneTrack(a.m3u8),r=this.getGroupedVideoManifestName(t),o=await this.writeTrackText(r,s);this.file_map[r]=o,await this.postProgress({type:ce.UploadProgress.group_media,percent:this.completed_percent+.2*this.total_percent+.2*this.total_percent*((t+1)/i)})}}async calculateThumbnails(){const t=this.readThumbnailInfo();if(!t)return;if(!t)return;const{tile_list:e}=t,{length:a}=e;let i=[...t.sprite_list];for(let t=0;t<a;t++){const a=e[t],s=a.file,r=await this.safelyAddOne({file_path:a.file_path,size:a.size}),o=await this.getPreviewId({file:s}),n=this.getFileName(r.file_index);await this.setPreviewIdMap({id:o,file:n,start:r.start,end:r.end},this.hostType),this.file_map[s]=r,i=i.map(t=>t.file===s?{...t,file:n,id:o,s:r.start,e:r.end}:t)}const s=this.getThumbnailInfoFilename(),r=await this.writeText(s,JSON.stringify(i));this.file_map[s]=r}async calculateOneTrack(t){const{segments:e,init:a,version:i,targetDuration:s,mediaSequence:r,endList:o}=t,n={},h=this.addOne({size:a.size,file_path:a.file_path}),d=await this.getPreviewId({file:a.uri}),c=this.getFileName(h.file_index),l=`${c}?id=${d}`;await this.setPreviewIdMap({id:d,file:c,start:h.start,end:h.end},this.hostType);const u=["#EXTM3U",`#EXT-X-VERSION:${i}`,`#EXT-X-TARGETDURATION:${s}`,`#EXT-X-MEDIA-SEQUENCE:${r}`,`#EXT-X-MAP:URI=${l},BYTERANGE="${h.size}@${h.start}"`];[...e].forEach(t=>{const{uri:e,size:a,duration:i,file_path:s}=t;n[e]=this.addOne({size:a,duration:i,file_path:s})});for(const[t,e]of Object.entries(n)){const a=await this.getPreviewId({file:t}),i=this.getFileName(e.file_index);await this.setPreviewIdMap({id:a,file:i,start:e.start,end:e.end},this.hostType),u.push(`#EXTINF:${e.duration},`),u.push(`#EXT-X-BYTERANGE:${e.size}@${e.start}`),u.push(`${i}?id=${a}`)}o&&u.push("#EXT-X-ENDLIST");return u.join("\n")}async writeTrackText(t,e){const a=(0,he.resolve)(this.params.outputRoot,t),i=(0,he.resolve)(this.params.outputRoot,`${t}.gz`),s=(0,he.resolve)(this.params.outputRoot,`${t}.bin`);await(0,de.writeFile)(a,e,"utf-8"),await(0,ue.gzip)(a,i);if(await(0,le.getFileSize)(i)>16){const t=(await(0,ue.getFileBufferSlice)(i,0,15)).toString("base64");await async function(t,e){await new Promise((a,i)=>{const s=(0,p.createReadStream)(t,{start:16}),r=(0,p.createWriteStream)(e);s.pipe(r),r.on("finish",()=>{a(!0)}),s.on("error",t=>{i(t)}),r.on("error",t=>{i(t)})})}(i,s);return{...this.addOne({file_path:s,size:await(0,le.getFileSize)(s)}),hash:t}}return{...this.addOne({file_path:a,size:await(0,le.getFileSize)(a)}),hash:""}}async writeText(t,e){const a=(0,he.resolve)(this.params.outputRoot,t);await(0,de.writeFile)(a,e,"utf-8");return this.addOne({file_path:a,size:await(0,le.getFileSize)(a)})}addOne({file_path:t,size:e,duration:a=0},i=!1){const s=this.getSizeLimit(this.hostType),{current_position:r,group_data:o}=this;if(i&&o[this.current_index]||!(r+e<=s)){this.current_index+=1;const{current_index:i}=this;o[i]?o[i].files.push(t):o[i]={filename:this.getFileName(i),files:[t]};const s=0,r=e-1;return this.current_position=e,{file_index:i,start:s,end:r,duration:a,size:r-s+1}}{const{current_index:i}=this,s=r,n=r+e-1;return this.current_position=n+1,o[i]?o[i].files.push(t):o[i]={filename:this.getFileName(i),files:[t]},{file_index:i,start:s,end:n,duration:a,size:n-s+1}}}async safelyAddOne(t){const e=this.getSizeLimit(this.hostType),{current_position:a}=this;return a+t.size<=e?0===a?(await this.insertSafeFile(),this.addOne(t)):this.addOne(t):(await this.insertSafeFile(),this.addOne(t))}},_e=class extends ot{async start(){try{if(this.grouperResult)return this.grouperResult;const t={meta:await this.getMetaData(),data:{}},{length:e}=this.params.hosts;for(let a=0;a<e;a++){const i=this.params.hosts[a],s=this.getSizeLimit(i),r=new fe({...this.params,host_type:i,file_size_limit:s,completed_percent:a/e}),o=await r.start();t.data[i]=o}return await this.setGrouperResult(t),t}catch(t){throw(0,ne.buildDError)(t,{message:t.message||"Error occurred during media grouping",detail:t.detail||`Error occurred during media grouping: ${this.params.input.filepath}`})}}async getMetaData(){const t={},e=this.audioTranscoderResult??[],a=this.videoTranscoderResult?[this.videoTranscoderResult]:[];if(a?.length){const e=await this.getMediainfo(),{duration:i}=e?.general;if(a?.length){const{width:e,height:s,framerate:r,bitdepth:o,label:n,codec:h,codec_name:d}=a[0];t.videos=[{duration:i,bitdepth:o,width:e,height:s,framerate:r,label:n,codec:h,codec_name:d}]}}if(e?.length)for(const a of e){const{high:e,adapt:i}=a,{channels:s,lossless:r}=i,o=await this.getMediainfo(),{duration:n}=o?.general,{codec:h,codec_name:d}=i,c={duration:n,channels:s,lossless:r,codec:h,codec_name:d};e&&(c.high={channels:e.channels,codec:e.codec,codec_name:e.codec_name,lossless:e.lossless}),t.audios=t.audios||[],t.audios.push(c)}return t}},ye=class extends ot{async start(){if(this.db.data.grouper_result)return this.db.data.grouper_result;const t=await this.getMediainfo();if(!t)return;const e=t.video,a=e?.length,i=t.audio,s=i?.length;if(!s&&!a)return;const r=new oe(this.params);if(await r.start(),s){const t=new vt(this.params);await t.start();const e=new Ct(this.params);await e.start();const a=new Yt(this.params);await a.start()}if(a){const t=new mt(this.params);await t.start();const e=new It(this.params);await e.start();const a=new Xt(this.params);await a.start()}const o=new _e(this.params);await o.start()}async getResult(){return this.db.data.grouper_result}},be=require("@soga/types"),ve=require("@soga/node-types"),Pe=require("@soga/mediainfo"),xe=require("@soga/fileutils"),ze=require("fs-extra"),Te=h(require("check-disk-space")),Re=require("@soga/error"),Se=class extends q{async start(){this.prepareResult||(await this.checkStorage(),await this.calculateMeta(),await this.calculateProgress())}async checkStorage(){const{length:t}=this.params.hosts,e=await(0,Te.default)(this.params.outputRoot),a=e.free,i=e.diskPath;if((3+t)*this.params.input.filesize>a)throw(0,Re.buildDError)(new Error(`${i} have no enough computer disk space, please adjust the temporary path in user settings.`),{message:`${i} have no enough computer disk space, please adjust the temporary path in user settings.`,detail:`${i} have no enough computer disk space to process ${this.params.input.filepath}`})}async calculateMeta(){if(this.meta)return this.meta;const{filename:t,local_btime:e,local_ctime:a,local_mtime:i,filesize:s}=this.params.input,r={file:t,size:s,btime:e,ctime:a,mtime:i,md5:""};return await this.setMeta(r),r}async calculateProgress(){if(this.prepareResult)return;const t={[ve.UploadProgress.prepare]:{weight:0,percent:1},[ve.UploadProgress.calculate_md5]:{weight:0,percent:0},[ve.UploadProgress.separate_video]:{weight:0,percent:0},[ve.UploadProgress.separate_audio]:{weight:0,percent:0},[ve.UploadProgress.separate_subtitle]:{weight:0,percent:0},[ve.UploadProgress.transcode_video]:{weight:0,percent:0},[ve.UploadProgress.transcode_audio]:{weight:0,percent:0},[ve.UploadProgress.transcode_thumbnail]:{weight:0,percent:0},[ve.UploadProgress.transcode_source]:{weight:0,percent:0},[ve.UploadProgress.transcode_txt]:{weight:0,percent:0},[ve.UploadProgress.transcode_img]:{weight:0,percent:0},[ve.UploadProgress.group_media]:{weight:0,percent:0},[ve.UploadProgress.upload_baidu]:{weight:0,percent:0},[ve.UploadProgress.upload_ali]:{weight:0,percent:0},[ve.UploadProgress.end]:{weight:0,percent:0}},e={keep_preview:this.params.keepPreview,keep_source:this.params.keepSource},a=await(0,xe.getFileSize)(this.params.input.filepath);t[ve.UploadProgress.prepare].weight=t[ve.UploadProgress.end].weight=Math.ceil(a/1024/1024/500),t[ve.UploadProgress.calculate_md5].weight=Math.ceil(a/1024/1024/200);let i=0;if(this.isMedia)if(this.params.keepPreview){const s=await(0,Pe.parseMediaInfo)(this.params.input.filepath),r=s?.general?.duration??0;if(s.video?.length){const e=s.video[0],{width:a,height:i,codec:r}=e,o=(0,xe.isVideoSupport)(r),{duration:n}=s.general,h=o?n/400:n*(a*i)/1920/1080;t[ve.UploadProgress.separate_video].weight=Math.ceil(h),t[ve.UploadProgress.transcode_video].weight=Math.ceil(.01*n)}if(s.audio?.length){const{duration:e}=s.general;let a=0;s.audio.forEach(t=>{const{codec:i,lossless:s,channels:r}=t,o={high_need:!1,high_transcode:!1,adapt_need:!1,adapt_transcode:!1};(0,xe.isAudioAdapt)(i)?r>2?(o.high_need=!0,o.high_transcode=!1,o.adapt_need=!0,o.adapt_transcode=!0):(o.high_need=!1,o.adapt_need=!0,o.adapt_transcode=!1):(0,xe.isAudioHigh)(i)?(o.high_need=!0,o.high_transcode=!1,o.adapt_need=!0,o.adapt_transcode=!0):(o.high_need=!1,o.adapt_need=!0,o.adapt_transcode=!1,s&&(o.high_need=!0,o.high_transcode=!0)),o.adapt_need&&(a+=o.adapt_transcode?e/40:5),o.high_need&&(a+=o.high_transcode?e/20:10)}),t[ve.UploadProgress.separate_audio].weight=Math.ceil(a),t[ve.UploadProgress.transcode_audio].weight=Math.ceil(.01*e)}const o=s.video?.length??0,n=s.audio?.length??0;if(o||n){e.keep_preview=!0;const o=(s.text?.length||0)+(this.params.subtitles?.length||0);t[ve.UploadProgress.separate_subtitle].weight=Math.ceil(o),t[ve.UploadProgress.transcode_thumbnail].weight=Math.ceil(.08*r),i+=a,t[ve.UploadProgress.group_media].weight=Math.ceil(a/1024/1024/10)}else e.keep_preview=!1,e.keep_source=!0,i+=a}else e.keep_source=!0,i+=a;else this.isTxt?e.keep_preview?(t[ve.UploadProgress.transcode_txt].weight=Math.ceil(a/1024/1024/1),i+=a):(e.keep_source=!0,i+=a):this.isImg?e.keep_preview&&(t[ve.UploadProgress.transcode_img].weight=Math.ceil(a/1024/1024/1),i+=a):(e.keep_source=!0,i+=a);e.keep_source&&(t[ve.UploadProgress.transcode_source].weight=Math.ceil(a/1024/1024/30)),this.params.hosts.includes(be.HostType.BAIDU)&&(t[ve.UploadProgress.upload_baidu].weight=Math.ceil(i/1024/1024/1)),this.params.hosts.includes(be.HostType.ALI)&&(t[ve.UploadProgress.upload_ali].weight=Math.ceil(i/1024/1024/2));const s={preview:e.keep_preview,source:e.keep_source};await this.setKeeps(s),await this.setPrepareResult(t)}},De=async t=>{await(0,ze.ensureDir)(t.outputRoot);const e=await b(t);try{const a=new Se({...t,db:e});return await a.start(),a}catch(t){}},Me=require("@soga/node-types"),Ie=require("crypto"),Fe=require("fs-extra"),$e=class extends q{async start(){await this.processFile();return await this.getResult()}async calculateMd5(){if(this.md5)return this.md5;const t=this.params.input.filepath,e=this.params.input.filesize;let a=0;const i=await new Promise((i,s)=>{let r=0;const o=(0,Ie.createHash)("md5"),n=(0,Fe.createReadStream)(t,{highWaterMark:4194304});n.on("data",async t=>{o.update(t),r+=t.length;const i=r/e;r-a>104857600&&(a=r,await this.postProgress({type:Me.UploadProgress.calculate_md5,percent:Math.min(i,1)}))}),n.on("end",()=>{const t=o.digest("hex");i(t)}),n.on("error",t=>{s(t)})});return i&&await this.setMd5(i),await this.postProgress({type:Me.UploadProgress.calculate_md5,percent:1}),i}async getResult(){if(this.result)return this.result;const{sourceResult:t,grouperResult:e,imgResult:a,txtResult:i,meta:s,keeps:r}=this,{length:o}=this.params.hosts,n={meta:{preview:r.preview,source:r.source,file:s}};for(let s=0;s<o;s++){const r=this.params.hosts[s];n[r]={max_size:0,parts:[]};const o=t=>{n[r].parts=[...n[r].parts,...t]},h=a?.data[r];if(h){h.cache&&(n[r].cache=h?.cache);const t=h.parts?.map(t=>({...t,preview:!0,source:!1}));t&&o(t),n.meta.img=a.meta,h.img&&(n[r].img=h.img)}const d=i?.data[r];if(d){o((d.parts||[]).map(t=>({...t,preview:!0,source:!1}))),n[r].cache=d.cache,n[r].txt={entrance:d.entrance,pad:i?.meta.pad,pages:i?.meta.pages}}const c=e?.data[r];if(c?.parts){o(c.parts.map(t=>({...t,preview:!0,source:!1}))),n.meta.audios=e.meta.audios,n.meta.videos=e.meta.videos,n[r].cache=c.cache,n[r].media={audios:c.audios,videos:c.videos,subtitles:c.subtitles,thumbnail:c.thumbnail,cover:c.cover}}const l=t?.data[r];if(l?.parts){o(l.parts.map(t=>{let e=!0;return(this.isMedia||this.isTxt)&&(e=!1),{...t,preview:e,source:!0}})),n[r].source={head:t.meta.head,download:l.download}}[...n[r]?.parts].forEach(t=>{t.size>n[r].max_size&&(n[r].max_size=t.size)})}return await this.setResult(n),n}async processFile(){const t="encoder_processed";if(this.db.data[t])return;const e=await De(this.params),{keeps:a}=e,i={...this.params,keepPreview:a.preview,keepSource:a.source},s=await this.calculateMd5();if(await this.setMd5(s),i.keepSource){const t=new N(this.params);await t.start()}if(e.isMedia&&i.keepPreview){const t=new ye(this.params);await t.start()}if(e.isTxt&&i.keepPreview){const t=new W(this.params);await t.start()}if(e.isImg){const t=new at(this.params);await t.start()}this.db.data[t]=!0,await this.db.write()}},ke=async t=>{try{const e=await b(t),a=new $e({...t,db:e});return a.start()}catch(e){throw(0,c.buildDError)(e,{message:"Error occurred during file encoding",detail:`Error occurred during file encoding: ${t.input.filepath}`})}};
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{buildDError as t}from"@soga/error";import{getDb as e}from"@soga/lowdb";import{createHash as a}from"crypto";import{createReadStream as i,createWriteStream as s,existsSync as r,remove as o,stat as n,writeFile as h}from"fs-extra";import{truncate as d}from"fs/promises";import{resolve as c}from"path";import{pipeline as l}from"stream/promises";function u(t){const e=a("md5");return e.update(`${t}`),e.digest("hex")}async function p(t){await new Promise((e,a)=>{(async()=>{const r=c(t.outputRoot,t.filename);await o(r);let n=!1;const h=s(r);h.on("open",()=>{n=!0}).on("error",async t=>{n&&h.close(),await o(r),a(t)});const{length:d}=t.files,l=async(e=0)=>{if(e<d){const a=t.files[e],s=t.files.length;await new Promise((t,e)=>{const d=i(a);d.pipe(h,{end:!s}),d.on("end",()=>{d.close(),t(!0)}),d.on("error",async t=>{d.destroy(),n&&h.close(),await o(r),e(t)})}),await l(e+1)}};await l(0),n&&h.end(),e(!0)})()})}async function g(t,a){const i=u(JSON.stringify({...t,dbName:a})),s="db_unique_key",r=c(t.outputRoot,a),o=await e(r,{});return o.data[s]?o.data[s]!=i&&(o.data={[s]:i},await o.write()):(o.data[s]=i,await o.write()),o}async function m(t){return await g({file_id:t.id,input:{filepath:t.input.filepath,filesize:t.input.filesize},outputRoot:t.outputRoot},"encoder_store.json")}async function w({input_path:t,target_path:e,start:a,end:n}){const h=i(t,{start:a,end:n,highWaterMark:65536}),d=s(e);try{await l(h,d)}catch(t){try{r(e)&&await o(e)}catch(t){console.warn("Failed to clean up incomplete file:",t.message)}throw t}}import{resolve as f}from"path";import{gzip as _,getFileBufferSlice as y}from"@soga/utils";import{getFileSize as b}from"@soga/fileutils";import{buildDError as v}from"@soga/error";import{UploadProgress as P}from"@soga/node-types";import{rename as x,stat as D,writeFile as T}from"fs-extra";import{HostType as z}from"@soga/types";var R=2097152,I={[z.BAIDU]:52428800,[z.ALI]:2147483648};z.BAIDU,z.ALI;import{HostType as M,RecordFtype as $,RecordType as S}from"@soga/types";import{calculateMd4 as k,calculateMd5 as F,calculateSha1 as E}from"@soga/utils";import{parentPort as N}from"worker_threads";var C=class{segmentNames={};params;id;port=null;db;get lowData(){return this.db.data}get isVideo(){return this.params.type==S.VIDEO}get isAudio(){return this.params.type==S.AUDIO}get isMedia(){return this.isAudio||this.isVideo}get isTxt(){return this.params.type==S.DOC&&this.params.ftype==$.DOC_TXT}get isImg(){return this.params.type==S.IMAGE}getSizeLimit(t){return I[t]||52428800}getFilesize(){return this.params.input.filesize}constructor(t){this.params=t,this.id=t.id,this.port=t.port??null,this.db=t.db}async getPartInfo({host_type:t,filepath:e,start:a,end:i,filename:s,index:r},o=!0){const n={start:a,end:i,size:i-a+1,path:e,index:r,file:s,md5:o?await F({file:e,start:a,end:i}):""};if(o){if(t===M.BAIDU){const t=await k({file:e,start:a,end:i});n.md4=t}if(t===M.ALI){const t=await E({file:e,start:a,end:i});n.sha1=t}}return n}async getStore(t){const{id:e,input:a,outputRoot:i}=this.params;return await g({file_id:e,input:{filepath:a.filepath,filesize:a.filesize},outputRoot:i},t)}async postProgress(t){const e={step:t.type,percent:t.percent};await this.postMessage({id:this.id,type:"percent",data:e})}async postMessage(t){this.port?this.port.postMessage(t):N&&N.postMessage(t)}async setKeeps(t){this.lowData.keeps=t,await this.db.write()}get keeps(){return this.lowData.keeps}async setMeta(t){this.lowData.meta=t,await this.db.write()}get meta(){return this.lowData.meta}async setSourceResult(t){this.lowData.source_result=t,await this.db.write()}get sourceResult(){return this.lowData.source_result}async setPrepareResult(t){this.lowData.prepare_result=t,await this.db.write()}get prepareResult(){return this.lowData.prepare_result}async setMd5(t){this.lowData.meta.md5=t,await this.db.write()}get md5(){return this.lowData.meta.md5}async setSubtitleEncoderResult(t){this.lowData.subtitle_encoder_result=t,await this.db.write()}get subtitleEncoderResult(){return this.lowData.subtitle_encoder_result}async setAudioSeparatorResult(t){this.lowData.audio_separator_result=t,await this.db.write()}get audioSeparatorResult(){return this.lowData.audio_separator_result}async setAudioTranscoderResult(t){this.lowData.audio_transcoder_result=t,await this.db.write()}get audioTranscoderResult(){return this.lowData.audio_transcoder_result}async setCoverResult(t){this.lowData.cover_result=t,await this.db.write()}get coverResult(){return this.lowData.cover_result}async setVideoTranscoderResult(t){this.lowData.video_transcoder_result=t,await this.db.write()}get videoTranscoderResult(){return this.lowData.video_transcoder_result}async setVideoThumbnailerResult(t){this.lowData.video_thumbnailer_result=t,await this.db.write()}get videoThumbnailerResult(){return this.lowData.video_thumbnailer_result}async setGrouperResult(t){this.lowData.grouper_result=t,await this.db.write()}get grouperResult(){return this.lowData.grouper_result}async setImgResult(t){this.lowData.img_result=t,await this.db.write()}get imgResult(){return this.lowData.img_result}async setTxtResult(t){this.lowData.txt_result=t,await this.db.write()}get txtResult(){return this.lowData.txt_result}async setResult(t){this.lowData.result=t,await this.db.write()}get result(){return this.lowData.result}_syncGetId({file:t,start:e,end:a},i){const s=`${i}_key_index`,r=`${i}_key_map`,o=`${t}_${e||0}_${a||0}`,n=this.db.data[r]||{};if(n[o])return n[o];this.db.data[s]=this.db.data[s]||0,this.db.data[r]=this.db.data[r]||{};const h=this.db.data[s]+1,d=`id_${h}`;return this.db.data[r][o]=d,this.db.data[s]=h,d}_syncSetIdMap({id:t,file:e,start:a,end:i},s,r){const o=`${s}_${r}_id_map`;this.db.data[o]=this.db.data[o]||{},this.db.data[o][t]={f:e,s:a,e:i}}},L=class extends C{syncGetSourceId(t){return this._syncGetId(t,"source")}async getSourceId(t){const e=this.syncGetSourceId(t);return await this.db.write(),e}getSourceIdMap(t){return this.db.data[`source_${t}_id_map`]||{}}syncSetSourceIdMap(t,e){this._syncSetIdMap(t,"source",e)}async setSourceIdMap(t,e){this.syncSetSourceIdMap(t,e),await this.db.write()}getSourceSegmentName=(t,e)=>{const a=`source_${e}_${t}`;if(this.segmentNames[a])return this.segmentNames[a];const i=`s-${u(`source-${e}-${this.md5}-${t}`)}`;return this.segmentNames[a]=i,i}},A=class extends L{head_size=32;getZipFilePath(){return f(this.params.outputRoot,"souce_zip.bin")}getDownloadListFileName(t){return`source_${t}_download_list.json`}getPartName(t,e){return this.getSourceSegmentName(e,t)}getPartPath(t,e){return f(this.params.outputRoot,this.getPartName(t,e))}get dbData(){return this.db.data}async setPartList(t,e){const a=`source_${t}_part_list`;this.dbData[a]=e,await this.params.db.write()}getPartList(t){const e=`source_${t}_part_list`;return this.dbData[e]}async setDownloadMap(t,e){const a=`source_${t}_download_map`;this.dbData[a]=e,await this.params.db.write()}getDownloadMap(t){const e=`source_${t}_download_map`;return this.dbData[e]}async sendProgress(t){await this.postProgress({type:P.transcode_source,percent:t})}async setDownloadList(t,e){const a=`source_${t}_download_list`;this.dbData[a]=e,await this.params.db.write()}getDownloadList(t){const e=`source_${t}_download_list`;return this.dbData[e]}async start(){try{if(this.sourceResult)return await this.sendProgress(1),this.sourceResult;await this.gzip();const{length:t}=this.params.hosts;for(let e=0;e<t;e++){const t=this.params.hosts[e];await this.calculatePartList(t),await this.processDownloadMap(t)}await this.sendProgress(.9);const e=await this.getResult();return await this.sendProgress(1),e}catch(t){throw v(t,{message:"Error occurred during source encoding",detail:`Error occurred during source encoding: ${this.params.input.filepath}`})}}async gzip(){if(this.dbData.source_gziped)return;const t=this.params.input.filepath,e=this.getZipFilePath();await _(t,e,async({percent:t})=>{await this.sendProgress(.6*t)}),this.dbData.source_gziped=!0,await this.params.db.write()}async getResult(){if(this.sourceResult)return this.sourceResult;const t={meta:await this.getMetaData(),data:{}},{length:e}=this.params.hosts;for(let a=0;a<e;a++){const e=this.params.hosts[a],i=this.getPartList(e),s=this.getDownloadMap(e);t.data[e]={download:s,parts:i}}return await this.setSourceResult(t),t}async getMetaData(){const t="source_meta",e=this.dbData[t];if(e)return e;const a=this.getZipFilePath(),i=await b(a),s={path:a,start:0,end:0},{head_size:r}=this;s.end=i<=r?i-1:r-1;const o={head:(await y(s.path,s.start,s.end)).toString("base64")};return this.dbData[t]=o,await this.params.db.write(),o}async writeDownloadListFile(t,e){const a=this.getDownloadListFileName(t),i=f(this.params.outputRoot,a);await T(i,e,"utf-8");return{file_path:i,size:await b(i)}}async processDownloadMap(t){const e=this.getDownloadMap(t);if(e)return e;const a=this.getDownloadList(t);let r;const{file_path:o,size:n}=await this.writeDownloadListFile(t,JSON.stringify(a)),h=this.getSizeLimit(t),d=this.getPartList(t);if(d.length){const e=d[d.length-1],{path:a,size:c,file:u,index:p,end:g,start:m}=e,w=f(this.params.outputRoot,u);if(c+n<=h){await async function({source1:t,source2:e,target:a}){const r=i(t.filepath,{start:t.start,end:t.end}),o=s(a);await l(r,o);const n=i(e),h=s(a,{flags:"a"});await l(n,h)}({source1:{filepath:a,start:m,end:g},source2:o,target:w});const e=(await D(w)).size,h=e-1,c=e-n,f=await this.getPartInfo({host_type:t,filepath:w,start:0,end:e-1,filename:u,index:p});d[d.length-1]=f;r={id:await this.getSourceId({file:u,start:c,end:h}),file:u,start:c,end:h}}else{const e=p+1,a=this.getPartName(t,e),i=this.getPartPath(t,e);await x(o,i);const s=await this.getSourceId({file:a,start:0,end:n-1}),h=await this.getPartInfo({host_type:t,filepath:i,start:0,end:n-1,filename:a,index:e});d.push(h),r={id:s,file:a,start:0,end:n-1}}return await this.setPartList(t,d),await this.setDownloadMap(t,r),r}}async calculatePartList(t){const e=`source_${t}_list_calculated`;if(this.dbData[e])return;const a=this.getZipFilePath(),i=await b(a),s=[],r=this.getSizeLimit(t),{head_size:o}=this,n=[];if(i>o){let e=0;for(let h=o;h<=i-1;h+=r){const o=Math.min(h+r-1,i-1),d=this.getPartName(t,e),c=await this.getPartInfo({host_type:t,filepath:a,start:h,end:o,filename:d,index:e});let l=0;for(let t=h;t<o;t+=R){const e=Math.min(t+R-1,o),a=e-t+1,i=l+a-1,s=await this.getSourceId({file:"source_zip",start:t,end:e});n.push({id:s,file:d,start:l,end:i}),l+=a}s.push(c),e++}}await this.setPartList(t,s),await this.setDownloadList(t,n),this.dbData[e]=!0,await this.db.write()}};import{resolve as O}from"path";import{createWriteStream as U,readFile as V,remove as G}from"fs-extra";import{getFileBufferSlice as B}from"@soga/utils";import j from"zlib";import{saveFileAsUtf8 as q}from"@soga/utils";import{buildDError as X}from"@soga/error";import{UploadProgress as K}from"@soga/node-types";import{resolve as J}from"path";import{getFileSize as H}from"@soga/fileutils";import{copy as Q,writeFile as W}from"fs-extra";var Z=class extends C{get preview_common_db_data(){return this.db.data}async getCurrentFileIndex(t){const e=this.db.data[`preview_${t}_current_index`];return"number"!=typeof e?(this.db.data[`preview_${t}_current_index`]=0,await this.db.write(),0):e}async increaseCurrentFileIndex(t){const e=await this.getCurrentFileIndex(t)+1;return this.db.data[`preview_${t}_current_index`]=e,await this.db.write(),e}getPartName(t,e){return this.getPreviewSegmentName(e,t)}getPartPath(t,e){return J(this.params.outputRoot,this.getPartName(t,e))}syncGetPreviewId(t){return this._syncGetId(t,"preview")}async getPreviewId(t){const e=this.syncGetPreviewId(t);return await this.db.write(),e}getPreviewIdMap(t){return this.db.data[`preview_${t}_id_map`]||{}}syncSetPreviewIdMap(t,e){this._syncSetIdMap(t,"preview",e)}async setPreviewIdMap(t,e){this.syncSetPreviewIdMap(t,e),await this.db.write()}getPreviewSegmentName=(t,e)=>{const a=`preview_${e}_${t}`;if(this.segmentNames[a])return this.segmentNames[a];const i=`p-${u(`preview-${e}-${this.md5}-${t}`)}`;return this.segmentNames[a]=i,i};async calculatePartList(t,e){const a=[],i=await this.getCurrentFileIndex(t);for(let s=0;s<i+1;s++){const i=this.getPartName(t,s),r=this.getPartPath(t,s),o=await H(r),n=await this.getPartInfo({host_type:t,filename:i,filepath:r,index:s,start:0,end:o-1},e);a.push(n)}return a}getPartListKey(t){return`preview_${t}_part_list`}async completePartList(t){const e=await this.getPartList(t);if(e){const a=[];for(const i of e)if(i.md5)a.push(i);else{const e=await this.getPartInfo({filename:i.file,filepath:i.path,start:i.start,end:i.end,host_type:t,index:i.index},!0);a.push(e)}await this.setPartList(t,a)}}async getPartList(t){const e=this.getPartListKey(t),a=this.preview_common_db_data[e];if(a)return a}async setPartList(t,e){const a=this.getPartListKey(t);this.preview_common_db_data[a]=e,await this.db.write()}async attachCacheData(){const{hosts:t}=this.params;for(const e of t)await this.attachHostCacheData(e),await this.completePartList(e)}getCacheInfo(t){const e=`preview_${t}_cache_info`;return this.preview_common_db_data[e]}async writeCacheFile(t,e){const a=`preview_${t}_cache_info.txt`,i=J(this.params.outputRoot,a);await W(i,e,"utf-8");return{file_path:i,size:await H(i)}}async setCacheInfo(t,e){const a=`preview_${t}_cache_info`;this.preview_common_db_data[a]=e,await this.db.write()}async attachHostCacheData(t){if(this.getCacheInfo(t))return;const e=await this.getPartList(t),a=this.getPreviewIdMap(t),{file_path:r,size:o}=await this.writeCacheFile(t,JSON.stringify(a)),h=this.getSizeLimit(t);if(e.length){const a=e[e.length-1],{path:c,size:u,file:p,index:g,end:m}=a;let w;if(u+o<=h){await async function({filepath:t,size:e},a){(await n(t)).size>e&&await d(t,e);const r=i(a),o=s(t,{flags:"a"});await l(r,o)}({filepath:c,size:u},r);const a=await H(c),h=await this.getPartInfo({host_type:t,filename:p,filepath:c,index:g,start:0,end:a-1});e[e.length-1]=h;const f=m+1,_=m+o;w={id:await this.getPreviewId({file:p,start:f,end:_}),file:p,start:f,end:_}}else{const a=g+1,i=this.getPartName(t,a),s=this.getPartPath(t,a);await Q(r,s);const n=await this.getPreviewId({file:i,start:0,end:o-1}),h=await this.getPartInfo({host_type:t,filename:i,filepath:s,index:a,start:0,end:o-1},!1);e.push(h),await this.setPartList(t,e),w={id:n,file:i,start:0,end:o-1}}w&&await this.setCacheInfo(t,w)}}},Y=class extends Z{content_size_1=81920;content_size_2=102400;totalPage=1;hashBuffer=Buffer.from("dpan");get hashBufferLength(){return this.hashBuffer.length}getU8FileName(){return`text_utf8_${this.params.id}.txt`}getU8FilePath(){return O(this.params.outputRoot,this.getU8FileName())}async sendProgress(t){await this.postProgress({type:K.transcode_txt,percent:t})}get dbData(){return this.db.data}async start(){try{if(this.dbData.txt_result)return await this.sendProgress(1),this.dbData.txt_result;await this.txtConvertToUtf8File(),await this.sendProgress(.2);const{length:t}=this.params.hosts;for(let e=0;e<t;e++){const a=this.params.hosts[e];await this.txtConvertToGzipFile(a),await this.sendProgress(.2+(e+1)/t*.6)}await this.attachCacheData();const e=await this.getResult();return await this.clean(),await this.sendProgress(1),e}catch(t){throw X(t,{message:"Error occurred during txt encoding",detail:`Error occurred during txt encoding: ${this.params.input.filepath}`})}}async getResult(){if(this.txtResult)return this.txtResult;const t={meta:{pad:this.hashBufferLength,pages:this.totalPage},data:{}};for(const e of this.params.hosts)t.data[e]={cache:this.getCacheInfo(e),parts:await this.getPartList(e),entrance:await this.getEntranceInfo(e)};return await this.setTxtResult(t),t}async clean(){try{if(this.params.debug)return;const t=this.getU8FilePath();await G(t)}catch(t){}}async setEntranceInfo(t,e){const a=`txt_${t}_entrance`;this.dbData[a]=e,await this.db.write()}async getEntranceInfo(t){const e=`txt_${t}_entrance`,a=this.dbData[e];if(a)return a}async txtConvertToUtf8File(){if(this.dbData.txt_utf8_converted)return;const t=this.params.input.filepath,e=this.getU8FilePath();await q(t,e),this.dbData.txt_utf8_converted=!0,await this.db.write()}async txtConvertToGzipFile(t){if(await this.getEntranceInfo(t))return;const e=this.getSizeLimit(t),a=this.getU8FilePath(),i=await this.calculateSlice(),{length:s}=i,r={};let o=0,n=U(this.getPartPath(t,await this.getCurrentFileIndex(t)));for(let h=0;h<s;h++){const d=h==s-1?0:h+1,c=i[d],{index:l,start:u,end:p}=c,g={page:l+1,text:(await B(a,u,p)).toString("utf8")},m=JSON.stringify(g);let w=Buffer.from(m,"utf8");if(0==d){const t={...g,map:r};w=Buffer.from(JSON.stringify(t),"utf8")}const f=await this.getPreviewId({file:"u8zip",start:u,end:p});await new Promise((a,i)=>{j.gzip(w,async(s,h)=>{if(s)return i(s);const c=h.length<this.hashBufferLength?this.hashBuffer:h.subarray(0,this.hashBufferLength),l=Buffer.concat([c,h]),u=l.length;if(o+u>e){n.end();const e=await this.increaseCurrentFileIndex(t);n=U(this.getPartPath(t,e)),o=0}const p=o,g=o+u-1;if(n.write(l),o+=u,0==d){n.end();const e={id:f,start:p,end:g,file:this.getPartName(t,await this.getCurrentFileIndex(t))};await this.setEntranceInfo(t,e)}else r[`p_${d+1}`]={id:f,f:this.getPartName(t,await this.getCurrentFileIndex(t)),s:p,e:g};this.syncSetPreviewIdMap({id:f,file:this.getPartName(t,await this.getCurrentFileIndex(t)),start:p,end:g},t),a(!0)})})}await this.db.write();const h=await this.calculatePartList(t,!1);await this.setPartList(t,h)}async calculateSlice(){if(this.dbData.txt_slice_list)return this.dbData.txt_slice_list;const t=this.getU8FilePath(),e=await new Promise((e,a)=>{V(t,"utf8",(t,i)=>{if(t)return void a(t);const s=this.content_size_1,r=this.content_size_2,o=[];let n=0,h=0,d=0;for(;h<i.length;){let t=Math.min(h+r,i.length);const e=Math.min(h+s,i.length),a=i.slice(e,t-1).indexOf("#");-1!==a&&(t=e+a);const c=i.slice(h,t),l=Buffer.byteLength(c);o.push({index:n++,start:d,end:d+l-1}),this.totalPage=n,h=t,d+=l}e(o)})});return this.dbData.txt_slice_list=e,await this.db.write(),e}};import{resolve as tt}from"path";import{getMetadata as et,compress as at}from"@soga/imgutils";import{gzip as it}from"@soga/utils";import{getFileSize as st}from"@soga/fileutils";import{buildDError as rt}from"@soga/error";import{UploadProgress as ot}from"@soga/node-types";import{remove as nt}from"fs-extra";var ht=class extends Z{getCompressFileName(){return"img_compress.jpg"}getCompressFilePath(){return tt(this.params.outputRoot,this.getCompressFileName())}getGzFileName(){return"compressed_img.zip"}getGzFilePath(){return tt(this.params.outputRoot,this.getGzFileName())}async sendProgress(t){await this.postProgress({type:ot.transcode_img,percent:t})}get dbData(){return this.db.data}async start(){try{if(this.imgResult)return await this.sendProgress(1),this.imgResult;await this.compress(),await this.sendProgress(.1),await this.gzip(),await this.sendProgress(.4);const{hosts:t}=this.params,{length:e}=t;for(let a=0;a<e;a++){const e=t[a];await this.splitFile(e),await this.calculatePartList(e,!1)}await this.attachCacheData(),await this.sendProgress(.9);const a=await this.getResult();return await this.clean(),await this.sendProgress(1),a}catch(t){throw rt(t,{message:"Error occurred during image encoding",detail:`Error occurred during image encoding: ${this.params.input.filepath}`})}}getCacheInfoFileName(t){return`img_${t}_cache.json`}async getResult(){if(this.imgResult)return this.imgResult;const{input:t}=this.params,e=t.filepath,{width:a,height:i}=await et(e),s=this.getCompressFilePath(),{width:r,height:o}=await et(s),n=await st(s),h={meta:{width:a,height:i,size:t.filesize,t_width:r,t_height:o,t_size:n},data:{}},{length:d}=this.params.hosts;for(let t=0;t<d;t++){const e=this.params.hosts[t],a=await this.getPartList(e),i=this.getPreviewList(e);h.data[e]={img:{preview:i},cache:this.getCacheInfo(e),parts:a}}return await this.setImgResult(h),h}async clean(){try{if(this.params.debug)return;const t=this.getCompressFilePath();await nt(t)}catch(t){}}async compress(){if(this.dbData.img_compressed)return;const t=this.getCompressFilePath();await at({ffmpeg_path:this.params.ffmpegPath,input_path:this.params.input.filepath,output_path:t}),this.dbData.img_compressed=!0,await this.db.write()}async gzip(){if(this.dbData.img_gziped)return;const t=this.getCompressFilePath(),e=this.getGzFilePath();await it(t,e),this.dbData.img_gziped=!0,await this.db.write()}async setPreviewList(t,e){const a=`img_${t}_preview_list`;this.dbData[a]=e,await this.db.write()}getPreviewList(t){const e=`img_${t}_preview_list`;return this.dbData[e]}async splitFile(t){if(this.getPreviewList(t))return;const e=this.getGzFilePath(),a=await st(e),i=this.getSizeLimit(t),s=[],r=[];for(let o=0;o<=a-1;o+=i){0!=o&&await this.increaseCurrentFileIndex(t);const n=Math.min(o+i-1,a-1),h=await this.getCurrentFileIndex(t),d=this.getPartName(t,h),c=this.getPartPath(t,h);await w({input_path:e,target_path:c,start:o,end:n});const l=0,u=n-o,p=await this.getPartInfo({host_type:t,filepath:c,filename:d,start:l,end:u,index:h},!1);s.push(p);const g=await this.getPreviewId({file:d,start:l,end:u});r.push({id:g,file:d,start:l,end:u}),await this.setPreviewIdMap({id:g,file:d,start:l,end:u},t)}await this.setPartList(t,s),await this.setPreviewList(t,r)}};import dt from"fluent-ffmpeg";import{spawn as ct}from"child_process";import{parseMediaInfo as lt}from"@soga/mediainfo";var ut=class extends Z{async getMediainfo(){const{mediainfo:t}=this.db.data;if(t)return t;const e=this.params.input.filepath,a=await lt(e);return this.db.data.mediainfo=a,await this.params.db.write(),a}constructor(t){super(t),dt.setFfmpegPath(t.ffmpegPath)}getFluent(){return dt()}async ffmpeg(t,e){const a=this.params.ffmpegPath;return await new Promise((i,s)=>{const r=ct(a,t,Object.assign({stdio:"ignore"},e));r.on("close",t=>{i(t)}),r.on("error",t=>{s(t)})})}};import{resolve as pt}from"path";import{isValidFile as gt,isVideoSupport as mt}from"@soga/fileutils";import{UploadProgress as wt}from"@soga/node-types";import{buildDError as ft}from"@soga/error";var _t=({type:t,track_order:e,quality:a})=>`audio-${e}-${a}-${t}.${"manifest"===t?"m3u8":"mp4"}`,yt=({width:t,height:e})=>`video-formatted-${t}-${e}.mp4`,bt=t=>`grouper_result_${t}`,vt=t=>{let e=0,a=0,i=0;t.segments.forEach(t=>{a+=t.duration,e+=t.size;const s=8*t.size/t.duration;s>i&&(i=s)});const s=8*e/a;return{bandwidth:Math.ceil(i),average_bandwidth:Math.ceil(s)}},Pt=(t,e)=>{if("number"==typeof t.percent)return t.percent/100;return function(t){const e=t.split(":").map(parseFloat),[a=0,i=0,s=0]=e.reverse();return 3600*s+60*i+a}(t.timemark)/e};var xt=class extends ut{async start(){try{await this.separateVideo(),await this.postProgress({type:wt.separate_video,percent:1})}catch(t){throw ft(t,{message:"Error occurred during video separation",detail:`Error occurred during video separation: ${this.params.input.filepath}`})}}async separateVideo(){const t="video_separated";if(this.db.data[t])return;const e=await this.getMediainfo();if(!e?.video?.length)return;const a=e.video[0],i=yt({width:a.width,height:a.height}),s=pt(this.params.outputRoot,i),r=mt(a.codec),o=["-sn","-an","-map","0:v:0"];let n="copy";r||(n=a.width*a.height>=2073600?"libx265":"libx264","libx265"==n&&o.push("-pix_fmt","yuv420p")),o.push("-c:v",n);const h=a.duration;o.push("-y"),await new Promise((t,e)=>{const a=this.getFluent().input(this.params.input.filepath).outputOptions(o).on("progress",async t=>{if(!r&&t.frames){const e=Pt(t,h);await this.postProgress({type:wt.separate_video,percent:e})}}).on("end",async()=>{t("end"),a.kill("SIGKILL")}).on("error",async t=>{e(t)}).output(s);a.run()});if(!await gt(s))throw new Error("Separate Video track failed");this.db.data[t]=!0,await this.params.db.write()}};import{resolve as Dt}from"path";import{isValidFile as Tt,isAudioAdapt as zt,isAudioHigh as Rt}from"@soga/fileutils";import{UploadProgress as It}from"@soga/node-types";import{buildDError as Mt}from"@soga/error";var $t=class extends ut{async start(){try{await this.separateTracks(),await this.postProgress({type:It.separate_audio,percent:1})}catch(t){throw Mt(t,{message:"Error occurred during audio separation",detail:`Error occurred during audio separation: ${this.params.input.filepath}`})}}async separateTracks(){if(this.audioSeparatorResult)return;const t=await this.getMediainfo();if(!t?.audio?.length)return;const{audio:e}=t,a=e.length,i=[];for(let t=0;t<a;t++){const s=e[t],{codec:r,channels:o,lossless:n}=s,h={adapt:{need:!0,codec:"",channels:Math.min(o,2)},high:{need:!1,codec:"flac",channels:0}};zt(r)?o>2?(h.high.need=!0,h.high.codec="copy",h.adapt.codec=r,h.adapt.need=!0):(h.adapt.need=!0,h.adapt.codec="copy",h.adapt.channels=0):Rt(r)?(h.high.need=!0,h.high.codec="copy",h.adapt.need=!0,h.adapt.codec="aac"):(h.adapt.need=!0,h.adapt.codec="aac",n&&(h.high.need=!0,h.high.codec="flac")),h.adapt.need&&await this.separateAudioTrack(t,{type:"adapt",codec:h.adapt.codec,tracks:a,channels:h.adapt.channels,need_adapt:!0,need_high:h.high.need}),h.high.need&&await this.separateAudioTrack(t,{type:"high",codec:h.high.codec,tracks:a,channels:h.high.channels,need_adapt:h.adapt.need,need_high:!0}),i.push(h)}await this.setAudioSeparatorResult(i)}async separateAudioTrack(t,e){const a=`audio_separated_${t}_${e.type}`;if(this.db.data[a])return;const i=await this.getMediainfo();if(!i?.audio?.length)return;const s=i.audio[t];if(!s)return;const r=s?.duration??i.general?.duration,o=_t({type:"formatted",track_order:t,quality:e.type}),n=Dt(this.params.outputRoot,o),h=["-sn","-vn","-map",`0:a:${t}`];e.codec&&h.push("-c:a",e.codec),e.channels&&h.push("-ac",e.channels.toString()),h.push("-y"),await new Promise((a,i)=>{const s=this.getFluent().input(this.params.input.filepath).outputOptions(h).on("progress",async a=>{if("copy"!=e.codec){const i=Pt(a,r);let s=t;"adapt"==e.type?e.need_high?s+=1/3*i:s+=i:e.need_adapt?(s+=1/3,s+=2/3*i):s+=i;const o=s/e.tracks;await this.postProgress({type:It.separate_audio,percent:o})}}).on("end",async()=>{a("end"),s.kill("SIGKILL")}).on("error",async t=>{i(t)}).output(n);s.run()});if(!await Tt(n))throw new Error(`Separate audio track failed: [track_order:${t}, track_quality ${e.type}] `);if("copy"==e.codec){let a=t;"adapt"==e.type&&e.need_high?a+=1/3:a+=1;const i=a/e.tracks;await this.postProgress({type:It.separate_audio,percent:i})}this.db.data[a]=!0,await this.params.db.write()}};import{resolve as St}from"path";import{parseMediaInfo as kt}from"@soga/mediainfo";import{getMp4boxInfo as Ft}from"@soga/mp4box";import{parseM3U8 as Et}from"@soga/m3u8";import{UploadProgress as Nt}from"@soga/node-types";import{isValidFile as Ct,getStandardInfo as Lt}from"@soga/fileutils";import{remove as At}from"fs-extra";import{buildDError as Ot}from"@soga/error";var Ut=class extends ut{getVideoInitName({width:t,height:e}){return`video-init-${t}-${e}.mp4`}getVideoManifestName({width:t,height:e}){return`video-hls-${t}-${e}.m3u8`}async start(){try{await this.transcodeVideo(),await this.saveData(),await this.postProgress({type:Nt.transcode_video,percent:1})}catch(t){throw Ot(t,{message:"Error occurred during video transcoding",detail:`Error occurred during video transcoding: ${this.params.input.filepath}`})}}async saveData(){const t=await this.getMediainfo();if(!t?.video?.length)return;if(this.videoTranscoderResult)return;const{width:e,height:a}=t.video[0],i=yt({width:e,height:a}),s=St(this.params.outputRoot,i),r=this.getVideoManifestName({width:e,height:a}),o=St(this.params.outputRoot,r),n=await Et(o),{videos:h}=await Ft(s),{codec:d}=h[0],{bandwidth:c,average_bandwidth:l}=vt(n),u=(await kt(s)).video[0],p=Lt(e,a),g={m3u8:n,m3u8_path:o,codec:d,width:e,height:a,bandwidth:c,average_bandwidth:l,bitdepth:u?.bitdepth,bitrate:u?.bitrate,codec_name:u?.codec??"",framerate:u?.framerate,label:p?.label??"unknown"};await this.setVideoTranscoderResult(g),this.params.debug||await At(s)}async transcodeVideo(){const t="video_transcode_state";if(this.db.data[t])return;const e=await this.getMediainfo();if(!e?.video?.length)return;const a=e.video[0],i={width:a.width,height:a.height},s=yt(i),r=this.getVideoInitName(i),o=this.getVideoManifestName({width:a.width,height:a.height}),n=["-i",s,"-an","-sn","-c:v","copy","-hls_list_size","0","-hls_time","6","-hls_segment_type","fmp4","-hls_fmp4_init_filename",r,"-y",o];await this.ffmpeg(n,{cwd:this.params.outputRoot});const h=St(this.params.outputRoot,o);if(!await Ct(h))throw new Error("Transcode video track failed");this.db.data[t]=!0,await this.db.write()}};import{resolve as Vt}from"path";import{getFileSize as Gt,isValidFile as Bt}from"@soga/fileutils";import{getMp4boxInfo as jt}from"@soga/mp4box";import{parseM3U8 as qt}from"@soga/m3u8";import{parseMediaInfo as Xt}from"@soga/mediainfo";import{remove as Kt}from"fs-extra";import{buildDError as Jt}from"@soga/error";import{UploadProgress as Ht}from"@soga/node-types";var Qt=class extends ut{async start(){try{await this.transcodeAudios(),await this.saveData()}catch(t){throw Jt(t,{message:"Error occurred during audio transcoding",detail:`Error occurred during audio transcoding: ${this.params.input.filepath}`})}}async saveData(){if(this.audioTranscoderResult)return;const t=await this.getMediainfo();if(!t?.audio?.length)return;const e=t.audio.length,a=this.audioSeparatorResult,i=[],s={};for(let t=0;t<e;t++){const e=a[t];e.adapt.need&&(s.adapt=await this.getQualityData({track_order:t,quality:"adapt"})),e.high.need&&(s.high=await this.getQualityData({track_order:t,quality:"high"})),i.push(s)}await this.setAudioTranscoderResult(i);try{if(this.params.debug)return;for(let t=0;t<e;t++){const e=a[t];if(e.adapt.need){const e=_t({type:"formatted",track_order:t,quality:"adapt"}),a=Vt(this.params.outputRoot,e);await Kt(a)}if(e.high.need){const e=_t({type:"formatted",track_order:t,quality:"high"}),a=Vt(this.params.outputRoot,e);await Kt(a)}}}catch(t){}}async getQualityData({track_order:t,quality:e}){const a=_t({type:"formatted",track_order:t,quality:e}),i=Vt(this.params.outputRoot,a),s=await Xt(i);if(!s.audio?.length)throw new Error("parse mediainfo failed!");const r=s.audio[0],o=_t({type:"manifest",track_order:t,quality:e}),n=await Gt(i),h=Vt(this.params.outputRoot,o),d=await jt(i),{audios:c}=d,{language:l,codec:u}=c[0],p=l&&!l.startsWith("un")?{language:l}:void 0,g=await qt(h),{bandwidth:m,average_bandwidth:w}=vt(g);return{m3u8:g,m3u8_path:h,codec:u,codec_name:r.codec,...p,order:t,lossless:r.lossless,channels:r.channels,bandwidth:m,size:n,average_bandwidth:w}}async transcodeAudios(){const t="audio_transcoded";if(this.db.data[t])return;const e=await this.getMediainfo();if(!e?.audio?.length)return;const a=e.audio.length,i=this.audioSeparatorResult;for(let t=0;t<a;t++){const e=i[t];e.adapt.need&&await this.transcodeAudio(t,{...e.adapt,type:"adapt"}),e.high.need&&await this.transcodeAudio(t,{...e.high,type:"high"});const s=(t+1)/a;await this.postProgress({type:Ht.transcode_audio,percent:s})}await this.postProgress({type:Ht.transcode_audio,percent:1}),this.db.data[t]=!0,await this.db.write()}async transcodeAudio(t,e){const a=`audio-transcoded-${t}-${e.type}`;if(this.db.data[a])return;const i=_t({type:"formatted",track_order:t,quality:e.type}),s=_t({type:"init",track_order:t,quality:e.type}),r=_t({type:"manifest",track_order:t,quality:e.type}),o=["-i",i,"-vn","-sn","-c:a","copy","-hls_list_size","0","-hls_time","6","-hls_segment_type","fmp4","-hls_fmp4_init_filename",s,"-y",r];await this.ffmpeg(o,{cwd:this.params.outputRoot});const n=Vt(this.params.outputRoot,r);if(!await Bt(n))throw new Error(`Transcode audio track failed: [track_order:${t}, track_quality ${e.type}] `);this.db.data[a]=!0,await this.db.write()}};import{resolve as Wt}from"path";import{getFileSize as Zt}from"@soga/fileutils";import{combine as Yt}from"@soga/imgutils";import{copy as te}from"fs-extra";import{UploadProgress as ee}from"@soga/node-types";import{buildDError as ae}from"@soga/error";var ie=class extends ut{m3u8_data=null;thumbnail_duration=30;thumbnail_group=[];row=8;col=8;screenshot_width=480;screenshot_height=270;getScreenshotName(t){return`video_screenshot_${t}.jpg`}getTileName(t){return`video_tile_${t}.jpg`}getCoverName(){return"video_cover.jpg"}async updateImagePercent(t,e){const a="screenshot"==e?6*t/7:t/7+6/7;await this.postProgress({type:ee.transcode_thumbnail,percent:a})}store;async initStore(){this.store=await this.getStore("thumbnail_store.json")}async start(){if(!this.videoThumbnailerResult)try{const t=await this.getMediainfo();if(!t?.video?.length)return;if(await this.init(),!this.m3u8_data)return;await this.generateScreenshots(),await this.generateTiles(),await this.saveCoverInfo(),await this.saveThumbnailInfo()}catch(t){throw ae(t,{message:"Error occurred during video thumbnail generation",detail:`Error occurred during video thumbnail generation: ${this.params.input.filepath}`})}}async init(){await this.initStore(),await this.initScreenshotSize(),await this.initM3U8Data(),await this.initThumbnailDuration(),await this.initThumbnailGroup()}async saveThumbnailInfo(){if(this.videoThumbnailerResult)return;const{col:t,row:e,thumbnail_group:a,screenshot_width:i,screenshot_height:s}=this,r=a.length,o=[],n=[];for(let h=0;h<r;h++){const r=a[h],d=r.start_time,c=r.end_time,l=Math.floor(h/(e*t)),u=h%e*i,p=Math.floor(h%(t*e)/e)*s,g=this.getTileName(l);n.push(g),o.push({file:g,st:d,et:c,x:u,y:p,w:i,h:s})}const h=[...new Set(n)],d=h.length,c=[];for(let t=0;t<d;t++){const e=h[t],a=Wt(this.params.outputRoot,e),i=await Zt(a);c.push({file:e,file_path:a,size:i})}const l={width:this.screenshot_width,height:this.screenshot_height,row:this.row,col:this.col,tile_list:c,sprite_list:o};await this.setVideoThumbnailerResult(l)}async saveCoverInfo(){if(this.coverResult)return;const t=this.store.data.thumbnail_screenshot_largest,e=t?.index||0,{screenshot_width:a,screenshot_height:i}=this,s=this.getScreenshotName(e),r=Wt(this.params.outputRoot,s),o=this.getCoverName(),n=Wt(this.params.outputRoot,o);await te(r,n);const h={file:o,path:n,size:await Zt(n),width:a,height:i};await this.setCoverResult(h)}async generateTiles(){const t=this.store.data.thumbnail_tile_index||0,{length:e}=this.thumbnail_group,a=this.col*this.row,i=Math.ceil(e/a);for(let e=t;e<i;e++)await this.generateOneTile(e),await this.updateImagePercent((e+1)/i,"tile")}async generateOneTile(t){const{col:e,row:a}=this,i=this.thumbnail_group.length,s=a*e,r=t*s,o=Math.min(s,i-r),n=[];for(let t=0;t<o;t++){const e=this.getScreenshotName(r+t),a=Wt(this.params.outputRoot,e);n.push(a)}const h=this.getTileName(t),d=Wt(this.params.outputRoot,h);await this.createSpriteSheet(n,d),this.store.data.thumbnail_tile_index=t+1,await this.store.write()}async createSpriteSheet(t,e){await Yt({col:this.col,inputs:t,output_path:e,width:this.screenshot_width,height:this.screenshot_height})}getKeyFrameParams(t,e=0){if(t<1)return["-vframes","1"];{const a=Math.max(t-e-.3,.1);if(a<1)return["-vframes","1"];return["-ss",`${a.toFixed(3)}`,"-vframes","1"]}}async generateScreenshots(){if(this.store.data.thumbnail_screenshot_state)return;this.store.data.thumbnail_screenshot_index||=0;const t=this.store.data.thumbnail_screenshot_index,e=this.store.data.thumbnail_screenshot_largest,a={index:0,size:0};if(e){const t=e;a.index=t.index,a.size=t.size}const{segments:i}=this.m3u8_data,{thumbnail_group:s,screenshot_width:r}=this,{length:o}=s,n=async(t,{errorTimes:e,fixedSeconds:o})=>{const h=s[t].item.index,d=i[h];try{const e=this.getScreenshotName(t),i=`concat:${d.init_uri}|${d.uri}`,s=this.getKeyFrameParams(d.duration,o),n=r>this.screenshot_height?`${r}:-2`:`-2:${this.screenshot_height}`,h=["-i",i,...s,"-vf",`scale=${n}:flags=lanczos`,"-y",e];await this.ffmpeg(h,{cwd:this.params.outputRoot});const c=Wt(this.params.outputRoot,e),l=await Zt(c);if(0===l)throw new Error(`Generate video thumbnail error: [index: ${t}, start_time: ${d.start_time}, end_time: ${d.end_time}]`);l>=a.size&&(a.index=t,a.size=l,this.store.data.thumbnail_screenshot_largest=a,await this.store.write()),this.store.data.thumbnail_screenshot_index=t+1,await this.store.write()}catch(a){const i=Math.max(10,d.duration);if(!(e<3))throw a;await n(t,{errorTimes:e+1,fixedSeconds:o+i/5})}};for(let e=t;e<o;e++)await n(e,{errorTimes:0,fixedSeconds:0}),await this.updateImagePercent((e+1)/o,"screenshot");this.store.data.thumbnail_screenshot_state=!0,await this.store.write()}async initScreenshotSize(){const{thumbnail_screenshot_size:t}=this.store.data;if(t)return this.screenshot_width=t.width,void(this.screenshot_height=t.height);const e=await this.getMediainfo();if(!e?.video?.length)return;const a=e.video[0],{width:i,height:s}=a,r=i>s?480:270;this.screenshot_width=2*Math.floor(Math.min(r,i)/2),this.screenshot_height=2*Math.floor(this.screenshot_width*(s/i)/2),this.store.data.thumbnail_screenshot_size={width:this.screenshot_width,height:this.screenshot_height}}async initThumbnailGroup(){if(this.store.data.thumbnail_group)return void(this.thumbnail_group=this.store.data.thumbnail_group);const t=[],{segments:e}=this.m3u8_data,{length:a}=e,i=this.thumbnail_duration;let s=0,r=[];for(let o=0;o<a;o++){const n=e[o];if(s+=n.duration,r.push(n),s>=i||o===a-1){const e=r.length,a=r[0],i=r[e-1];t.push({duration:s,start_time:a.start_time,end_time:i.end_time,items:r,item:i}),s=0,r=[]}}if(t.length>1){if(t[t.length-1].duration<1){const e=t.pop(),a=t[t.length-2];a.duration=a.duration+e.duration,a.end_time=e.end_time,a.items=a.items.concat(e.items),a.item=e.item,e.items}}t.forEach(t=>{const{items:e}=t;for(let a=e.length-1;a>=0;a--)if(e[a].duration>1){t.item=e[a];break}}),this.thumbnail_group=t,this.store.data.thumbnail_group=t,await this.store.write()}getVideoM3U8Info(){return this.videoTranscoderResult?.m3u8}async initM3U8Data(){this.m3u8_data=this.getVideoM3U8Info()}async initThumbnailDuration(){if(this.store.data.thumbnail_duration)return this.thumbnail_duration=this.store.data.thumbnail_duration,this.thumbnail_duration;let t=30;const e=await this.getMediainfo(),a=e?.video;if(!a?.length)return t;const i=a[0],s=i.duration||e?.general?.duration,{width:r,height:o}=i;r*o>=518400&&(t=10),r*o>=921600&&(t=20),r*o>=2073600&&(t=30),r*o>=3686400&&(t=40),r*o>=8294400&&(t=60);const n=s??0;if(n&&(n<60&&(t=0),n<300&&(t=Math.ceil(t/4)),n<600&&(t=Math.ceil(t/2)),n>3600)){const e=n/3600;t=Math.ceil(t*e)}return t=Math.min(60,t),this.thumbnail_duration=t,this.store.data.thumbnail_duration=t,await this.store.write(),t}};import{resolve as se}from"path";import{pathExists as re}from"fs-extra";import{getMetadata as oe}from"@soga/imgutils";import{getFileSize as ne}from"@soga/fileutils";import{UploadProgress as he}from"@soga/node-types";import{buildDError as de}from"@soga/error";var ce=class extends ut{get cover_name(){return"audio_cover.png"}async start(){try{await this.generateCover(),this.isAudio&&await this.postProgress({type:he.transcode_thumbnail,percent:1})}catch(t){throw de(t,{message:"Error occurred during audio cover generation",detail:`Error occurred during audio cover generation: ${this.params.input.filepath}`})}}async generateCover(){const t=await this.getMediainfo();if(t.video?.length)return;const e="audio-covered";try{if(this.coverResult)return this.coverResult;if(this.db.data[e])return;const{cover_name:t}=this,a=["-i",this.params.input.filepath,"-map","0:v","-y",t];await this.ffmpeg(a,{cwd:this.params.outputRoot});const i=se(this.params.outputRoot,t),s=await re(i),r=await oe(i);if(s){const e={file:t,path:i,size:await ne(i),width:r.width??0,height:r.height??0};await this.setCoverResult(e)}}catch(t){throw t}finally{this.db.data[e]=!0,await this.db.write()}}};import{parse as le,resolve as ue}from"path";import{getFileLanguage as pe,isUtf8File as ge,saveFileAsUtf8 as me,gzip as we}from"@soga/utils";import{isValidFile as fe,getFileSize as _e,isValidPath as ye}from"@soga/fileutils";import{copy as be}from"fs-extra";import{buildDError as ve}from"@soga/error";import{UploadProgress as Pe}from"@soga/node-types";var xe=class extends ut{builtin_tracks=0;external_tracks=0;get tracks(){return this.builtin_tracks+this.external_tracks}async sendProgress(t){await this.postProgress({type:Pe.separate_subtitle,percent:t})}get dbData(){return this.db.data}async start(){try{if(this.subtitleEncoderResult)return;const t=await this.getMediainfo();if(this.builtin_tracks=t?.text?.length||0,this.external_tracks=this.params.subtitles?.length||0,!this.tracks)return await this.setSubtitleEncoderResult([]),void await this.sendProgress(1);const e=await this.parseBuiltinTextTracks();await this.sendProgress(this.builtin_tracks/this.tracks);const a=await this.parseExternalTextTracks(),i=[...e,...a];await this.setSubtitleEncoderResult(i),await this.sendProgress(1)}catch(t){throw ve(t,{message:"Error occurred while process subtitle track",detail:`Error occurred while process subtitle track: ${this.params.input.filepath}`})}}async parseBuiltinTextTracks(){const t=await this.getMediainfo(),e=t?.text;if(!e?.length)return[];const{subtitle_builtin_tracks:a}=this.dbData;if(a)return a;const i=e.length,s=[];for(let t=0;t<i;t++){const e=await this.parseBuiltinTextTrack(t);e&&s.push(e),await this.sendProgress((t+1)/this.tracks)}return this.dbData.subtitle_builtin_tracks=s,await this.params.db.write(),s}async parseBuiltinTextTrack(t){const e=this.params.outputRoot,a=`subtitle-builtin-${t}.zip`,i=ue(e,a),s=`subtitle-temp-${t}.vtt`,r=ue(e,s),o=ue(e,`subtitle-builtin-u8-${t}.vtt`),n=["-i",this.params.input.filepath,"-vn","-an","-map",`0:s:${t}`,"-c","webvtt","-y",s];await this.ffmpeg(n,{cwd:this.params.outputRoot});if(await fe(r)){if(await ge(r))await be(r,o);else{await me(r,o);await fe(o)||await be(r,o)}const e=await pe(o),{label:s,lang:n}=e;await we(o,i);return{file:a,file_path:i,size:await _e(i),lang:n,name:s||`builtin_${t+1}`,title:s||`builtin_${t+1}`,builtin:!0,source:null}}return!1}async parseExternalTextTracks(){const{subtitles:t}=this.params;if(!t?.length)return[];const{subtitle_external_tracks:e}=this.dbData;if(e)return e;const a=[],i=t.length;for(let e=0;e<i;e++){const i=await this.parseExternalTextTrack(e,t[e]);i&&a.push(i),await this.sendProgress((this.builtin_tracks+(e+1))/this.tracks)}return this.dbData.subtitle_external_tracks=a,await this.params.db.write(),a}async parseExternalTextTrack(t,e){const{ext:a}=le(e),i=this.params.outputRoot,s=`subtitle-external-${t}.vtt`,r=ue(i,s),o=`subtitle-external-${t}.zip`,n=ue(i,o),h=ue(i,`subtitle-external-u8-${t}${a}`),d=`subtitle-external-source-${t}.zip`,c=ue(i,d);if(!await ye(e))return!1;if(await ge(e))await be(e,h);else{await me(e,h);if(!await fe(h))return!1}const l=["-i",h,"-c","webvtt","-y",s];await this.ffmpeg(l,{cwd:this.params.outputRoot});if(await fe(r)){const i=await pe(r),{label:s,lang:h}=i;await we(e,c),await we(r,n);const l=await _e(c);return{file:o,size:await _e(n),file_path:n,lang:h,name:s||`external_${t+1}`,title:s||`external_${t+1}`,builtin:!1,source:{file:d,file_path:c,size:l,ext:a}}}return!1}};import{buildDError as De}from"@soga/error";import{resolve as Te}from"path";import{writeFile as ze}from"fs-extra";import{UploadProgress as Re}from"@soga/node-types";import{getFileSize as Ie}from"@soga/fileutils";import{gzip as Me,getFileBufferSlice as $e}from"@soga/utils";import{buildDError as Se}from"@soga/error";import{resolve as ke}from"path";import{getFileSize as Fe}from"@soga/fileutils";var Ee=class extends ut{hostType;safe_index=0;file_map={};completed_percent=0;total_percent=0;store;async initStore(t){this.store=await this.getStore(`${t}_grouper_store.json`)}getFileName=t=>this.getPreviewSegmentName(t,this.hostType);getGroupedVideoManifestName(t){return`grouper_video_${this.hostType}_${t}.m3u8`}getAudioManifestName(t,e){return`grouper_audio_${this.hostType}_${e}_${t}.m3u8`}getThumbnailInfoFilename(){return`grouper_thumbnail_${this.hostType}.json`}getCacheInfoFilename(){return`grouper_cache_${this.hostType}.json`}constructor(t){super(t),this.hostType=t.host_type,this.completed_percent=t.completed_percent,this.total_percent=1/t.hosts.length}async generateSafeFile(t){return await async function(t){const e=`safe_${t.type}_${t.file_index}.txt`,a=u(t.filesize),i=c(t.outputRoot,e);return await h(i,a),{file_path:i,size:a.length}}({type:t,file_index:this.safe_index++,outputRoot:this.params.outputRoot,filesize:this.params.input.filesize})}readAudioTracks(){return this.audioTranscoderResult??[]}readVideoTracks(){return this.videoTranscoderResult?[this.videoTranscoderResult]:[]}readThumbnailInfo(){return this.videoThumbnailerResult}readCoverInfo(){return this.coverResult}readSubtitleInfo(){return this.subtitleEncoderResult}async getPartData(){const t=this.store.data.grouper_part_names??[],e=[];for(let a=0;a<t.length;a++){const i=t[a],s=ke(this.params.outputRoot,i),r=await Fe(s),o=await this.getPartInfo({host_type:this.hostType,filepath:s,start:0,end:r-1,filename:i});e.push(o)}return e}async getAudioData(){const t=this.readAudioTracks();if(!t?.length)return;const e=[];for(let a=0;a<t.length;a++){const i=t[a];if(i.adapt){const{average_bandwidth:t,bandwidth:s,channels:r,codec:o,codec_name:n,language:h,order:d}=i.adapt,c=this.getAudioManifestName("adapt",a),l=this.file_map[c],{file_index:u,start:p,end:g,size:m,hash:w}=l,f=this.getFileName(u),_=await this.getPreviewId({file:c});await this.setPreviewIdMap({id:_,file:f,start:p,end:g},this.hostType);const y={id:_,average_band:t,band:s,channels:r,codec:o,codec_name:n,language:h,order:d,file:f,start:p,end:g,size:m,hash:w};if(i.high){const{average_bandwidth:t,bandwidth:e,channels:s,codec:r,codec_name:o,language:n,order:h}=i.high,d=this.getAudioManifestName("high",a),c=this.file_map[d],{file_index:l,start:u,end:p,size:g,hash:m}=c,w=this.getFileName(l),f=await this.getPreviewId({file:d});await this.setPreviewIdMap({id:f,file:w,start:u,end:p},this.hostType),y.high={id:f,average_band:t,band:e,channels:s,codec:r,codec_name:o,language:n,order:h,file:w,start:u,end:p,size:g,hash:m}}e.push(y)}}return e}async getVideoData(){const t=this.readVideoTracks();if(!t?.length)return;const e=[];for(let a=0;a<t.length;a++){const i=t[a],s=this.getGroupedVideoManifestName(a),r=await this.getPreviewId({file:s}),o=this.file_map[s],{file_index:n,start:h,end:d,size:c,hash:l}=o,u=this.getFileName(n);await this.setPreviewIdMap({id:r,file:u,start:h,end:d},this.hostType);const{average_bandwidth:p,bandwidth:g,codec:m,width:w,height:f,label:_,codec_name:y,bitdepth:b,framerate:v}=i,P={id:r,average_band:p,band:g,codec:m,codec_name:y,bitdepth:b,framerate:Math.round(v),width:w,height:f,file:u,start:h,end:d,size:c,label:_,hash:l};e.push(P)}return e}async getSubtitleData(){const t=this.readSubtitleInfo();if(!t?.length)return;const e=[],{length:a}=t;for(let i=0;i<a;i++){const a=t[i],{builtin:s,file:r,lang:o,title:n,name:h,source:d}=a,c=this.file_map[r],{file_index:l,start:u,end:p,size:g}=c,m=this.getFileName(l),w={uuid:await this.getPreviewId({file:r,start:u,end:p}),builtin:s,lang:o,name:h,title:n,file:m,start:u,end:p,size:g};if(d){const{file:t,ext:e}=d,a=this.file_map[t],{file_index:i,start:s,end:r,size:o}=a,n=this.getFileName(i);w.source={size:o,file:n,start:s,end:r,ext:e}}e.push(w)}return e}async getThumbnailData(){const t=this.readThumbnailInfo();if(!t)return;const{row:e,col:a,width:i,height:s}=t,r=this.getThumbnailInfoFilename(),o=this.file_map[r],{file_index:n,start:h,end:d,size:c}=o,l=this.getFileName(n),u=await this.getPreviewId({file:r});await this.setPreviewIdMap({id:u,file:l,start:h,end:d},this.hostType);return{id:u,row:e,col:a,width:i,height:s,file:l,start:h,end:d,size:c}}async getCoverData(){const t=this.readCoverInfo();if(!t)return;const e=t,{file:a,width:i,height:s}=e,r=this.file_map[a],{file_index:o,start:n,end:h,size:d}=r,c=this.getFileName(o),l=await this.getPreviewId({file:e.path});await this.setPreviewIdMap({id:l,file:c,start:n,end:h},this.hostType);return{id:l,width:i,height:s,file:c,start:n,end:h,size:d}}async getCacheData(){const t=this.getCacheInfoFilename(),e=await this.getPreviewId({file:t}),a=this.file_map[t],{file_index:i,start:s,end:r,size:o}=a,n=this.getFileName(i);await this.setPreviewIdMap({id:e,file:n,start:s,end:r},this.hostType);return{id:e,file:n,start:s,end:r}}async saveData(){const t=bt(this.hostType);if(this.db.data[t])return;const e={},a=await this.getAudioData();a&&(e.audios=a);const i=await this.getVideoData();i&&(e.videos=i);const s=await this.getSubtitleData();s&&(e.subtitles=s);const r=await this.getThumbnailData();r&&(e.thumbnail=r);const o=await this.getCoverData();o&&(e.cover=o),e.parts=await this.getPartData(),e.cache=await this.getCacheData(),this.db.data[t]=e,await this.db.write()}},Ne=class extends Ee{current_position=0;current_index=0;group_data=[];async start(){const t=bt(this.hostType);if(this.db.data[t])return this.db.data[t];try{return await this.initStore(this.hostType),await this.calculateData(),await this.postProgress({type:Re.group_media,percent:this.completed_percent+.5*this.total_percent}),await this.processGroups(),await this.postProgress({type:Re.group_media,percent:this.completed_percent+.9*this.total_percent}),await this.saveData(),await this.postProgress({type:Re.group_media,percent:this.completed_percent+this.total_percent}),this.db.data[t]}catch(t){throw Se(t,{message:`Error occurred during media grouping ${this.hostType}`,detail:`Error occurred during media grouping ${this.hostType}: ${this.params.input.filepath}`})}}async processGroups(){const t="grouper_process_state";if(this.store.data[t])return;this.store.data.grouper_process_map||={},this.store.data.grouper_process_index||=0;const{length:e}=this.group_data;for(let t=0;t<e;t++){const a=this.group_data[t];this.store.data.grouper_process_map[a.filename]||(await p({outputRoot:this.params.outputRoot,files:a.files,filename:a.filename}),this.store.data.grouper_process_map[a.filename]=!0,await this.store.write(),await this.postProgress({type:Re.group_media,percent:this.completed_percent+.5*this.total_percent+this.total_percent*(.4*(t+1)/e)}))}this.store.data[t]=!0,await this.store.write()}async insertSafeFile(){const t=await this.generateSafeFile(this.hostType);this.addOne(t,!0)}async calculateData(){this.store.data.grouper_group_list||=[],this.store.data.grouper_file_map||={},await this.insertSafeFile(),await this.calculateMediaTracks(),await this.calculateThumbnails(),await this.calculateCovers(),await this.calculateCaches(),this.current_index+=1,this.current_position=0,await this.calculateSubtitles(),this.store.data.grouper_group_list=this.group_data,this.store.data.grouper_file_map=this.file_map;const t=this.group_data.map(t=>t.filename);this.store.data.grouper_part_names=t,this.store.data.grouper_calculate_state=!0,await this.store.write()}async calculateSubtitles(){const t=this.readSubtitleInfo();if(!t?.length)return;await this.insertSafeFile();const{length:e}=t;for(let a=0;a<e;a++){const e=t[a],{file:i,file_path:s,size:r}=e,o=this.addOne({file_path:s,size:r});if(this.file_map[i]=o,e.source){const{file:t,file_path:a,size:i}=e.source,s=this.addOne({file_path:a,size:i});this.file_map[t]=s}}}async calculateCaches(){await this.getAudioData(),await this.getVideoData(),await this.getThumbnailData(),await this.getCoverData();const t=this.getPreviewIdMap(this.hostType),e=this.getCacheInfoFilename(),a=await this.writeText(e,JSON.stringify(t));this.file_map[e]=a}async calculateCovers(){const t=this.readCoverInfo();if(!t)return;const{file:e,path:a,size:i}=t,s=this.addOne({file_path:a,size:i});this.file_map[e]=s}async calculateMediaTracks(){const t=this.readAudioTracks(),e=this.readVideoTracks(),a=t?.length;for(let e=0;e<a;e++){const i=t[e];if(i.adapt){const t=await this.calculateOneTrack(i.adapt.m3u8),a=this.getAudioManifestName("adapt",e),s=await this.writeTrackText(a,t);this.file_map[a]=s}if(i.high){const t=await this.calculateOneTrack(i.high.m3u8),a=this.getAudioManifestName("high",e),s=await this.writeTrackText(a,t);this.file_map[a]=s}await this.postProgress({type:Re.group_media,percent:this.completed_percent+.4*this.total_percent*((e+1)/a)})}const i=e.length;for(let t=0;t<i;t++){const a=e[t],s=await this.calculateOneTrack(a.m3u8),r=this.getGroupedVideoManifestName(t),o=await this.writeTrackText(r,s);this.file_map[r]=o,await this.postProgress({type:Re.group_media,percent:this.completed_percent+.2*this.total_percent+.2*this.total_percent*((t+1)/i)})}}async calculateThumbnails(){const t=this.readThumbnailInfo();if(!t)return;if(!t)return;const{tile_list:e}=t,{length:a}=e;let i=[...t.sprite_list];for(let t=0;t<a;t++){const a=e[t],s=a.file,r=await this.safelyAddOne({file_path:a.file_path,size:a.size}),o=await this.getPreviewId({file:s}),n=this.getFileName(r.file_index);await this.setPreviewIdMap({id:o,file:n,start:r.start,end:r.end},this.hostType),this.file_map[s]=r,i=i.map(t=>t.file===s?{...t,file:n,id:o,s:r.start,e:r.end}:t)}const s=this.getThumbnailInfoFilename(),r=await this.writeText(s,JSON.stringify(i));this.file_map[s]=r}async calculateOneTrack(t){const{segments:e,init:a,version:i,targetDuration:s,mediaSequence:r,endList:o}=t,n={},h=this.addOne({size:a.size,file_path:a.file_path}),d=await this.getPreviewId({file:a.uri}),c=this.getFileName(h.file_index),l=`${c}?id=${d}`;await this.setPreviewIdMap({id:d,file:c,start:h.start,end:h.end},this.hostType);const u=["#EXTM3U",`#EXT-X-VERSION:${i}`,`#EXT-X-TARGETDURATION:${s}`,`#EXT-X-MEDIA-SEQUENCE:${r}`,`#EXT-X-MAP:URI=${l},BYTERANGE="${h.size}@${h.start}"`];[...e].forEach(t=>{const{uri:e,size:a,duration:i,file_path:s}=t;n[e]=this.addOne({size:a,duration:i,file_path:s})});for(const[t,e]of Object.entries(n)){const a=await this.getPreviewId({file:t}),i=this.getFileName(e.file_index);await this.setPreviewIdMap({id:a,file:i,start:e.start,end:e.end},this.hostType),u.push(`#EXTINF:${e.duration},`),u.push(`#EXT-X-BYTERANGE:${e.size}@${e.start}`),u.push(`${i}?id=${a}`)}o&&u.push("#EXT-X-ENDLIST");return u.join("\n")}async writeTrackText(t,e){const a=Te(this.params.outputRoot,t),r=Te(this.params.outputRoot,`${t}.gz`),o=Te(this.params.outputRoot,`${t}.bin`);await ze(a,e,"utf-8"),await Me(a,r);if(await Ie(r)>16){const t=(await $e(r,0,15)).toString("base64");await async function(t,e){await new Promise((a,r)=>{const o=i(t,{start:16}),n=s(e);o.pipe(n),n.on("finish",()=>{a(!0)}),o.on("error",t=>{r(t)}),n.on("error",t=>{r(t)})})}(r,o);return{...this.addOne({file_path:o,size:await Ie(o)}),hash:t}}return{...this.addOne({file_path:a,size:await Ie(a)}),hash:""}}async writeText(t,e){const a=Te(this.params.outputRoot,t);await ze(a,e,"utf-8");return this.addOne({file_path:a,size:await Ie(a)})}addOne({file_path:t,size:e,duration:a=0},i=!1){const s=this.getSizeLimit(this.hostType),{current_position:r,group_data:o}=this;if(i&&o[this.current_index]||!(r+e<=s)){this.current_index+=1;const{current_index:i}=this;o[i]?o[i].files.push(t):o[i]={filename:this.getFileName(i),files:[t]};const s=0,r=e-1;return this.current_position=e,{file_index:i,start:s,end:r,duration:a,size:r-s+1}}{const{current_index:i}=this,s=r,n=r+e-1;return this.current_position=n+1,o[i]?o[i].files.push(t):o[i]={filename:this.getFileName(i),files:[t]},{file_index:i,start:s,end:n,duration:a,size:n-s+1}}}async safelyAddOne(t){const e=this.getSizeLimit(this.hostType),{current_position:a}=this;return a+t.size<=e?0===a?(await this.insertSafeFile(),this.addOne(t)):this.addOne(t):(await this.insertSafeFile(),this.addOne(t))}},Ce=class extends ut{async start(){try{if(this.grouperResult)return this.grouperResult;const t={meta:await this.getMetaData(),data:{}},{length:e}=this.params.hosts;for(let a=0;a<e;a++){const i=this.params.hosts[a],s=this.getSizeLimit(i),r=new Ne({...this.params,host_type:i,file_size_limit:s,completed_percent:a/e}),o=await r.start();t.data[i]=o}return await this.setGrouperResult(t),t}catch(t){throw De(t,{message:t.message||"Error occurred during media grouping",detail:t.detail||`Error occurred during media grouping: ${this.params.input.filepath}`})}}async getMetaData(){const t={},e=this.audioTranscoderResult??[],a=this.videoTranscoderResult?[this.videoTranscoderResult]:[];if(a?.length){const e=await this.getMediainfo(),{duration:i}=e?.general;if(a?.length){const{width:e,height:s,framerate:r,bitdepth:o,label:n,codec:h,codec_name:d}=a[0];t.videos=[{duration:i,bitdepth:o,width:e,height:s,framerate:r,label:n,codec:h,codec_name:d}]}}if(e?.length)for(const a of e){const{high:e,adapt:i}=a,{channels:s,lossless:r}=i,o=await this.getMediainfo(),{duration:n}=o?.general,{codec:h,codec_name:d}=i,c={duration:n,channels:s,lossless:r,codec:h,codec_name:d};e&&(c.high={channels:e.channels,codec:e.codec,codec_name:e.codec_name,lossless:e.lossless}),t.audios=t.audios||[],t.audios.push(c)}return t}},Le=class extends ut{async start(){if(this.db.data.grouper_result)return this.db.data.grouper_result;const t=await this.getMediainfo();if(!t)return;const e=t.video,a=e?.length,i=t.audio,s=i?.length;if(!s&&!a)return;const r=new xe(this.params);if(await r.start(),s){const t=new $t(this.params);await t.start();const e=new Qt(this.params);await e.start();const a=new ce(this.params);await a.start()}if(a){const t=new xt(this.params);await t.start();const e=new Ut(this.params);await e.start();const a=new ie(this.params);await a.start()}const o=new Ce(this.params);await o.start()}async getResult(){return this.db.data.grouper_result}};import{HostType as Ae}from"@soga/types";import{UploadProgress as Oe}from"@soga/node-types";import{parseMediaInfo as Ue}from"@soga/mediainfo";import{getFileSize as Ve,isAudioAdapt as Ge,isAudioHigh as Be,isVideoSupport as je}from"@soga/fileutils";import{ensureDir as qe}from"fs-extra";import Xe from"check-disk-space";import{buildDError as Ke}from"@soga/error";var Je=class extends C{async start(){this.prepareResult||(await this.checkStorage(),await this.calculateMeta(),await this.calculateProgress())}async checkStorage(){const{length:t}=this.params.hosts,e=await Xe(this.params.outputRoot),a=e.free,i=e.diskPath;if((3+t)*this.params.input.filesize>a)throw Ke(new Error(`${i} have no enough computer disk space, please adjust the temporary path in user settings.`),{message:`${i} have no enough computer disk space, please adjust the temporary path in user settings.`,detail:`${i} have no enough computer disk space to process ${this.params.input.filepath}`})}async calculateMeta(){if(this.meta)return this.meta;const{filename:t,local_btime:e,local_ctime:a,local_mtime:i,filesize:s}=this.params.input,r={file:t,size:s,btime:e,ctime:a,mtime:i,md5:""};return await this.setMeta(r),r}async calculateProgress(){if(this.prepareResult)return;const t={[Oe.prepare]:{weight:0,percent:1},[Oe.calculate_md5]:{weight:0,percent:0},[Oe.separate_video]:{weight:0,percent:0},[Oe.separate_audio]:{weight:0,percent:0},[Oe.separate_subtitle]:{weight:0,percent:0},[Oe.transcode_video]:{weight:0,percent:0},[Oe.transcode_audio]:{weight:0,percent:0},[Oe.transcode_thumbnail]:{weight:0,percent:0},[Oe.transcode_source]:{weight:0,percent:0},[Oe.transcode_txt]:{weight:0,percent:0},[Oe.transcode_img]:{weight:0,percent:0},[Oe.group_media]:{weight:0,percent:0},[Oe.upload_baidu]:{weight:0,percent:0},[Oe.upload_ali]:{weight:0,percent:0},[Oe.end]:{weight:0,percent:0}},e={keep_preview:this.params.keepPreview,keep_source:this.params.keepSource},a=await Ve(this.params.input.filepath);t[Oe.prepare].weight=t[Oe.end].weight=Math.ceil(a/1024/1024/500),t[Oe.calculate_md5].weight=Math.ceil(a/1024/1024/200);let i=0;if(this.isMedia)if(this.params.keepPreview){const s=await Ue(this.params.input.filepath),r=s?.general?.duration??0;if(s.video?.length){const e=s.video[0],{width:a,height:i,codec:r}=e,o=je(r),{duration:n}=s.general,h=o?n/400:n*(a*i)/1920/1080;t[Oe.separate_video].weight=Math.ceil(h),t[Oe.transcode_video].weight=Math.ceil(.01*n)}if(s.audio?.length){const{duration:e}=s.general;let a=0;s.audio.forEach(t=>{const{codec:i,lossless:s,channels:r}=t,o={high_need:!1,high_transcode:!1,adapt_need:!1,adapt_transcode:!1};Ge(i)?r>2?(o.high_need=!0,o.high_transcode=!1,o.adapt_need=!0,o.adapt_transcode=!0):(o.high_need=!1,o.adapt_need=!0,o.adapt_transcode=!1):Be(i)?(o.high_need=!0,o.high_transcode=!1,o.adapt_need=!0,o.adapt_transcode=!0):(o.high_need=!1,o.adapt_need=!0,o.adapt_transcode=!1,s&&(o.high_need=!0,o.high_transcode=!0)),o.adapt_need&&(a+=o.adapt_transcode?e/40:5),o.high_need&&(a+=o.high_transcode?e/20:10)}),t[Oe.separate_audio].weight=Math.ceil(a),t[Oe.transcode_audio].weight=Math.ceil(.01*e)}const o=s.video?.length??0,n=s.audio?.length??0;if(o||n){e.keep_preview=!0;const o=(s.text?.length||0)+(this.params.subtitles?.length||0);t[Oe.separate_subtitle].weight=Math.ceil(o),t[Oe.transcode_thumbnail].weight=Math.ceil(.08*r),i+=a,t[Oe.group_media].weight=Math.ceil(a/1024/1024/10)}else e.keep_preview=!1,e.keep_source=!0,i+=a}else e.keep_source=!0,i+=a;else this.isTxt?e.keep_preview?(t[Oe.transcode_txt].weight=Math.ceil(a/1024/1024/1),i+=a):(e.keep_source=!0,i+=a):this.isImg?e.keep_preview&&(t[Oe.transcode_img].weight=Math.ceil(a/1024/1024/1),i+=a):(e.keep_source=!0,i+=a);e.keep_source&&(t[Oe.transcode_source].weight=Math.ceil(a/1024/1024/30)),this.params.hosts.includes(Ae.BAIDU)&&(t[Oe.upload_baidu].weight=Math.ceil(i/1024/1024/1)),this.params.hosts.includes(Ae.ALI)&&(t[Oe.upload_ali].weight=Math.ceil(i/1024/1024/2));const s={preview:e.keep_preview,source:e.keep_source};await this.setKeeps(s),await this.setPrepareResult(t)}},He=async t=>{await qe(t.outputRoot);const e=await m(t);try{const a=new Je({...t,db:e});return await a.start(),a}catch(t){}};import{UploadProgress as Qe}from"@soga/node-types";import{createHash as We}from"crypto";import{createReadStream as Ze}from"fs-extra";var Ye=class extends C{async start(){await this.processFile();return await this.getResult()}async calculateMd5(){if(this.md5)return this.md5;const t=this.params.input.filepath,e=this.params.input.filesize;let a=0;const i=await new Promise((i,s)=>{let r=0;const o=We("md5"),n=Ze(t,{highWaterMark:4194304});n.on("data",async t=>{o.update(t),r+=t.length;const i=r/e;r-a>104857600&&(a=r,await this.postProgress({type:Qe.calculate_md5,percent:Math.min(i,1)}))}),n.on("end",()=>{const t=o.digest("hex");i(t)}),n.on("error",t=>{s(t)})});return i&&await this.setMd5(i),await this.postProgress({type:Qe.calculate_md5,percent:1}),i}async getResult(){if(this.result)return this.result;const{sourceResult:t,grouperResult:e,imgResult:a,txtResult:i,meta:s,keeps:r}=this,{length:o}=this.params.hosts,n={meta:{preview:r.preview,source:r.source,file:s}};for(let s=0;s<o;s++){const r=this.params.hosts[s];n[r]={max_size:0,parts:[]};const o=t=>{n[r].parts=[...n[r].parts,...t]},h=a?.data[r];if(h){h.cache&&(n[r].cache=h?.cache);const t=h.parts?.map(t=>({...t,preview:!0,source:!1}));t&&o(t),n.meta.img=a.meta,h.img&&(n[r].img=h.img)}const d=i?.data[r];if(d){o((d.parts||[]).map(t=>({...t,preview:!0,source:!1}))),n[r].cache=d.cache,n[r].txt={entrance:d.entrance,pad:i?.meta.pad,pages:i?.meta.pages}}const c=e?.data[r];if(c?.parts){o(c.parts.map(t=>({...t,preview:!0,source:!1}))),n.meta.audios=e.meta.audios,n.meta.videos=e.meta.videos,n[r].cache=c.cache,n[r].media={audios:c.audios,videos:c.videos,subtitles:c.subtitles,thumbnail:c.thumbnail,cover:c.cover}}const l=t?.data[r];if(l?.parts){o(l.parts.map(t=>{let e=!0;return(this.isMedia||this.isTxt)&&(e=!1),{...t,preview:e,source:!0}})),n[r].source={head:t.meta.head,download:l.download}}[...n[r]?.parts].forEach(t=>{t.size>n[r].max_size&&(n[r].max_size=t.size)})}return await this.setResult(n),n}async processFile(){const t="encoder_processed";if(this.db.data[t])return;const e=await He(this.params),{keeps:a}=e,i={...this.params,keepPreview:a.preview,keepSource:a.source},s=await this.calculateMd5();if(await this.setMd5(s),i.keepSource){const t=new A(this.params);await t.start()}if(e.isMedia&&i.keepPreview){const t=new Le(this.params);await t.start()}if(e.isTxt&&i.keepPreview){const t=new Y(this.params);await t.start()}if(e.isImg){const t=new ht(this.params);await t.start()}this.db.data[t]=!0,await this.db.write()}},ta=async e=>{try{const t=await m(e),a=new Ye({...e,db:t});return a.start()}catch(a){throw t(a,{message:"Error occurred during file encoding",detail:`Error occurred during file encoding: ${e.input.filepath}`})}};export{ta as encode,He as getPrepare};
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@soga/file-encoder",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "",
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"module": "./dist/index.mjs",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"demo": "tsx ./demo/demo",
|
|
16
|
+
"build": "rimraf dist && tsup src/index.ts --format cjs,esm --dts --minify terser",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@soga/typescript-config": "latest",
|
|
21
|
+
"@types/fluent-ffmpeg": "^2.1.27",
|
|
22
|
+
"@types/langdetect": "^0.2.2",
|
|
23
|
+
"@types/fs-extra": "^11.0.4",
|
|
24
|
+
"rimraf": "^6.0.1",
|
|
25
|
+
"terser": "^5.43.1",
|
|
26
|
+
"tsup": "^8.5.0",
|
|
27
|
+
"tsx": "^4.20.6",
|
|
28
|
+
"typescript": "^5.8.3"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [],
|
|
31
|
+
"author": "",
|
|
32
|
+
"license": "ISC",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@soga/fileutils": "latest",
|
|
35
|
+
"@soga/utils": "latest",
|
|
36
|
+
"@soga/types": "latest",
|
|
37
|
+
"@soga/node-types": "latest",
|
|
38
|
+
"@soga/error": "latest",
|
|
39
|
+
"@soga/lowdb": "latest",
|
|
40
|
+
"@soga/m3u8": "latest",
|
|
41
|
+
"@soga/mediainfo": "latest",
|
|
42
|
+
"@soga/mp4box": "latest",
|
|
43
|
+
"@soga/imgutils": "latest",
|
|
44
|
+
"fluent-ffmpeg": "^2.1.3",
|
|
45
|
+
"fs-extra": "^11.3.2",
|
|
46
|
+
"lowdb": "^7.0.1",
|
|
47
|
+
"piscina": "^5.0.0",
|
|
48
|
+
"uuid": "^11.1.0",
|
|
49
|
+
"check-disk-space": "^3.4.0"
|
|
50
|
+
}
|
|
51
|
+
}
|