@soga/mediainfo 0.4.0 → 0.5.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.
@@ -0,0 +1,61 @@
1
+ declare function parseMediaRaw(media_path: string): Promise<any>;
2
+ declare function parseMediaInfo(media_path: string): Promise<{
3
+ audio: AudioTrackInfo[];
4
+ video: VideoTrackInfo[];
5
+ text: TextTrackInfo[];
6
+ general: GeneralInfo;
7
+ }>;
8
+ type GeneralInfo = {
9
+ audioCount: number;
10
+ videoCount: number;
11
+ textCount: number;
12
+ fileSize: number;
13
+ codec: string;
14
+ title: string;
15
+ duration: number;
16
+ extra?: {
17
+ duration: string;
18
+ };
19
+ };
20
+ type AudioTrackInfo = {
21
+ is_default: boolean;
22
+ order: number;
23
+ codec: string;
24
+ bitrate: number;
25
+ framerate: number;
26
+ sample_rate: number;
27
+ channels: number;
28
+ duration: number;
29
+ lossless: boolean;
30
+ };
31
+ type VideoTrackInfo = {
32
+ is_default: boolean;
33
+ order: number;
34
+ width: number;
35
+ height: number;
36
+ codec: string;
37
+ profile: string;
38
+ framerate: number;
39
+ bitrate: number;
40
+ duration: number;
41
+ bitdepth: number;
42
+ format_profile: string;
43
+ format_tier: string;
44
+ };
45
+ type TextTrackInfo = {
46
+ is_default: boolean;
47
+ codec: string;
48
+ order: number;
49
+ duration: number;
50
+ language?: string;
51
+ title?: string;
52
+ is_vtt?: boolean;
53
+ };
54
+ type Mediainfo = {
55
+ general?: GeneralInfo;
56
+ audio?: AudioTrackInfo[];
57
+ video?: VideoTrackInfo[];
58
+ text?: TextTrackInfo[];
59
+ };
60
+
61
+ export { type AudioTrackInfo, type GeneralInfo, type Mediainfo, type TextTrackInfo, type VideoTrackInfo, parseMediaInfo, parseMediaRaw };
@@ -0,0 +1,61 @@
1
+ declare function parseMediaRaw(media_path: string): Promise<any>;
2
+ declare function parseMediaInfo(media_path: string): Promise<{
3
+ audio: AudioTrackInfo[];
4
+ video: VideoTrackInfo[];
5
+ text: TextTrackInfo[];
6
+ general: GeneralInfo;
7
+ }>;
8
+ type GeneralInfo = {
9
+ audioCount: number;
10
+ videoCount: number;
11
+ textCount: number;
12
+ fileSize: number;
13
+ codec: string;
14
+ title: string;
15
+ duration: number;
16
+ extra?: {
17
+ duration: string;
18
+ };
19
+ };
20
+ type AudioTrackInfo = {
21
+ is_default: boolean;
22
+ order: number;
23
+ codec: string;
24
+ bitrate: number;
25
+ framerate: number;
26
+ sample_rate: number;
27
+ channels: number;
28
+ duration: number;
29
+ lossless: boolean;
30
+ };
31
+ type VideoTrackInfo = {
32
+ is_default: boolean;
33
+ order: number;
34
+ width: number;
35
+ height: number;
36
+ codec: string;
37
+ profile: string;
38
+ framerate: number;
39
+ bitrate: number;
40
+ duration: number;
41
+ bitdepth: number;
42
+ format_profile: string;
43
+ format_tier: string;
44
+ };
45
+ type TextTrackInfo = {
46
+ is_default: boolean;
47
+ codec: string;
48
+ order: number;
49
+ duration: number;
50
+ language?: string;
51
+ title?: string;
52
+ is_vtt?: boolean;
53
+ };
54
+ type Mediainfo = {
55
+ general?: GeneralInfo;
56
+ audio?: AudioTrackInfo[];
57
+ video?: VideoTrackInfo[];
58
+ text?: TextTrackInfo[];
59
+ };
60
+
61
+ export { type AudioTrackInfo, type GeneralInfo, type Mediainfo, type TextTrackInfo, type VideoTrackInfo, parseMediaInfo, parseMediaRaw };
package/dist/index.js ADDED
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ parseMediaInfo: () => parseMediaInfo,
34
+ parseMediaRaw: () => parseMediaRaw
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+ var import_fs_extra = require("fs-extra");
38
+ var import_promises = require("fs/promises");
39
+ var import_mediainfo = __toESM(require("mediainfo.js"));
40
+ async function parseMediaRaw(media_path) {
41
+ const mediainfo = await (0, import_mediainfo.default)({
42
+ format: "JSON"
43
+ });
44
+ const fileList = typeof media_path === "string" ? [media_path] : media_path;
45
+ let total = 0;
46
+ const arr = [];
47
+ for await (const [index, file_path] of fileList.entries()) {
48
+ const { size } = await (0, import_promises.stat)(file_path);
49
+ arr.push({
50
+ index,
51
+ start: total,
52
+ end: total + size - 1,
53
+ size,
54
+ file_path
55
+ });
56
+ total += size;
57
+ }
58
+ const getBuffer = async (size, offset) => {
59
+ if (!size) {
60
+ return new Uint8Array(0);
61
+ }
62
+ const start = offset;
63
+ const end = offset + size - 1;
64
+ const first = arr.find((item) => item.start <= start && item.end >= start);
65
+ const last = arr.find((item) => item.start <= end && item.end >= end);
66
+ if (!first || !last) {
67
+ return new Uint8Array(0);
68
+ }
69
+ const list = [];
70
+ if (first.index === last.index) {
71
+ list.push({
72
+ index: first.index,
73
+ file_path: first.file_path,
74
+ from: start - first.start,
75
+ to: end - first.start
76
+ });
77
+ } else {
78
+ list.push({
79
+ index: first.index,
80
+ file_path: first.file_path,
81
+ from: start - first.start,
82
+ to: first.end
83
+ });
84
+ for (let i = first.index + 1; i < last.index; i++) {
85
+ const item = arr[i];
86
+ if (item) {
87
+ list.push({
88
+ index: item.index,
89
+ file_path: item.file_path,
90
+ from: 0,
91
+ to: item.size - 1
92
+ });
93
+ }
94
+ }
95
+ list.push({
96
+ index: last.index,
97
+ file_path: last.file_path,
98
+ from: 0,
99
+ to: end - last.start
100
+ });
101
+ }
102
+ const buffers = [];
103
+ for await (const item of list) {
104
+ const { file_path, from, to } = item;
105
+ const stream = (0, import_fs_extra.createReadStream)(file_path, { start: from, end: to });
106
+ for await (const data2 of stream) {
107
+ buffers.push(data2);
108
+ }
109
+ stream.close();
110
+ }
111
+ const buffer = Buffer.concat(buffers);
112
+ return buffer;
113
+ };
114
+ const data = await mediainfo.analyzeData(() => total, getBuffer);
115
+ try {
116
+ const rawJson = JSON.parse(data);
117
+ return rawJson;
118
+ } catch (err) {
119
+ const text = data.replace(',"":{}]}]}', ',"":{}}]}');
120
+ const rawJson = JSON.parse(text);
121
+ return rawJson;
122
+ }
123
+ }
124
+ async function parseMediaInfo(media_path) {
125
+ const raw = await parseMediaRaw(media_path);
126
+ const rawMediainfo = raw.media;
127
+ const list = rawMediainfo.track;
128
+ const info = {
129
+ audio: [],
130
+ video: [],
131
+ text: [],
132
+ general: {}
133
+ };
134
+ let audioOrder = 0;
135
+ let videoOrder = 0;
136
+ let textOrder = 0;
137
+ list.forEach((item) => {
138
+ const type = item["@type"];
139
+ if (type === "Audio") {
140
+ info.audio.push({
141
+ is_default: item.Default === "Yes",
142
+ codec: item.Format.toLowerCase(),
143
+ // order: Number(item.StreamOrder),
144
+ order: audioOrder++,
145
+ // size: Number(item.StreamSize),
146
+ bitrate: Number(item.BitRate),
147
+ framerate: Number(item.FrameRate),
148
+ sample_rate: Number(item.SamplingRate),
149
+ duration: Number(item.Duration),
150
+ channels: Number(item.Channels),
151
+ lossless: item.Compression_Mode === "Lossless"
152
+ });
153
+ } else if (type === "Text") {
154
+ info.text.push({
155
+ is_default: item.Default === "Yes",
156
+ codec: item.Format.toLowerCase(),
157
+ // order: Number(item.StreamOrder),
158
+ order: textOrder++,
159
+ duration: Number(item.Duration),
160
+ title: item.Title || item.Language,
161
+ language: item.Language
162
+ });
163
+ } else if (type === "Video") {
164
+ info.video.push({
165
+ is_default: item.Default === "Yes",
166
+ codec: item.Format.toLowerCase(),
167
+ order: videoOrder++,
168
+ width: Number(item.Width),
169
+ height: Number(item.Height),
170
+ profile: item.Format_Profile,
171
+ bitrate: Number(item.BitRate),
172
+ framerate: Number(item.FrameRate) ? Math.round(Number(item.FrameRate)) : 0,
173
+ // sample_rate: Number(item.SamplingRate),
174
+ duration: Number(item.Duration),
175
+ bitdepth: Number(item.BitDepth),
176
+ format_profile: item.Format_Profile,
177
+ format_tier: item.Format_Tier
178
+ });
179
+ } else if (type === "General") {
180
+ info.general = {
181
+ audioCount: Number(item.AudioCount),
182
+ textCount: Number(item.TextCount) || 0,
183
+ videoCount: Number(item.VideoCount),
184
+ fileSize: Number(item.FileSize),
185
+ title: item.Title || "",
186
+ duration: Number(item.Duration),
187
+ codec: item.Format
188
+ };
189
+ if (!info.general.duration && item.extra?.duration) {
190
+ info.general.duration = Number(item.extra.duration);
191
+ }
192
+ }
193
+ });
194
+ return info;
195
+ }
196
+ // Annotate the CommonJS export names for ESM import in node:
197
+ 0 && (module.exports = {
198
+ parseMediaInfo,
199
+ parseMediaRaw
200
+ });
@@ -1,20 +1,14 @@
1
+ // src/index.ts
1
2
  import { createReadStream } from "fs-extra";
