Skip to content

WIP 708 caption logging #403

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions 708-caption-logger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const fs = require('fs');
const mp4 = require('./lib/mp4');
const file = fs.readFileSync(process.argv[2] || './bad-708.ts');

// https://github.com/google/ExoPlayer/blob/16b51d689c6a1a5ec327d1977a5fe8de9fefe41e/library/core/src/main/java/com/google/android/exoplayer2/text/cea/Cea708Decoder.java#L529
const transmuxer = new mp4.Transmuxer();

// Setting the BMDT to ensure that captions and id3 tags are not
// time-shifted by this value when they are output and instead are
// zero-based
transmuxer.setBaseMediaDecodeTime(100000);

transmuxer.on('data', function(data) {
if (data.captions) {
console.log(data.captions);
}
});

transmuxer.push(file);
transmuxer.flush();
126 changes: 124 additions & 2 deletions lib/m2ts/caption-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,97 @@
// Link To Transport
// -----------------

const handleC0 = function(command) {
// Nul
if (command === 0x00) {
// do nothing
//console.log('c0 NUL')
} else if (command === 0x03) {
//console.log('c0 EXT');
} else if (command === 0x08) {
//console.log('c0 Backspace');
process.stdout.moveCursor(-1);
process.stdout.clearLine(1)
} else if (command === 0x0C) {
//console.log('c0 Formfeed');
} else if (command === 0x0D) {
//console.log('c0 CarriageReturn');
} else if (command === 0x0E) {
//console.log('c0 ClearLine');
} else {
if (command >= 0x11 && command <= 0x17) {
//console.log('c0 EXT1');
} else if (command >= 0x18 && command <= 0x1f) {
//console.log('c0 P16');
} else {
//console.log('c0 invalid command')
}
}

};

const handleC1 = function(command) {
if (command >= 0x80 && command <= 0x87) {
//console.log('C1 set current window CW' + (command - 0x80));
} else if (command === 0x88) {
//console.log('C1 CLW (clearWindows)');
return 1;
} else if (command === 0x89) {
//console.log('C1 DSW (displayWindows)');
return 1;
} else if (command === 0x8A) {
//console.log('C1 HDW (hideWindows)');
return 1;
} else if (command === 0x8b) {
//console.log('C1 TGW (toggleWindows)');
return 1;
} else if (command === 0x8c) {
//console.log('C1 DLW (deleteWindows)');
return 1;
} else if (command === 0x8D) {
//console.log('C1 DLY (delay)');
return 1;
} else if (command === 0x8E) {
//console.log('C1 DLC (delay cancel)');
} else if (command === 0x8F) {
//console.log('C1 RST (reset)');
} else if (command === 0x90) {
//console.log('C1 SPA (set pen attributes)');
return 2;
} else if (command === 0x91) {
// console.log('C1 SPC (set pen color)')
return 3;
} else if (command === 0x92) {
// console.log('C1 SPL (set pen location)');
return 2;
} else if (command === 0x97) {
// console.log('C1 SWA (set window attributes)');
return 4;
} else if (command >= 0x98 && command <= 0x9F) {
// console.log('C1 DF' + (command - 0x98) + '(define window)');
return 6;
} else {
// console.log('C1 invalid command');
}
};

const handleG0 = function(command) {
let str = String.fromCharCode(command & 0xFF);

if (command === 0x7F) {
str = String.fromCharCode(0x266a);
}

//console.log('G0 ' + command.toString(16) + ' ' + str );
process.stdout.write(str);
};

const handleG1 = function(command) {
//console.log('G1 ' + command.toString(16) + ' ' + String.fromCharCode(command));
process.stdout.write(String.fromCharCode(command));
};


var Stream = require('../utils/stream');
var cea708Parser = require('../tools/caption-packet-parser');

Expand Down Expand Up @@ -493,6 +584,7 @@ Cea708Stream.prototype.add708Bytes = function(packet) {
var data = packet.ccData;
var byte0 = data >>> 8;
var byte1 = data & 0xff;
debugger;

// I would just keep a list of packets instead of bytes, but it isn't clear in the spec
// that service blocks will always line up with byte pairs.
Expand All @@ -513,7 +605,7 @@ Cea708Stream.prototype.push708Packet = function() {
var b = packetData[i++];

packet708.seq = b >> 6;
packet708.sizeCode = b & 0x3f; // 0b00111111;
packet708.sizeCode = (b & 0x3f) * 2 - 1; // 0b00111111;

for (; i < packetData.length; i++) {
b = packetData[i++];
Expand All @@ -529,7 +621,7 @@ Cea708Stream.prototype.push708Packet = function() {
this.pushServiceBlock(serviceNum, i, blockSize);

if (blockSize > 0) {
i += blockSize - 1;
i += blockSize;
}
}
};
Expand All @@ -548,16 +640,46 @@ Cea708Stream.prototype.push708Packet = function() {
*/
Cea708Stream.prototype.pushServiceBlock = function(serviceNum, start, size) {
var b;
var dw;
var i = start;
var packetData = this.current708Packet.data;
var service = this.services[serviceNum];

debugger;

if (!service) {
service = this.initService(serviceNum, i);
}

for (; i < start + size && i < packetData.length; i++) {
b = packetData[i];
let skip = 0;

// extended commands
if (b === 0x10) {
b = packetData[i++];
if (b <= 0x1f) {
console.log('cl group c2', dw.toString(16));
} else if (b >= 0x20 && b <= 0x7f) {
console.log('gl group g2', dw.toString(16));
} else if (b >= 0x80 && dw <= 0x9f) {
console.log('cr group c3', dw.toString(16));
} else if (dw >= 0xa0 && dw <= 0xff) {
console.log('gr group g3', dw.toString(16));
}
} else if (b <= 0x1f) {
skip = handleC0(b);
} else if (b <= 0x7f) {
skip = handleG0(b);
} else if (b <= 0x9f) {
skip = handleC1(b);
} else if (b <= 0xff) {
skip = handleG1(b);
}
if (skip) {
i += skip;
}
continue;

if (within708TextBlock(b)) {
i = this.handleText(i, service);
Expand Down
2 changes: 2 additions & 0 deletions lib/tools/caption-packet-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ var parseUserData = function(sei) {
var parseCaptionPackets = function(pts, userData) {
var results = [], i, count, offset, data;


// if this is just filler, return immediately
if (!(userData[0] & 0x40)) {
return results;
Expand All @@ -142,6 +143,7 @@ var parseCaptionPackets = function(pts, userData) {
results.push(data);
}
}

return results;
};

Expand Down