diff --git a/.gitignore b/.gitignore
index 97289ca..8681a87 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,10 +4,6 @@
# node modules
node_modules/
-# dist
-dist/package.json
-dist/README.md
-
# roolup cache
.rollup.cache/
diff --git a/dist/README.md b/dist/README.md
new file mode 100644
index 0000000..89ba2d1
--- /dev/null
+++ b/dist/README.md
@@ -0,0 +1,52 @@
+### A tool for download hls/m3u8 to mp4
+
+#### This package depends on @ffmpeg/ffmpeg, you need install it first
+
+```shell
+# install ffmpeg
+npm install @ffmpeg/ffmpeg @ffmpeg/core
+
+```
+
+##### for more information, see [https://github.com/ffmpegwasm/ffmpeg.wasm](https://github.com/ffmpegwasm/ffmpeg.wasm)
+
+### online demo
+
+[online demo](https://code-app.netlify.app/hls2mp4/)
+
+### install
+
+```shell
+# npm
+npm install hls2mp4
+
+# yarn
+yarn add hls2mp4
+```
+
+### usage
+
+```js
+import Hls2Mp4 from "hls2mp4";
+
+const hls2mp4 = new Hls2Mp4({
+ log: true
+}, (type, progress) => {
+ // type = 0 => load FFmpeg
+ // type = 1 => parse m3u8
+ // type = 2 => downloading ts
+ // type = 3 => merge ts
+});
+
+const buffer = await hls2mp4.download('your m3u8 url')
+hls2mp4.saveToFile(buffer, 'test.mp4')
+```
+
+#### as script
+```html
+
+
+
+```
diff --git a/dist/hls2mp4.cjs b/dist/hls2mp4.cjs
index 9c82b56..79d0a20 100644
--- a/dist/hls2mp4.cjs
+++ b/dist/hls2mp4.cjs
@@ -1039,15 +1039,16 @@ var Hls2Mp4 = /** @class */ (function () {
});
};
Hls2Mp4.prototype.downloadM3u8 = function (url) {
+ var _a, _b, _c;
return __awaiter(this, void 0, void 0, function () {
- var m3u8Parsed, _a, content, parsedUrl, keyMatchRegExp, keyTagMatchRegExp, matchReg, matches, segments, i, matched, matchedKey, matchedIV, batch, treatedSegments, segments_1, segments_1_1, group, total, keyBuffer, keyUrl, _loop_1, this_1, i, e_1_1, m3u8;
- var e_1, _b;
- return __generator(this, function (_c) {
- switch (_c.label) {
+ var m3u8Parsed, _d, content, parsedUrl, keyMatchRegExp, keyTagMatchRegExp, matchReg, matches, segments, i, matched, matchedKey, matchedIV, batch, treatedSegments, segments_1, segments_1_1, group, total, keyBuffer, keyUrl, _loop_1, this_1, i, e_1_1, m3u8;
+ var e_1, _e;
+ return __generator(this, function (_f) {
+ switch (_f.label) {
case 0: return [4 /*yield*/, this.parseM3u8(url)];
case 1:
- m3u8Parsed = _c.sent();
- _a = m3u8Parsed, content = _a.content, parsedUrl = _a.url;
+ m3u8Parsed = _f.sent();
+ _d = m3u8Parsed, content = _d.content, parsedUrl = _d.url;
keyMatchRegExp = createFileUrlRegExp('key', 'gi');
keyTagMatchRegExp = new RegExp('#EXT-X-KEY:METHOD=(AES-128|NONE)(,URI="' + keyMatchRegExp.source + '"(,IV=\\w+)?)?', 'gi');
matchReg = new RegExp(keyTagMatchRegExp.source + '|' + createFileUrlRegExp('ts', 'gi').source, 'g');
@@ -1056,37 +1057,35 @@ var Hls2Mp4 = /** @class */ (function () {
throw new Error('Invalid m3u8 file, no ts file found');
}
segments = [];
- if (matches) {
- for (i = 0; i < matches.length; i++) {
- matched = matches[i];
- if (matched.match(/#EXT-X-KEY/)) {
- matchedKey = matched.match(keyMatchRegExp);
- matchedIV = matched.match(/(?<=IV=)\w+$/);
- segments.push({
- key: matchedKey === null || matchedKey === void 0 ? void 0 : matchedKey[0],
- iv: matchedIV === null || matchedIV === void 0 ? void 0 : matchedIV[0],
- segments: []
- });
- }
- else if (i === 0) {
- segments.push({
- segments: [matched]
- });
- }
- else {
- segments[segments.length - 1].segments.push(matched);
- }
+ for (i = 0; i < matches.length; i++) {
+ matched = matches[i];
+ if (matched.match(/#EXT-X-KEY/)) {
+ matchedKey = (_a = matched.match(keyMatchRegExp)) === null || _a === void 0 ? void 0 : _a[0];
+ matchedIV = (_c = (_b = matched.match(/IV=\w+$/)) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.replace(/^IV=/, '');
+ segments.push({
+ key: matchedKey,
+ iv: matchedIV,
+ segments: []
+ });
+ }
+ else if (i === 0) {
+ segments.push({
+ segments: [matched]
+ });
+ }
+ else {
+ segments[segments.length - 1].segments.push(matched);
}
}
this.totalSegments = segments.reduce(function (prev, current) { return prev + current.segments.length; }, 0);
this.savedSegments = 0;
batch = this.tsDownloadConcurrency;
treatedSegments = 0;
- _c.label = 2;
+ _f.label = 2;
case 2:
- _c.trys.push([2, 12, 13, 14]);
+ _f.trys.push([2, 12, 13, 14]);
segments_1 = __values(segments), segments_1_1 = segments_1.next();
- _c.label = 3;
+ _f.label = 3;
case 3:
if (!!segments_1_1.done) return [3 /*break*/, 11];
group = segments_1_1.value;
@@ -1096,14 +1095,14 @@ var Hls2Mp4 = /** @class */ (function () {
keyUrl = parseUrl(parsedUrl, group.key);
return [4 /*yield*/, this.downloadFile(keyUrl)];
case 4:
- keyBuffer = _c.sent();
- _c.label = 5;
+ keyBuffer = _f.sent();
+ _f.label = 5;
case 5:
_loop_1 = function (i) {
- var downloadSegs, downloadSegs_1, downloadSegs_1_1, _d, source, name_1;
- var e_2, _e;
- return __generator(this, function (_f) {
- switch (_f.label) {
+ var downloadSegs, downloadSegs_1, downloadSegs_1_1, _g, source, name_1;
+ var e_2, _h;
+ return __generator(this, function (_j) {
+ switch (_j.label) {
case 0: return [4 /*yield*/, this_1.downloadSegments(group.segments.slice(i * batch, Math.min(total, (i + 1) * batch)).map(function (seg, j) {
var url = parseUrl(parsedUrl, seg);
var name = "seg-".concat(treatedSegments + i * batch + j, ".ts");
@@ -1114,17 +1113,17 @@ var Hls2Mp4 = /** @class */ (function () {
};
}), keyBuffer, group.iv)];
case 1:
- downloadSegs = _f.sent();
+ downloadSegs = _j.sent();
try {
for (downloadSegs_1 = (e_2 = void 0, __values(downloadSegs)), downloadSegs_1_1 = downloadSegs_1.next(); !downloadSegs_1_1.done; downloadSegs_1_1 = downloadSegs_1.next()) {
- _d = downloadSegs_1_1.value, source = _d.source, name_1 = _d.name;
+ _g = downloadSegs_1_1.value, source = _g.source, name_1 = _g.name;
content = content.replace(source, name_1);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
- if (downloadSegs_1_1 && !downloadSegs_1_1.done && (_e = downloadSegs_1.return)) _e.call(downloadSegs_1);
+ if (downloadSegs_1_1 && !downloadSegs_1_1.done && (_h = downloadSegs_1.return)) _h.call(downloadSegs_1);
}
finally { if (e_2) throw e_2.error; }
}
@@ -1134,30 +1133,30 @@ var Hls2Mp4 = /** @class */ (function () {
};
this_1 = this;
i = 0;
- _c.label = 6;
+ _f.label = 6;
case 6:
if (!(i <= Math.floor((total / batch)))) return [3 /*break*/, 9];
return [5 /*yield**/, _loop_1(i)];
case 7:
- _c.sent();
- _c.label = 8;
+ _f.sent();
+ _f.label = 8;
case 8:
i++;
return [3 /*break*/, 6];
case 9:
treatedSegments += total;
- _c.label = 10;
+ _f.label = 10;
case 10:
segments_1_1 = segments_1.next();
return [3 /*break*/, 3];
case 11: return [3 /*break*/, 14];
case 12:
- e_1_1 = _c.sent();
+ e_1_1 = _f.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 14];
case 13:
try {
- if (segments_1_1 && !segments_1_1.done && (_b = segments_1.return)) _b.call(segments_1);
+ if (segments_1_1 && !segments_1_1.done && (_e = segments_1.return)) _e.call(segments_1);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
@@ -1255,7 +1254,7 @@ var Hls2Mp4 = /** @class */ (function () {
anchor.click();
setTimeout(function () { return URL.revokeObjectURL(objectUrl); }, 100);
};
- Hls2Mp4.version = '1.1.8';
+ Hls2Mp4.version = '1.1.9';
Hls2Mp4.TaskType = TaskType;
return Hls2Mp4;
}());
diff --git a/dist/hls2mp4.js b/dist/hls2mp4.js
index 2903087..24f03a8 100644
--- a/dist/hls2mp4.js
+++ b/dist/hls2mp4.js
@@ -1038,15 +1038,16 @@ var Hls2Mp4 = (function (FFmpeg) {
});
};
Hls2Mp4.prototype.downloadM3u8 = function (url) {
+ var _a, _b, _c;
return __awaiter(this, void 0, void 0, function () {
- var m3u8Parsed, _a, content, parsedUrl, keyMatchRegExp, keyTagMatchRegExp, matchReg, matches, segments, i, matched, matchedKey, matchedIV, batch, treatedSegments, segments_1, segments_1_1, group, total, keyBuffer, keyUrl, _loop_1, this_1, i, e_1_1, m3u8;
- var e_1, _b;
- return __generator(this, function (_c) {
- switch (_c.label) {
+ var m3u8Parsed, _d, content, parsedUrl, keyMatchRegExp, keyTagMatchRegExp, matchReg, matches, segments, i, matched, matchedKey, matchedIV, batch, treatedSegments, segments_1, segments_1_1, group, total, keyBuffer, keyUrl, _loop_1, this_1, i, e_1_1, m3u8;
+ var e_1, _e;
+ return __generator(this, function (_f) {
+ switch (_f.label) {
case 0: return [4 /*yield*/, this.parseM3u8(url)];
case 1:
- m3u8Parsed = _c.sent();
- _a = m3u8Parsed, content = _a.content, parsedUrl = _a.url;
+ m3u8Parsed = _f.sent();
+ _d = m3u8Parsed, content = _d.content, parsedUrl = _d.url;
keyMatchRegExp = createFileUrlRegExp('key', 'gi');
keyTagMatchRegExp = new RegExp('#EXT-X-KEY:METHOD=(AES-128|NONE)(,URI="' + keyMatchRegExp.source + '"(,IV=\\w+)?)?', 'gi');
matchReg = new RegExp(keyTagMatchRegExp.source + '|' + createFileUrlRegExp('ts', 'gi').source, 'g');
@@ -1055,37 +1056,35 @@ var Hls2Mp4 = (function (FFmpeg) {
throw new Error('Invalid m3u8 file, no ts file found');
}
segments = [];
- if (matches) {
- for (i = 0; i < matches.length; i++) {
- matched = matches[i];
- if (matched.match(/#EXT-X-KEY/)) {
- matchedKey = matched.match(keyMatchRegExp);
- matchedIV = matched.match(/(?<=IV=)\w+$/);
- segments.push({
- key: matchedKey === null || matchedKey === void 0 ? void 0 : matchedKey[0],
- iv: matchedIV === null || matchedIV === void 0 ? void 0 : matchedIV[0],
- segments: []
- });
- }
- else if (i === 0) {
- segments.push({
- segments: [matched]
- });
- }
- else {
- segments[segments.length - 1].segments.push(matched);
- }
+ for (i = 0; i < matches.length; i++) {
+ matched = matches[i];
+ if (matched.match(/#EXT-X-KEY/)) {
+ matchedKey = (_a = matched.match(keyMatchRegExp)) === null || _a === void 0 ? void 0 : _a[0];
+ matchedIV = (_c = (_b = matched.match(/IV=\w+$/)) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.replace(/^IV=/, '');
+ segments.push({
+ key: matchedKey,
+ iv: matchedIV,
+ segments: []
+ });
+ }
+ else if (i === 0) {
+ segments.push({
+ segments: [matched]
+ });
+ }
+ else {
+ segments[segments.length - 1].segments.push(matched);
}
}
this.totalSegments = segments.reduce(function (prev, current) { return prev + current.segments.length; }, 0);
this.savedSegments = 0;
batch = this.tsDownloadConcurrency;
treatedSegments = 0;
- _c.label = 2;
+ _f.label = 2;
case 2:
- _c.trys.push([2, 12, 13, 14]);
+ _f.trys.push([2, 12, 13, 14]);
segments_1 = __values(segments), segments_1_1 = segments_1.next();
- _c.label = 3;
+ _f.label = 3;
case 3:
if (!!segments_1_1.done) return [3 /*break*/, 11];
group = segments_1_1.value;
@@ -1095,14 +1094,14 @@ var Hls2Mp4 = (function (FFmpeg) {
keyUrl = parseUrl(parsedUrl, group.key);
return [4 /*yield*/, this.downloadFile(keyUrl)];
case 4:
- keyBuffer = _c.sent();
- _c.label = 5;
+ keyBuffer = _f.sent();
+ _f.label = 5;
case 5:
_loop_1 = function (i) {
- var downloadSegs, downloadSegs_1, downloadSegs_1_1, _d, source, name_1;
- var e_2, _e;
- return __generator(this, function (_f) {
- switch (_f.label) {
+ var downloadSegs, downloadSegs_1, downloadSegs_1_1, _g, source, name_1;
+ var e_2, _h;
+ return __generator(this, function (_j) {
+ switch (_j.label) {
case 0: return [4 /*yield*/, this_1.downloadSegments(group.segments.slice(i * batch, Math.min(total, (i + 1) * batch)).map(function (seg, j) {
var url = parseUrl(parsedUrl, seg);
var name = "seg-".concat(treatedSegments + i * batch + j, ".ts");
@@ -1113,17 +1112,17 @@ var Hls2Mp4 = (function (FFmpeg) {
};
}), keyBuffer, group.iv)];
case 1:
- downloadSegs = _f.sent();
+ downloadSegs = _j.sent();
try {
for (downloadSegs_1 = (e_2 = void 0, __values(downloadSegs)), downloadSegs_1_1 = downloadSegs_1.next(); !downloadSegs_1_1.done; downloadSegs_1_1 = downloadSegs_1.next()) {
- _d = downloadSegs_1_1.value, source = _d.source, name_1 = _d.name;
+ _g = downloadSegs_1_1.value, source = _g.source, name_1 = _g.name;
content = content.replace(source, name_1);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
- if (downloadSegs_1_1 && !downloadSegs_1_1.done && (_e = downloadSegs_1.return)) _e.call(downloadSegs_1);
+ if (downloadSegs_1_1 && !downloadSegs_1_1.done && (_h = downloadSegs_1.return)) _h.call(downloadSegs_1);
}
finally { if (e_2) throw e_2.error; }
}
@@ -1133,30 +1132,30 @@ var Hls2Mp4 = (function (FFmpeg) {
};
this_1 = this;
i = 0;
- _c.label = 6;
+ _f.label = 6;
case 6:
if (!(i <= Math.floor((total / batch)))) return [3 /*break*/, 9];
return [5 /*yield**/, _loop_1(i)];
case 7:
- _c.sent();
- _c.label = 8;
+ _f.sent();
+ _f.label = 8;
case 8:
i++;
return [3 /*break*/, 6];
case 9:
treatedSegments += total;
- _c.label = 10;
+ _f.label = 10;
case 10:
segments_1_1 = segments_1.next();
return [3 /*break*/, 3];
case 11: return [3 /*break*/, 14];
case 12:
- e_1_1 = _c.sent();
+ e_1_1 = _f.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 14];
case 13:
try {
- if (segments_1_1 && !segments_1_1.done && (_b = segments_1.return)) _b.call(segments_1);
+ if (segments_1_1 && !segments_1_1.done && (_e = segments_1.return)) _e.call(segments_1);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
@@ -1254,7 +1253,7 @@ var Hls2Mp4 = (function (FFmpeg) {
anchor.click();
setTimeout(function () { return URL.revokeObjectURL(objectUrl); }, 100);
};
- Hls2Mp4.version = '1.1.8';
+ Hls2Mp4.version = '1.1.9';
Hls2Mp4.TaskType = TaskType;
return Hls2Mp4;
}());
diff --git a/dist/hls2mp4.umd.js b/dist/hls2mp4.umd.js
index cd07464..3adf0b7 100644
--- a/dist/hls2mp4.umd.js
+++ b/dist/hls2mp4.umd.js
@@ -1041,15 +1041,16 @@
});
};
Hls2Mp4.prototype.downloadM3u8 = function (url) {
+ var _a, _b, _c;
return __awaiter(this, void 0, void 0, function () {
- var m3u8Parsed, _a, content, parsedUrl, keyMatchRegExp, keyTagMatchRegExp, matchReg, matches, segments, i, matched, matchedKey, matchedIV, batch, treatedSegments, segments_1, segments_1_1, group, total, keyBuffer, keyUrl, _loop_1, this_1, i, e_1_1, m3u8;
- var e_1, _b;
- return __generator(this, function (_c) {
- switch (_c.label) {
+ var m3u8Parsed, _d, content, parsedUrl, keyMatchRegExp, keyTagMatchRegExp, matchReg, matches, segments, i, matched, matchedKey, matchedIV, batch, treatedSegments, segments_1, segments_1_1, group, total, keyBuffer, keyUrl, _loop_1, this_1, i, e_1_1, m3u8;
+ var e_1, _e;
+ return __generator(this, function (_f) {
+ switch (_f.label) {
case 0: return [4 /*yield*/, this.parseM3u8(url)];
case 1:
- m3u8Parsed = _c.sent();
- _a = m3u8Parsed, content = _a.content, parsedUrl = _a.url;
+ m3u8Parsed = _f.sent();
+ _d = m3u8Parsed, content = _d.content, parsedUrl = _d.url;
keyMatchRegExp = createFileUrlRegExp('key', 'gi');
keyTagMatchRegExp = new RegExp('#EXT-X-KEY:METHOD=(AES-128|NONE)(,URI="' + keyMatchRegExp.source + '"(,IV=\\w+)?)?', 'gi');
matchReg = new RegExp(keyTagMatchRegExp.source + '|' + createFileUrlRegExp('ts', 'gi').source, 'g');
@@ -1058,37 +1059,35 @@
throw new Error('Invalid m3u8 file, no ts file found');
}
segments = [];
- if (matches) {
- for (i = 0; i < matches.length; i++) {
- matched = matches[i];
- if (matched.match(/#EXT-X-KEY/)) {
- matchedKey = matched.match(keyMatchRegExp);
- matchedIV = matched.match(/(?<=IV=)\w+$/);
- segments.push({
- key: matchedKey === null || matchedKey === void 0 ? void 0 : matchedKey[0],
- iv: matchedIV === null || matchedIV === void 0 ? void 0 : matchedIV[0],
- segments: []
- });
- }
- else if (i === 0) {
- segments.push({
- segments: [matched]
- });
- }
- else {
- segments[segments.length - 1].segments.push(matched);
- }
+ for (i = 0; i < matches.length; i++) {
+ matched = matches[i];
+ if (matched.match(/#EXT-X-KEY/)) {
+ matchedKey = (_a = matched.match(keyMatchRegExp)) === null || _a === void 0 ? void 0 : _a[0];
+ matchedIV = (_c = (_b = matched.match(/IV=\w+$/)) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.replace(/^IV=/, '');
+ segments.push({
+ key: matchedKey,
+ iv: matchedIV,
+ segments: []
+ });
+ }
+ else if (i === 0) {
+ segments.push({
+ segments: [matched]
+ });
+ }
+ else {
+ segments[segments.length - 1].segments.push(matched);
}
}
this.totalSegments = segments.reduce(function (prev, current) { return prev + current.segments.length; }, 0);
this.savedSegments = 0;
batch = this.tsDownloadConcurrency;
treatedSegments = 0;
- _c.label = 2;
+ _f.label = 2;
case 2:
- _c.trys.push([2, 12, 13, 14]);
+ _f.trys.push([2, 12, 13, 14]);
segments_1 = __values(segments), segments_1_1 = segments_1.next();
- _c.label = 3;
+ _f.label = 3;
case 3:
if (!!segments_1_1.done) return [3 /*break*/, 11];
group = segments_1_1.value;
@@ -1098,14 +1097,14 @@
keyUrl = parseUrl(parsedUrl, group.key);
return [4 /*yield*/, this.downloadFile(keyUrl)];
case 4:
- keyBuffer = _c.sent();
- _c.label = 5;
+ keyBuffer = _f.sent();
+ _f.label = 5;
case 5:
_loop_1 = function (i) {
- var downloadSegs, downloadSegs_1, downloadSegs_1_1, _d, source, name_1;
- var e_2, _e;
- return __generator(this, function (_f) {
- switch (_f.label) {
+ var downloadSegs, downloadSegs_1, downloadSegs_1_1, _g, source, name_1;
+ var e_2, _h;
+ return __generator(this, function (_j) {
+ switch (_j.label) {
case 0: return [4 /*yield*/, this_1.downloadSegments(group.segments.slice(i * batch, Math.min(total, (i + 1) * batch)).map(function (seg, j) {
var url = parseUrl(parsedUrl, seg);
var name = "seg-".concat(treatedSegments + i * batch + j, ".ts");
@@ -1116,17 +1115,17 @@
};
}), keyBuffer, group.iv)];
case 1:
- downloadSegs = _f.sent();
+ downloadSegs = _j.sent();
try {
for (downloadSegs_1 = (e_2 = void 0, __values(downloadSegs)), downloadSegs_1_1 = downloadSegs_1.next(); !downloadSegs_1_1.done; downloadSegs_1_1 = downloadSegs_1.next()) {
- _d = downloadSegs_1_1.value, source = _d.source, name_1 = _d.name;
+ _g = downloadSegs_1_1.value, source = _g.source, name_1 = _g.name;
content = content.replace(source, name_1);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
- if (downloadSegs_1_1 && !downloadSegs_1_1.done && (_e = downloadSegs_1.return)) _e.call(downloadSegs_1);
+ if (downloadSegs_1_1 && !downloadSegs_1_1.done && (_h = downloadSegs_1.return)) _h.call(downloadSegs_1);
}
finally { if (e_2) throw e_2.error; }
}
@@ -1136,30 +1135,30 @@
};
this_1 = this;
i = 0;
- _c.label = 6;
+ _f.label = 6;
case 6:
if (!(i <= Math.floor((total / batch)))) return [3 /*break*/, 9];
return [5 /*yield**/, _loop_1(i)];
case 7:
- _c.sent();
- _c.label = 8;
+ _f.sent();
+ _f.label = 8;
case 8:
i++;
return [3 /*break*/, 6];
case 9:
treatedSegments += total;
- _c.label = 10;
+ _f.label = 10;
case 10:
segments_1_1 = segments_1.next();
return [3 /*break*/, 3];
case 11: return [3 /*break*/, 14];
case 12:
- e_1_1 = _c.sent();
+ e_1_1 = _f.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 14];
case 13:
try {
- if (segments_1_1 && !segments_1_1.done && (_b = segments_1.return)) _b.call(segments_1);
+ if (segments_1_1 && !segments_1_1.done && (_e = segments_1.return)) _e.call(segments_1);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
@@ -1257,7 +1256,7 @@
anchor.click();
setTimeout(function () { return URL.revokeObjectURL(objectUrl); }, 100);
};
- Hls2Mp4.version = '1.1.8';
+ Hls2Mp4.version = '1.1.9';
Hls2Mp4.TaskType = TaskType;
return Hls2Mp4;
}());
diff --git a/dist/index.js b/dist/index.js
index 3c77b58..cc3b3e9 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1037,15 +1037,16 @@ var Hls2Mp4 = /** @class */ (function () {
});
};
Hls2Mp4.prototype.downloadM3u8 = function (url) {
+ var _a, _b, _c;
return __awaiter(this, void 0, void 0, function () {
- var m3u8Parsed, _a, content, parsedUrl, keyMatchRegExp, keyTagMatchRegExp, matchReg, matches, segments, i, matched, matchedKey, matchedIV, batch, treatedSegments, segments_1, segments_1_1, group, total, keyBuffer, keyUrl, _loop_1, this_1, i, e_1_1, m3u8;
- var e_1, _b;
- return __generator(this, function (_c) {
- switch (_c.label) {
+ var m3u8Parsed, _d, content, parsedUrl, keyMatchRegExp, keyTagMatchRegExp, matchReg, matches, segments, i, matched, matchedKey, matchedIV, batch, treatedSegments, segments_1, segments_1_1, group, total, keyBuffer, keyUrl, _loop_1, this_1, i, e_1_1, m3u8;
+ var e_1, _e;
+ return __generator(this, function (_f) {
+ switch (_f.label) {
case 0: return [4 /*yield*/, this.parseM3u8(url)];
case 1:
- m3u8Parsed = _c.sent();
- _a = m3u8Parsed, content = _a.content, parsedUrl = _a.url;
+ m3u8Parsed = _f.sent();
+ _d = m3u8Parsed, content = _d.content, parsedUrl = _d.url;
keyMatchRegExp = createFileUrlRegExp('key', 'gi');
keyTagMatchRegExp = new RegExp('#EXT-X-KEY:METHOD=(AES-128|NONE)(,URI="' + keyMatchRegExp.source + '"(,IV=\\w+)?)?', 'gi');
matchReg = new RegExp(keyTagMatchRegExp.source + '|' + createFileUrlRegExp('ts', 'gi').source, 'g');
@@ -1054,37 +1055,35 @@ var Hls2Mp4 = /** @class */ (function () {
throw new Error('Invalid m3u8 file, no ts file found');
}
segments = [];
- if (matches) {
- for (i = 0; i < matches.length; i++) {
- matched = matches[i];
- if (matched.match(/#EXT-X-KEY/)) {
- matchedKey = matched.match(keyMatchRegExp);
- matchedIV = matched.match(/(?<=IV=)\w+$/);
- segments.push({
- key: matchedKey === null || matchedKey === void 0 ? void 0 : matchedKey[0],
- iv: matchedIV === null || matchedIV === void 0 ? void 0 : matchedIV[0],
- segments: []
- });
- }
- else if (i === 0) {
- segments.push({
- segments: [matched]
- });
- }
- else {
- segments[segments.length - 1].segments.push(matched);
- }
+ for (i = 0; i < matches.length; i++) {
+ matched = matches[i];
+ if (matched.match(/#EXT-X-KEY/)) {
+ matchedKey = (_a = matched.match(keyMatchRegExp)) === null || _a === void 0 ? void 0 : _a[0];
+ matchedIV = (_c = (_b = matched.match(/IV=\w+$/)) === null || _b === void 0 ? void 0 : _b[0]) === null || _c === void 0 ? void 0 : _c.replace(/^IV=/, '');
+ segments.push({
+ key: matchedKey,
+ iv: matchedIV,
+ segments: []
+ });
+ }
+ else if (i === 0) {
+ segments.push({
+ segments: [matched]
+ });
+ }
+ else {
+ segments[segments.length - 1].segments.push(matched);
}
}
this.totalSegments = segments.reduce(function (prev, current) { return prev + current.segments.length; }, 0);
this.savedSegments = 0;
batch = this.tsDownloadConcurrency;
treatedSegments = 0;
- _c.label = 2;
+ _f.label = 2;
case 2:
- _c.trys.push([2, 12, 13, 14]);
+ _f.trys.push([2, 12, 13, 14]);
segments_1 = __values(segments), segments_1_1 = segments_1.next();
- _c.label = 3;
+ _f.label = 3;
case 3:
if (!!segments_1_1.done) return [3 /*break*/, 11];
group = segments_1_1.value;
@@ -1094,14 +1093,14 @@ var Hls2Mp4 = /** @class */ (function () {
keyUrl = parseUrl(parsedUrl, group.key);
return [4 /*yield*/, this.downloadFile(keyUrl)];
case 4:
- keyBuffer = _c.sent();
- _c.label = 5;
+ keyBuffer = _f.sent();
+ _f.label = 5;
case 5:
_loop_1 = function (i) {
- var downloadSegs, downloadSegs_1, downloadSegs_1_1, _d, source, name_1;
- var e_2, _e;
- return __generator(this, function (_f) {
- switch (_f.label) {
+ var downloadSegs, downloadSegs_1, downloadSegs_1_1, _g, source, name_1;
+ var e_2, _h;
+ return __generator(this, function (_j) {
+ switch (_j.label) {
case 0: return [4 /*yield*/, this_1.downloadSegments(group.segments.slice(i * batch, Math.min(total, (i + 1) * batch)).map(function (seg, j) {
var url = parseUrl(parsedUrl, seg);
var name = "seg-".concat(treatedSegments + i * batch + j, ".ts");
@@ -1112,17 +1111,17 @@ var Hls2Mp4 = /** @class */ (function () {
};
}), keyBuffer, group.iv)];
case 1:
- downloadSegs = _f.sent();
+ downloadSegs = _j.sent();
try {
for (downloadSegs_1 = (e_2 = void 0, __values(downloadSegs)), downloadSegs_1_1 = downloadSegs_1.next(); !downloadSegs_1_1.done; downloadSegs_1_1 = downloadSegs_1.next()) {
- _d = downloadSegs_1_1.value, source = _d.source, name_1 = _d.name;
+ _g = downloadSegs_1_1.value, source = _g.source, name_1 = _g.name;
content = content.replace(source, name_1);
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
- if (downloadSegs_1_1 && !downloadSegs_1_1.done && (_e = downloadSegs_1.return)) _e.call(downloadSegs_1);
+ if (downloadSegs_1_1 && !downloadSegs_1_1.done && (_h = downloadSegs_1.return)) _h.call(downloadSegs_1);
}
finally { if (e_2) throw e_2.error; }
}
@@ -1132,30 +1131,30 @@ var Hls2Mp4 = /** @class */ (function () {
};
this_1 = this;
i = 0;
- _c.label = 6;
+ _f.label = 6;
case 6:
if (!(i <= Math.floor((total / batch)))) return [3 /*break*/, 9];
return [5 /*yield**/, _loop_1(i)];
case 7:
- _c.sent();
- _c.label = 8;
+ _f.sent();
+ _f.label = 8;
case 8:
i++;
return [3 /*break*/, 6];
case 9:
treatedSegments += total;
- _c.label = 10;
+ _f.label = 10;
case 10:
segments_1_1 = segments_1.next();
return [3 /*break*/, 3];
case 11: return [3 /*break*/, 14];
case 12:
- e_1_1 = _c.sent();
+ e_1_1 = _f.sent();
e_1 = { error: e_1_1 };
return [3 /*break*/, 14];
case 13:
try {
- if (segments_1_1 && !segments_1_1.done && (_b = segments_1.return)) _b.call(segments_1);
+ if (segments_1_1 && !segments_1_1.done && (_e = segments_1.return)) _e.call(segments_1);
}
finally { if (e_1) throw e_1.error; }
return [7 /*endfinally*/];
@@ -1253,7 +1252,7 @@ var Hls2Mp4 = /** @class */ (function () {
anchor.click();
setTimeout(function () { return URL.revokeObjectURL(objectUrl); }, 100);
};
- Hls2Mp4.version = '1.1.8';
+ Hls2Mp4.version = '1.1.9';
Hls2Mp4.TaskType = TaskType;
return Hls2Mp4;
}());
diff --git a/dist/package.json b/dist/package.json
new file mode 100644
index 0000000..14fe5fe
--- /dev/null
+++ b/dist/package.json
@@ -0,0 +1,46 @@
+{
+ "name": "hls2mp4",
+ "version": "1.1.9",
+ "description": "a tool for download hls/m3u8 to mp4",
+ "main": "index.js",
+ "types": "index.d.ts",
+ "repository": "https://github.com/icefee/hls2mp4",
+ "keywords": [
+ "ffmpeg",
+ "hls",
+ "m3u8"
+ ],
+ "author": "icefee@outlook.com",
+ "license": "MIT",
+ "scripts": {
+ "build": "rollup -c"
+ },
+ "dependencies": {
+ "aes-js": "^3.1.2"
+ },
+ "devDependencies": {
+ "@ffmpeg/core": "^0.11.0",
+ "@ffmpeg/ffmpeg": "^0.11.6",
+ "@rollup/plugin-node-resolve": "^15.0.2",
+ "@rollup/plugin-commonjs": "^25.0.0",
+ "@rollup/plugin-typescript": "^11.1.0",
+ "@types/aes-js": "^3.1.1",
+ "rollup": "^3.21.4",
+ "tslib": "^2.0.0",
+ "typescript": "^4.7.4"
+ },
+ "type": "module",
+ "homepage": "https://github.com/icefee/hls2mp4",
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 681764e..9f09eb0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "hls2mp4",
- "version": "1.1.8",
+ "version": "1.1.9",
"description": "a tool for download hls/m3u8 to mp4",
"main": "index.js",
"types": "index.d.ts",