Skip to content

Commit

Permalink
βœ” Debug in Prod πŸ’©
Browse files Browse the repository at this point in the history
  • Loading branch information
bifeldy committed Oct 12, 2023
1 parent 4646b98 commit 7cce3d5
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 129 deletions.
2 changes: 1 addition & 1 deletion dist/fansubid/server/main.js

Large diffs are not rendered by default.

262 changes: 134 additions & 128 deletions src/api/services/mkv-extract.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,139 +62,145 @@ export class MkvExtractService {

async mkvExtract(fileName: string, filePath: string): Promise<any[]> {
return new Promise((resolve, reject) => {

const startTime = Date.now();
this.gs.log(`[MKVEXTRACT_START] πŸ“‚ ${fileName} -- ${startTime} 🧬`, null, 'error');

const fileStream = createReadStream(filePath, {
highWaterMark: 2 * 1024 * 1024
});
const decoder = new Decoder();
const tracks = [];
const trackData = [];
const files = [];
const subtitleFileSize = [];
let currentFile = 0;
let currentTimecode = 0;
let trackIndexTemp = 0;
let trackTypeTemp = 0;
let trackDataTemp = '';
let trackIndex = 0;

decoder.on('error', error => {
this.gs.log(`[MKVEXTRACT_DECODER_ERROR] πŸŒ‹ ${fileName} 🧬`, error, 'error');
fileStream.destroy();
reject(error);
});

decoder.on('data', chunk => {
this.gs.log(`[MKVEXTRACT_DATA_CHUNK] βŒ› ${fileName} -- ${chunk[0]} -- ${chunk[1].name} -- ${chunk[1].dataSize} 🧬`, null, 'error');
switch (chunk[0]) {
case 'end':
// if (chunk[1].name === 'Info') {
// fileStream.destroy();
// }
if (chunk[1].name === 'TrackEntry') {
if (trackTypeTemp === 0x11) {
tracks.push(trackIndexTemp);
trackData.push([trackDataTemp]);
subtitleFileSize.push(0);
try {

const startTime = Date.now();
this.gs.log(`[MKVEXTRACT_START] πŸ“‚ ${fileName} -- ${startTime} 🧬`, null, 'error');

const fileStream = createReadStream(filePath, {
highWaterMark: 2 * 1024 * 1024
});
const decoder = new Decoder();
const tracks = [];
const trackData = [];
const files = [];
const subtitleFileSize = [];
let currentFile = 0;
let currentTimecode = 0;
let trackIndexTemp = 0;
let trackTypeTemp = 0;
let trackDataTemp = '';
let trackIndex = 0;

decoder.on('error', error => {
this.gs.log(`[MKVEXTRACT_DECODER_ERROR] πŸŒ‹ ${fileName} 🧬`, error, 'error');
fileStream.destroy();
reject(error);
});

decoder.on('data', chunk => {
this.gs.log(`[MKVEXTRACT_DATA_CHUNK] βŒ› ${fileName} -- ${chunk[0]} -- ${chunk[1].name} -- ${chunk[1].dataSize} 🧬`, null, 'error');
switch (chunk[0]) {
case 'end':
// if (chunk[1].name === 'Info') {
// fileStream.destroy();
// }
if (chunk[1].name === 'TrackEntry') {
if (trackTypeTemp === 0x11) {
tracks.push(trackIndexTemp);
trackData.push([trackDataTemp]);
subtitleFileSize.push(0);
}
}
}
break;
case 'tag':
if (chunk[1].name === 'FileName') {
if (!files[currentFile]) {
files[currentFile] = {};
break;
case 'tag':
if (chunk[1].name === 'FileName') {
if (!files[currentFile]) {
files[currentFile] = {};
}
files[currentFile].name = chunk[1].data.toString();
}
files[currentFile].name = chunk[1].data.toString();
}
if (chunk[1].name === 'FileData') {
if (!files[currentFile]) {
files[currentFile] = {};
if (chunk[1].name === 'FileData') {
if (!files[currentFile]) {
files[currentFile] = {};
}
files[currentFile].data = chunk[1].data;
files[currentFile].size = chunk[1].dataSize;
}
files[currentFile].data = chunk[1].data;
files[currentFile].size = chunk[1].dataSize;
}
if (chunk[1].name === 'TrackNumber') {
trackIndexTemp = chunk[1].data[0];
}
if (chunk[1].name === 'TrackType') {
trackTypeTemp = chunk[1].data[0];
}
if (chunk[1].name === 'CodecPrivate') {
trackDataTemp = chunk[1].data.toString();
}
if (chunk[1].name === 'SimpleBlock' || chunk[1].name === 'Block') {
const trackLength = tools.readVint(chunk[1].data);
trackIndex = tracks.indexOf(trackLength.value);
if (trackIndex !== -1) {
const timestampArray = new Uint8Array(chunk[1].data).slice(trackLength.length, trackLength.length + 2);
const timestamp = new DataView(timestampArray.buffer).getInt16(0);
const lineData = chunk[1].data.slice(trackLength.length + 3);
trackData[trackIndex].push(lineData.toString(), timestamp, currentTimecode);
subtitleFileSize[trackIndex] += chunk[1].dataSize;
if (chunk[1].name === 'TrackNumber') {
trackIndexTemp = chunk[1].data[0];
}
}
if (chunk[1].name === 'Timecode') {
const timecode = this.readUnsignedInteger(this.padZeroes(chunk[1].data));
currentTimecode = timecode;
}
if (chunk[1].name === 'BlockDuration' && trackIndex !== -1) {
// the duration is in milliseconds
const duration = this.readUnsignedInteger(this.padZeroes(chunk[1].data));
trackData[trackIndex].push(duration);
}
break;
default:
// do nothing
}
if (files[currentFile] && files[currentFile].name && files[currentFile].data && files[currentFile].size) {
currentFile++;
}
});

fileStream.on('end', () => {
for (const [idx, val] of trackData.entries()) {
const heading = val[0];
const isASS = heading.includes('Format:');
const formatFn = isASS ? this.formatTimestamp : this.formatTimestampSRT;
const eventMatches = isASS ? heading.match(/\[Events\]\s+Format:([^\r\n]*)/) : [''];
const headingParts = isASS ? heading.split(eventMatches[0]) : ['', ''];
const fixedLines: any = [];
for (let i = 1; i < val.length; i += 4) {
const line = val[i];
const lineTimestamp = val[i + 1];
const chunkTimestamp = val[i + 2];
const duration = val[i + 3];
const lineParts = isASS && line.split(',');
const lineIndex = isASS ? lineParts[0] : (i - 1) / 4;
const startTimestamp = formatFn(chunkTimestamp + lineTimestamp);
const endTimestamp = formatFn(chunkTimestamp + lineTimestamp + duration);
let fixedLine: any;
if (isASS) {
fixedLine = 'Dialogue: ' + [lineParts[1], startTimestamp, endTimestamp].concat(lineParts.slice(2)).join(',');
} else {
fixedLine = lineIndex + 1 + '\r\n' + startTimestamp.replace('.', ',') + ' --> ' + endTimestamp.replace('.', ',') + '\r\n' + line + '\r\n';
}
if (fixedLines[lineIndex]) {
fixedLines[lineIndex] += '\r\n' + fixedLine;
} else {
fixedLines[lineIndex] = fixedLine;
}
if (chunk[1].name === 'TrackType') {
trackTypeTemp = chunk[1].data[0];
}
if (chunk[1].name === 'CodecPrivate') {
trackDataTemp = chunk[1].data.toString();
}
if (chunk[1].name === 'SimpleBlock' || chunk[1].name === 'Block') {
const trackLength = tools.readVint(chunk[1].data);
trackIndex = tracks.indexOf(trackLength.value);
if (trackIndex !== -1) {
const timestampArray = new Uint8Array(chunk[1].data).slice(trackLength.length, trackLength.length + 2);
const timestamp = new DataView(timestampArray.buffer).getInt16(0);
const lineData = chunk[1].data.slice(trackLength.length + 3);
trackData[trackIndex].push(lineData.toString(), timestamp, currentTimecode);
subtitleFileSize[trackIndex] += chunk[1].dataSize;
}
}
if (chunk[1].name === 'Timecode') {
const timecode = this.readUnsignedInteger(this.padZeroes(chunk[1].data));
currentTimecode = timecode;
}
if (chunk[1].name === 'BlockDuration' && trackIndex !== -1) {
// the duration is in milliseconds
const duration = this.readUnsignedInteger(this.padZeroes(chunk[1].data));
trackData[trackIndex].push(duration);
}
break;
default:
// do nothing
}
if (files[currentFile] && files[currentFile].name && files[currentFile].data && files[currentFile].size) {
currentFile++;
}
files.push({
name: fileName + '_' + (idx + 1) + (isASS ? '.ass' : '.srt'),
data: (isASS ? headingParts[0] + eventMatches[0] + '\r\n' : '') + fixedLines.join('\r\n') + headingParts[1] + '\r\n',
size: subtitleFileSize[idx]
});
};
const endTime = Date.now();
this.gs.log(`[MKVEXTRACT_END] 🎬 ${fileName} -- ${endTime} -- ${(endTime - startTime) / 1000} seconds 🧬`, files, 'error');
resolve(files);
});

fileStream.pipe(decoder as any);
});

fileStream.on('end', () => {
for (const [idx, val] of trackData.entries()) {
const heading = val[0];
const isASS = heading.includes('Format:');
const formatFn = isASS ? this.formatTimestamp : this.formatTimestampSRT;
const eventMatches = isASS ? heading.match(/\[Events\]\s+Format:([^\r\n]*)/) : [''];
const headingParts = isASS ? heading.split(eventMatches[0]) : ['', ''];
const fixedLines: any = [];
for (let i = 1; i < val.length; i += 4) {
const line = val[i];
const lineTimestamp = val[i + 1];
const chunkTimestamp = val[i + 2];
const duration = val[i + 3];
const lineParts = isASS && line.split(',');
const lineIndex = isASS ? lineParts[0] : (i - 1) / 4;
const startTimestamp = formatFn(chunkTimestamp + lineTimestamp);
const endTimestamp = formatFn(chunkTimestamp + lineTimestamp + duration);
let fixedLine: any;
if (isASS) {
fixedLine = 'Dialogue: ' + [lineParts[1], startTimestamp, endTimestamp].concat(lineParts.slice(2)).join(',');
} else {
fixedLine = lineIndex + 1 + '\r\n' + startTimestamp.replace('.', ',') + ' --> ' + endTimestamp.replace('.', ',') + '\r\n' + line + '\r\n';
}
if (fixedLines[lineIndex]) {
fixedLines[lineIndex] += '\r\n' + fixedLine;
} else {
fixedLines[lineIndex] = fixedLine;
}
}
files.push({
name: fileName + '_' + (idx + 1) + (isASS ? '.ass' : '.srt'),
data: (isASS ? headingParts[0] + eventMatches[0] + '\r\n' : '') + fixedLines.join('\r\n') + headingParts[1] + '\r\n',
size: subtitleFileSize[idx]
});
};
const endTime = Date.now();
this.gs.log(`[MKVEXTRACT_END] 🎬 ${fileName} -- ${endTime} -- ${(endTime - startTime) / 1000} seconds 🧬`, files, 'error');
resolve(files);
});

fileStream.pipe(decoder as any);

} catch (e) {
this.gs.log(`[MKVEXTRACT_DATA_ERROR] πŸŒ‹ ${fileName} 🧬`, e, 'error');
reject(e);
}

});
}
Expand Down

0 comments on commit 7cce3d5

Please sign in to comment.