0

index.js

const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ffmpeg = require('fluent-ffmpeg');
const process = require('process');


const args = process.argv.slice(2);
if (args.length !== 4) {
    console.error('Incorrect number of arguments');
    process.exit(1);
  }
const startTime = args[0];
const timeDuration = args[1];
const inputFile = args[2];
const outputFile=args[3];

ffmpeg.setFfmpegPath(ffmpegPath);

ffmpeg(inputFile)
  .setStartTime(startTime)
  .setDuration(timeDuration)
  .output(outputFile)
  .outputOptions('-hls_list_size 0')
  .on('end', function(err) {
    if(!err) { console.log('conversion Done') }
  })
  .on('error', function(err){
    console.log('error: ', err)
  }).run();

Here is the index.js and I'm running it by hitting the command on the terminal

node index.js 5 40 ./input.mp4 ./output.m3u8

Here 5 is for starting time and 40 is the time duration in seconds. The process creates m3u8 with ts files but the first ts file isn't getting created properly. It's been created in kb format while all the other files in mb format. enter image description here

the output_test0 isn't getting generated properly and so that's why while playing the m3u8 file, the first few seconds is just static picture. This issue has been happening with the first ts output only. Any trick on how to fix it?

Alan
  • 21
  • 4
  • Are you sure it is not a problem with the video player? Try to rule out node.js by executing the ffmpeg command directly in a terminal and see if the result is different. – Hernán Alarcón Jan 14 '21 at 03:27
  • I tried this in command line ``` ffmpeg -i f1.mp4 -profile:v baseline -level 3.0 -s 640x360 -start_number 0 -hls_time 10 -hls_list_size 0 -f hls index.m3u8``` and it works perfectly fine. I tried to set output options in node js too but the first ts file still isn't working – Alan Jan 14 '21 at 07:48
  • Use [the start event](https://www.npmjs.com/package/fluent-ffmpeg#start-ffmpeg-process-started) to print the command line and configure your node.js code to obtain a command line equivalent to the one that you already know that works. – Hernán Alarcón Jan 14 '21 at 15:49
  • I found the issue. Here is the right command line " ffmpeg -i test.m3u8 -ss 6.2 -y -t 45 -profile:v baseline -level 3 -start_number 0 -hls_list_size 0 -f hls output_test.m3u8 " . But node js is passing this in command line " ffmpeg -ss 6.2 -i test.m3u8 -y -t 45 -profile:v baseline -level 3 -start_number 0 -hls_list_size 0 -f hls output_test.m3u8" basically -ss [start_time] should go after -i [input] . Any trick how to fix that? The command needs to be output seeking. Here is the document link https://trac.ffmpeg.org/wiki/Seeking – Alan Jan 14 '21 at 17:24

1 Answers1

1

Following your comment about how it seems to be caused by the use of input seeking instead of output seeking:

Use seek() or seekOutput() instead of setStartTime(). The documentation describes the difference:

seek(time): seek output


Aliases: seekOutput().

Seeks streams before encoding them into the output. This is different from calling seekInput() in that the offset will only apply to one output. This is also slower, as skipped frames will still be decoded (but dropped).

The time argument may be a number (in seconds) or a timestamp string (with format [[hh:]mm:]ss[.xxx]).

ffmpeg('/path/to/file.avi')
  .seekInput('1:00')

  .output('from-1m30s.avi')
  .seek(30)

  .output('from-1m40s.avi')
  .seek('0:40');

setStartTime() is an alias for seekInput(). From the same documentation:

seekInput(time): set input start time


Alias: setStartTime().

Seeks an input and only start decoding at given time offset.

Note that seek() or seekOutput() should be applied to the output and not on the input as seekInput(), i.e. after output().

Hernán Alarcón
  • 3,494
  • 14
  • 16
  • Thanks, I have been able to solve it. Here is the link to my updated code https://codesandbox.io/s/modest-brahmagupta-8dins Basically what I did was, removed setStartTime() and replaced it with outputOption('-ss',startTime) , for this the command became -i [file path] -ss [start_time]. Now it is in output seeking format so it worked. Thanks :) – Alan Jan 14 '21 at 19:02