UNPKG

arib-subtitle-timedmetadater

Version:
186 lines (185 loc) 8.13 kB
#!/usr/bin/env node "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var arib_mpeg2ts_parser_1 = require("arib-mpeg2ts-parser"); var arib_mpeg2ts_parser_2 = require("arib-mpeg2ts-parser"); var ID3 = /** @class */ (function () { function ID3() { } ID3.metadata_pointer_descriptor = function (program_number) { var metadata_pointer_descriptor_application_format = Buffer.from([0xFF, 0xFF]); var metadata_pointer_descriptor_application_format_identifier = Buffer.from([ 0x49, 0x44, 0x33, 0x20, // ID3 ]); var metadata_pointer_descriptor_format = Buffer.from([0xFF]); var metadata_pointer_descriptor_format_identifier = Buffer.from([ 0x49, 0x44, 0x33, 0x20 // ID3 ]); var metadata_pointer_descriptor_flags = Buffer.from([ 0x00, 0x1F // metadata_service_id + other flags ]); var metadata_pointer_descriptor_program_number = Buffer.from([ ((program_number & 0xFF00) >> 8), ((program_number & 0x00FF) >> 0) ]); var metadata_descriptor_payload = Buffer.concat([ metadata_pointer_descriptor_application_format, metadata_pointer_descriptor_application_format_identifier, metadata_pointer_descriptor_format, metadata_pointer_descriptor_format_identifier, metadata_pointer_descriptor_flags, metadata_pointer_descriptor_program_number, ]); var metadata_descriptor_length = Buffer.from([metadata_descriptor_payload.length]); var metadata_descriptor_tag = Buffer.from([0x26]); return Buffer.concat([ metadata_descriptor_tag, metadata_descriptor_length, metadata_descriptor_payload, ]); }; ID3.metadata_descriptor = function () { var metadata_descriptor_application_format = Buffer.from([0xFF, 0xFF]); var metadata_descriptor_application_format_identifier = Buffer.from([ 0x49, 0x44, 0x33, 0x20, // ID3 ]); var metadata_descriptor_format = Buffer.from([0xFF]); var metadata_descriptor_format_identifier = Buffer.from([ 0x49, 0x44, 0x33, 0x20, // ID3 ]); var metadata_descriptor_flags = Buffer.from([ 0xFF, 0x0F, // metadata_service_id + other flags ]); var metadata_descriptor_payload = Buffer.concat([ metadata_descriptor_application_format, metadata_descriptor_application_format_identifier, metadata_descriptor_format, metadata_descriptor_format_identifier, metadata_descriptor_flags, ]); var metadata_descriptor_length = Buffer.from([metadata_descriptor_payload.length]); var metadata_descriptor_tag = Buffer.from([0x26]); return Buffer.concat([ metadata_descriptor_tag, metadata_descriptor_length, metadata_descriptor_payload, ]); }; ID3.metadata_elementary_stream = function (PID) { var descriptor = this.metadata_descriptor(); var ES_info_length = Buffer.from([ ((descriptor.length & 0xFF00) >> 8), ((descriptor.length & 0x00FF) >> 0), ]); var elementary_PID = Buffer.from([ ((PID & 0x1F00) >> 8), ((PID & 0x00FF) >> 0), ]); var stream_type = Buffer.from([0x15]); return Buffer.concat([ stream_type, elementary_PID, ES_info_length, descriptor, ]); }; ID3.ID3v2TXXX = function (description, text) { var txxx_payload = Buffer.concat([ Buffer.from([0x03]), Buffer.from(description, 'utf-8'), Buffer.from([0x00]), Buffer.from(text, 'utf-8'), Buffer.from([0x00]), // for video.js TXXX handling (必ず NULL 終端にしておく方がいい、 NULL 終端前提の場合がある) ]); var txxx_paylaod_size = Buffer.from([ ((txxx_payload.length & 0xFE00000) >> 21), ((txxx_payload.length & 0x01FC000) >> 14), ((txxx_payload.length & 0x0003F80) >> 7), ((txxx_payload.length & 0x000007F) >> 0), ]); var txxx_frame = Buffer.concat([ Buffer.from('TXXX', 'utf-8'), txxx_paylaod_size, Buffer.from([0x00, 0x00]), txxx_payload, ]); var txxx_frame_size = Buffer.from([ ((txxx_frame.length & 0xFE00000) >> 21), ((txxx_frame.length & 0x01FC000) >> 14), ((txxx_frame.length & 0x0003F80) >> 7), ((txxx_frame.length & 0x000007F) >> 0), ]); return Buffer.concat([ Buffer.from([0x49, 0x44, 0x33, 0x04, 0x00, 0x00]), txxx_frame_size, txxx_frame, ]); }; ID3.ID3v2PRIV = function (owner, binary) { var priv_payload = Buffer.concat([ Buffer.from(owner, 'utf-8'), Buffer.from([0x00]), binary ]); var priv_paylaod_size = Buffer.from([ ((priv_payload.length & 0xFE00000) >> 21), ((priv_payload.length & 0x01FC000) >> 14), ((priv_payload.length & 0x0003F80) >> 7), ((priv_payload.length & 0x000007F) >> 0), ]); var priv_frame = Buffer.concat([ Buffer.from('PRIV', 'utf-8'), priv_paylaod_size, Buffer.from([0x00, 0x00]), priv_payload, ]); var priv_frame_size = Buffer.from([ ((priv_frame.length & 0xFE00000) >> 21), ((priv_frame.length & 0x01FC000) >> 14), ((priv_frame.length & 0x0003F80) >> 7), ((priv_frame.length & 0x000007F) >> 0), ]); return Buffer.concat([ Buffer.from([0x49, 0x44, 0x33, 0x04, 0x00, 0x00]), priv_frame_size, priv_frame, ]); }; ID3.timedmetadata = function (pts, id3) { var header = Buffer.from([ 0x00, 0x00, 0x01, 0xbd, // +2 bytes ]); var flags = Buffer.from([ 0x84, 0x80, // (10, 00, 1, 0, 0, 0), (10 (PTS only), 0, 0, 0, 0, 0, 0, 0) +1 byte ]); var PTS = Buffer.from([ ((2 << 4) | (((pts / (1 << 30)) & 0x7) << 1) | 1), ((((pts >>> 0) & 0x3FC00000) >> 22)), ((((pts >>> 0) & 0x003F8000) >> 15) << 1) | 1, ((((pts >>> 0) & 0x00007F80) >> 7)), ((((pts >>> 0) & 0x0000007F) >> 0) << 1) | 1, ]); // TSPES.PES_HEADER_SIZE + flags + PES_header_data_length + PTS + payload var without_padding_length = arib_mpeg2ts_parser_2.TSPES.PES_HEADER_SIZE + 2 + 1 + 5 /* PTS */ + 5 /* padding for ffmepg metadata(0x15) handling*/ + id3.length; var packet_payload_size = (arib_mpeg2ts_parser_1.TSPacket.PACKET_SIZE - arib_mpeg2ts_parser_1.TSPacket.HEADER_SIZE); var stuffing_length = packet_payload_size - (without_padding_length % packet_payload_size); var payload = Buffer.concat([ flags, Buffer.from([5] /* PTS */), PTS, Buffer.alloc(5, 0), /* ffmpeg は metadata (0x15) の先頭を 5byte をヘッダーだと思って、スキップしてデータ処理をする */ /* この 5byte のヘッダーは stream_id 0xbd ではなく、stream_id 0xfc の時にあるものなので、timed-id3 でスキップは不適格 */ /* なので、 ffmpeg じゃなく直で利用する場合には、この 5 byteパディングは要らない */ /* TODO: オプションで ffmpeg と正常ハンドリング と変えられるようにしておくこと */ id3, ]); return Buffer.concat([ header, Buffer.from([ (((payload.length + stuffing_length) & 0xFF00) >> 8), (((payload.length + stuffing_length) & 0x00FF) >> 0), ]), payload, Buffer.alloc(stuffing_length, 0xFF), ]); }; return ID3; }()); exports.default = ID3;