hlsrecord 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #!/usr/bin/env node
  2. /* eslint-disable no-process-exit */
  3. "use strict";
  4. // record a live hls-stream storing an on-demand ready version
  5. var fs = require('fs'),
  6. path = require('path');
  7. var nopt = require('noptify/node_modules/nopt');
  8. var HlsSegmentReader = require('hls-segment-reader');
  9. var recorder = require('../lib/recorder');
  10. function DateValue(){}
  11. nopt.typeDefs[DateValue] = { type: DateValue, validate: function (data, key, val) {
  12. var date;
  13. if (val === 'now') val = '+0';
  14. if (val.length && (val[0] === '+' || val[0] === '-')) {
  15. date = new Date(Math.round(new Date().getTime() / 1000 + parseInt(val, 10)) * 1000);
  16. } else if (parseInt(val, 10) == val) {
  17. date = new Date(parseInt(val, 10) * 1000);
  18. } else {
  19. data = new Date(val);
  20. }
  21. if (!date) return false;
  22. data[key] = date;
  23. }};
  24. var hlsrecord = require('noptify')(process.argv, { program: 'hlsrecord <url>' });
  25. hlsrecord.version(require('../package').version)
  26. .option('collect', '-C', 'Collect output segments to a single file', Boolean)
  27. .option('output', '-o', 'Output directory', path)
  28. .option('create-dir', '-c', 'Explicitly create output dir', Boolean)
  29. .option('begin-date', '-b', 'Start recording at', DateValue)
  30. .option('end-date', '-e', 'Stop recording at', DateValue)
  31. .option('start-offset', '-s', 'Playback start time offset in seconds', Number)
  32. .option('create-dir', '-c', 'Explicitly create output dir', Boolean)
  33. .option('extension', 'Preserve specified vendor extension', Array)
  34. .option('segment-extension', 'Preserve specified vendor segment extension', Array)
  35. // .option('-a, --user-agent <string>', 'HTTP User-Agent')
  36. // .option('-f, --full', 'record all variants')
  37. .parse(process.argv);
  38. var options = hlsrecord.nopt;
  39. var src = options.argv.remain[0];
  40. if (!src) {
  41. hlsrecord.help();
  42. process.exit(-1);
  43. }
  44. var outDir = options.output || 'stream';
  45. if (options['create-dir'])
  46. fs.mkdirSync(outDir);
  47. if (options['begin-date'])
  48. console.log('fetching from:', options['begin-date']);
  49. if (options['end-date'])
  50. console.log('fetching until:', options['end-date']);
  51. var extensions = {};
  52. (options.extension || []).forEach(function(ext) {
  53. extensions[ext] = false;
  54. });
  55. (options['segment-extension'] || []).forEach(function(ext) {
  56. extensions[ext] = true;
  57. });
  58. var readerOptions = {
  59. withData: true,
  60. fullStream: !options['begin-date'],
  61. startDate: options['begin-date'],
  62. stopDate: options['end-date'],
  63. maxStallTime: 5 * 60 * 1000,
  64. extensions: extensions,
  65. highWaterMark: 0,
  66. };
  67. function createReader(src) {
  68. var r = new HlsSegmentReader(src, readerOptions);
  69. r.on('error', function(err) {
  70. console.error('reader error', err);
  71. });
  72. return r;
  73. }
  74. var rdr = createReader(src);
  75. recorder(rdr, outDir, { subreader:createReader, startOffset: options['start-offset'], collect: options.collect }).start();