123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- #!/usr/bin/env node
- /* eslint-disable no-console */
- const fs = require('fs');
- const path = require('path');
- const {Transmuxer} = require('../lib/mp4');
- const {version} = require('../package.json');
- const {concatTypedArrays} = require('@videojs/vhs-utils/cjs/byte-helpers');
- const {ONE_SECOND_IN_TS} = require('../lib/utils/clock.js');
- const showHelp = function() {
- console.log(`
- transmux media-file > foo.mp4
- transmux media-file -o foo.mp4
- curl -s 'some-media-ulr' | transmux.js -o foo.mp4
- wget -O - -o /dev/null 'some-media-url' | transmux.js -o foo.mp4
- transmux a supported segment (ts or adts) info an fmp4
- -h, --help print help
- -v, --version print the version
- -o, --output <string> write to a file instead of stdout
- -d, --debugger add a break point just before data goes to transmuxer
- `);
- };
- const parseArgs = function(args) {
- const options = {};
- for (let i = 0; i < args.length; i++) {
- const arg = args[i];
- if ((/^--version|-v$/).test(arg)) {
- console.log(`transmux.js v${version}`);
- process.exit(0);
- } else if ((/^--help|-h$/).test(arg)) {
- showHelp();
- process.exit(0);
- } else if ((/^--debugger|-d$/).test(arg)) {
- options.debugger = true;
- } else if ((/^--output|-o$/).test(arg)) {
- i++;
- options.output = args[i];
- } else {
- options.file = arg;
- }
- }
- return options;
- };
- const cli = function(stdin) {
- const options = parseArgs(process.argv.slice(2));
- let inputStream;
- let outputStream;
- // if stdin was provided
- if (stdin && options.file) {
- console.error(`You cannot pass in a file ${options.file} and pipe from stdin!`);
- process.exit(1);
- }
- if (stdin) {
- inputStream = process.stdin;
- } else if (options.file) {
- inputStream = fs.createReadStream(path.resolve(options.file));
- }
- if (!inputStream) {
- console.error('A file or stdin must be passed in as an argument or via pipeing to this script!');
- process.exit(1);
- }
- if (options.output) {
- outputStream = fs.createWriteStream(path.resolve(options.output), {
- encoding: null
- });
- } else {
- outputStream = process.stdout;
- }
- return new Promise(function(resolve, reject) {
- let allData;
- inputStream.on('data', (chunk) => {
- allData = concatTypedArrays(allData, chunk);
- });
- inputStream.on('error', reject);
- inputStream.on('close', () => {
- if (!allData || !allData.length) {
- return reject('file is empty');
- }
- resolve(allData);
- });
- }).then(function(inputData) {
- const transmuxer = new 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(ONE_SECOND_IN_TS);
- transmuxer.on('data', function(data) {
- if (data.initSegment) {
- outputStream.write(concatTypedArrays(data.initSegment, data.data));
- } else {
- outputStream.write(data.data);
- }
- });
- if (options.debugger) {
- // eslint-disable-next-line
- debugger;
- }
- transmuxer.push(inputData);
- transmuxer.flush();
- process.exit(0);
- }).catch(function(e) {
- console.error(e);
- process.exit(1);
- });
- };
- // no stdin if isTTY is set
- cli(!process.stdin.isTTY ? process.stdin : null);
|