2
3
  import { stat } from "fs/promises";
3
- import getMediainfo, { FormatType, MediaInfo } from "mediainfo.js";
4
-
5
- export async function parseMediaRaw(media_path: string) {
6
- const mediainfo: MediaInfo<FormatType> = await getMediainfo({
7
- format: "JSON" as FormatType,
4
+ import getMediainfo from "mediainfo.js";
5
+ async function parseMediaRaw(media_path) {
6
+ const mediainfo = await getMediainfo({
7
+ format: "JSON"
8
8
  });
9
9
  const fileList = typeof media_path === "string" ? [media_path] : media_path;
10
10
  let total = 0;
11
- const arr = [] as {
12
- index: number;
13
- start: number;
14
- end: number;
15
- size: number;
16
- file_path: string;
17
- }[];
11
+ const arr = [];
18
12
  for await (const [index, file_path] of fileList.entries()) {
19
13
  const { size } = await stat(file_path);
20
14
  arr.push({
@@ -22,12 +16,11 @@ export async function parseMediaRaw(media_path: string) {
22
16
  start: total,
23
17
  end: total + size - 1,
24
18
  size,
25
- file_path,
19
+ file_path
26
20
  });
27
21
  total += size;
28
22
  }
29
-
30
- const getBuffer = async (size: number, offset: number) => {
23
+ const getBuffer = async (size, offset) => {
31
24
  if (!size) {
32
25
  return new Uint8Array(0);
33
26
  }
@@ -38,26 +31,20 @@ export async function parseMediaRaw(media_path: string) {
38
31
  if (!first || !last) {
39
32
  return new Uint8Array(0);
40
33
  }
41
-
42
- const list = [] as {
43
- index: number;
44
- file_path: string;
45
- from: number;
46
- to: number;
47
- }[];
34
+ const list = [];
48
35
  if (first.index === last.index) {
49
36
  list.push({
50
37
  index: first.index,
51
38
  file_path: first.file_path,
52
39
  from: start - first.start,
53
- to: end - first.start,
40
+ to: end - first.start
54
41
  });
55
42
  } else {
56
43
  list.push({
57
44
  index: first.index,
58
45
  file_path: first.file_path,
59
46
  from: start - first.start,
60
- to: first.end,
47
+ to: first.end
61
48
  });
62
49
  for (let i = first.index + 1; i < last.index; i++) {
63
50
  const item = arr[i];
@@ -66,7 +53,7 @@ export async function parseMediaRaw(media_path: string) {
66
53
  index: item.index,
67
54
  file_path: item.file_path,
68
55
  from: 0,
69
- to: item.size - 1,
56
+ to: item.size - 1
70
57
  });
71
58
  }
72
59
  }
@@ -74,15 +61,15 @@ export async function parseMediaRaw(media_path: string) {
74
61
  index: last.index,
75
62
  file_path: last.file_path,
76
63
  from: 0,
77
- to: end - last.start,
64
+ to: end - last.start
78
65
  });
79
66
  }
80
- const buffers = [] as Buffer[];
67
+ const buffers = [];
81
68
  for await (const item of list) {
82
69
  const { file_path, from, to } = item;
83
70
  const stream = createReadStream(file_path, { start: from, end: to });
84
- for await (const data of stream) {
85
- buffers.push(data);
71
+ for await (const data2 of stream) {
72
+ buffers.push(data2);
86
73
  }
87
74
  stream.close();
88
75
  }
@@ -90,35 +77,29 @@ export async function parseMediaRaw(media_path: string) {
90
77
  return buffer;
91
78
  };
92
79
  const data = await mediainfo.analyzeData(() => total, getBuffer);
93
-
94
80
  try {
95
- const rawJson = JSON.parse(data as string);
81
+ const rawJson = JSON.parse(data);
96
82
  return rawJson;
97
83
  } catch (err) {
98
- // const text = (data as string).replace(
99
- // '"Menu","":{}]}]}',
100
- // '"Menu","":{}}]}',
101
- // );
102
- const text = (data as string).replace(',"":{}]}]}', ',"":{}}]}');
84
+ const text = data.replace(',"":{}]}]}', ',"":{}}]}');
103
85
  const rawJson = JSON.parse(text);
104
86
  return rawJson;
105
87
  }
106
88
  }
107
-
108
- export async function parseMediaInfo(media_path: string) {
89
+ async function parseMediaInfo(media_path) {
109
90
  const raw = await parseMediaRaw(media_path);
110
91
  const rawMediainfo = raw.media;
111
92
  const list = rawMediainfo.track;
112
93
  const info = {
113
- audio: [] as AudioTrackInfo[],
114
- video: [] as VideoTrackInfo[],
115
- text: [] as TextTrackInfo[],
116
- general: {} as GeneralInfo,
94
+ audio: [],
95
+ video: [],
96
+ text: [],
97
+ general: {}
117
98
  };
118
99
  let audioOrder = 0;
119
100
  let videoOrder = 0;
120
101
  let textOrder = 0;
121
- list.forEach((item: any) => {
102
+ list.forEach((item) => {
122
103
  const type = item["@type"];
123
104
  if (type === "Audio") {
124
105
  info.audio.push({
@@ -132,7 +113,7 @@ export async function parseMediaInfo(media_path: string) {
132
113
  sample_rate: Number(item.SamplingRate),
133
114
  duration: Number(item.Duration),
134
115
  channels: Number(item.Channels),
135
- lossless: item.Compression_Mode === "Lossless",
116
+ lossless: item.Compression_Mode === "Lossless"
136
117
  });
137
118
  } else if (type === "Text") {
138
119
  info.text.push({
@@ -142,7 +123,7 @@ export async function parseMediaInfo(media_path: string) {
142
123
  order: textOrder++,
143
124
  duration: Number(item.Duration),
144
125
  title: item.Title || item.Language,
145
- language: item.Language,
126
+ language: item.Language
146
127
  });
147
128
  } else if (type === "Video") {
148
129
  info.video.push({
@@ -153,14 +134,12 @@ export async function parseMediaInfo(media_path: string) {
153
134
  height: Number(item.Height),
154
135
  profile: item.Format_Profile,
155
136
  bitrate: Number(item.BitRate),
156
- framerate: Number(item.FrameRate)
157
- ? Math.round(Number(item.FrameRate))
158
- : 0,
137
+ framerate: Number(item.FrameRate) ? Math.round(Number(item.FrameRate)) : 0,
159
138
  // sample_rate: Number(item.SamplingRate),
160
139
  duration: Number(item.Duration),
161
140
  bitdepth: Number(item.BitDepth),
162
141
  format_profile: item.Format_Profile,
163
- format_tier: item.Format_Tier,
142
+ format_tier: item.Format_Tier
164
143
  });
165
144
  } else if (type === "General") {
166
145
  info.general = {
@@ -170,69 +149,16 @@ export async function parseMediaInfo(media_path: string) {
170
149
  fileSize: Number(item.FileSize),
171
150
  title: item.Title || "",
172
151
  duration: Number(item.Duration),
173
- codec: item.Format,
152
+ codec: item.Format
174
153
  };
175
154
  if (!info.general.duration && item.extra?.duration) {
176
155
  info.general.duration = Number(item.extra.duration);
177
156
  }
178
157
  }
179
158
  });
180
-
181
159
  return info;
182
160
  }
183
-
184
- export type GeneralInfo = {
185
- audioCount: number;
186
- videoCount: number;
187
- textCount: number;
188
- fileSize: number;
189
- codec: string;
190
- title: string;
191
- duration: number;
192
- extra?: {
193
- duration: string;
194
- };
195
- };
196
- export type AudioTrackInfo = {
197
- is_default: boolean;
198
- order: number;
199
- codec: string;
200
- bitrate: number;
201
- framerate: number;
202
- sample_rate: number;
203
- channels: number;
204
- duration: number;
205
- lossless: boolean;
206
- };
207
-
208
- export type VideoTrackInfo = {
209
- is_default: boolean;
210
- order: number;
211
- width: number;
212
- height: number;
213
- codec: string;
214
- profile: string;
215
- framerate: number;
216
- bitrate: number;
217
- duration: number;
218
- bitdepth: number;
219
- format_profile: string;
220
- format_tier: string;
221
- };
222
-
223
- export type TextTrackInfo = {
224
- is_default: boolean;
225
- codec: string;
226
- order: number;
227
- duration: number;
228
- language?: string;
229
- title?: string;
230
- is_vtt?: boolean;
231
- };
232
-
233
- export type Mediainfo = {
234
- general?: GeneralInfo;
235
- audio?: AudioTrackInfo[];
236
- video?: VideoTrackInfo[];
237
- text?: TextTrackInfo[];
161
+ export {
162
+ parseMediaInfo,
163
+ parseMediaRaw
238
164
  };
package/package.json CHANGED
@@ -1,13 +1,19 @@
1
1
  {
2
2
  "name": "@soga/mediainfo",
3
- "version": "0.4.0",
3
+ "publishConfig": {
4
+ "access": "public"
5
+ },
6
+ "version": "0.5.0",
4
7
  "main": "./dist/index.js",
5
8
  "module": "./dist/index.mjs",
6
9
  "types": "./dist/index.d.ts",
7
10
  "scripts": {
8
- "build": "tsup src/index.ts --format cjs,esm --dts",
11
+ "build": "rimraf dist && tsup src/index.ts --format cjs,esm --dts",
9
12
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch"
10
13
  },
14
+ "files": [
15
+ "dist"
16
+ ],
11
17
  "keywords": [],
12
18
  "author": "",
13
19
  "license": "ISC",
@@ -18,6 +24,8 @@
18
24
  "tsup": "^8.5.0"
19
25
  },
20
26
  "devDependencies": {
21
- "@types/fs-extra": "^11.0.4"
22
- }
27
+ "@types/fs-extra": "^11.0.4",
28
+ "rimraf": "^6.0.1"
29
+ },
30
+ "prepublishOnly": "npm run build"
23
31
  }
package/tsconfig.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "extends": "@repo/typescript-config/node.json",
3
- "compilerOptions": {
4
- "outDir": "dist"
5
- },
6
- "include": ["src"],
7
- "exclude": ["node_modules", "dist"]
8
- }