Node-fluent-ffmpeg: How to make multiple .ts output files if doing HLS

Created on 8 May 2018  路  7Comments  路  Source: fluent-ffmpeg/node-fluent-ffmpeg

How can I ensure that multiple files get written when working with HLS? I'm creating a HLS playlist and I would need saving the 000.ts etc. segments separately. The resulting .m3u8 file is there as expected, but not the actual files listed in its contents. Not sure how to approach this, as with HLS, I obviously don't know the number of files in advance - it depends on the input file length and chunk size settings.

Version information

  • fluent-ffmpeg version: 2.1.2
  • ffmpeg version: 4.0
  • OS: OSX High Sierra 10.13.4

Code to reproduce

const ffmpeg = require('fluent-ffmpeg')
const command = ffmpeg(msg.payload.filePath)
      .audioCodec('libopus')
      .audioBitrate(96)
      .outputOptions([
        '-hls_time 10',
        '-hls_playlist_type vod',
        `-hls_segment_filename %03d.ts`,
        '-hls_base_url http://localhost:8080/'
      ])
      .output('outputfile.m3u8')
      .on('progress', function(progress) {
        console.log('Processing: ' + progress.percent + '% done')
      })
      .on('end', function(err, stdout, stderr) {
        console.log('Finished processing!' /*, err, stdout, stderr*/)
      })
      .run() 

Expected results

All files are saved, the .m3u8 and all the 0000-0003.ts segments

Observed results

ffmpeg does everything correctly, except saving the .ts files, this is the log of stdout:

ffmpeg version 4.0 Copyright (c) 2000-2018 the FFmpeg developers
  built with Apple LLVM version 9.1.0 (clang-902.0.39.1)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.0 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-gpl --enable-libmp3lame --enable-libopus --enable-libx264 --enable-libxvid --enable-opencl --enable-videotoolbox --disable-lzma
  libavutil      56. 14.100 / 56. 14.100
  libavcodec     58. 18.100 / 58. 18.100
  libavformat    58. 12.100 / 58. 12.100
  libavdevice    58.  3.100 / 58.  3.100
  libavfilter     7. 16.100 /  7. 16.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  1.100 /  5.  1.100
  libswresample   3.  1.100 /  3.  1.100
  libpostproc    55.  1.100 / 55.  1.100
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, aiff, from '/testfile.aif':
  Duration: 00:00:30.22, start: 0.000000, bitrate: 1411 kb/s
    Stream #0:0: Audio: pcm_s16be, 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
  Stream #0:0 -> #0:0 (pcm_s16be (native) -> opus (libopus))
Press [q] to stop, [?] for help
[hls @ 0x7faafe800000] Opening '000.ts' for writing
[mpegts @ 0x7faafd008e00] frame size not set
Output #0, hls, to '/outputfile.m3u8':
  Metadata:
    encoder         : Lavf58.12.100
    Stream #0:0: Audio: opus (libopus), 48000 Hz, stereo, s16, 96 kb/s
    Metadata:
      encoder         : Lavc58.18.100 libopus
[hls @ 0x7faafe800000] Opening '001.ts' for writing
[hls @ 0x7faafe800000] Opening '/outputfile.m3u8.tmp' for writing
[hls @ 0x7faafe800000] Opening '002.ts' for writing
[hls @ 0x7faafe800000] Opening '/outputfile.m3u8.tmp' for writing
[hls @ 0x7faafe800000] Opening '003.ts' for writing
[hls @ 0x7faafe800000] Opening '/outputfile.m3u8.tmp' for writing
[hls @ 0x7faafe800000] Opening '/outputfile.m3u8.tmp' for writing
size=N/A time=00:00:30.23 bitrate=N/A speed=85.9x
video:0kB audio:352kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
cat outputfile.m3u8
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:10.000000,
http://localhost:8080/000.ts
#EXTINF:10.000000,
http://localhost:8080/001.ts
#EXTINF:10.000000,
http://localhost:8080/002.ts
#EXTINF:0.228733,
http://localhost:8080/003.ts
#EXT-X-ENDLIST

Most helpful comment

[edited]
Searching the web and I found this

Try this

const ffmpeg = require('fluent-ffmpeg')
const command = ffmpeg('e:/dlds/test.avi')
    .audioCodec('libopus')
    .audioBitrate(96)
    .outputOptions([
        '-codec: copy',
        '-hls_time 10',
        '-hls_playlist_type vod',
        '-hls_base_url http://localhost:8080/',
        '-hls_segment_filename ~/%03d.ts'
    ])
    .output('outputfile.m3u8')
    .on('progress', function(progress) {
        console.log('Processing: ' + progress.percent + '% done')
    })
    .on('end', function(err, stdout, stderr) {
        console.log('Finished processing!' /*, err, stdout, stderr*/)
    })
    .run() 

All 7 comments

@haywirez Maybe ffmpeg is placing them in your /tmp?
Try and search them on your system.

On windows it's working
image

[edited]
Searching the web and I found this

Try this

const ffmpeg = require('fluent-ffmpeg')
const command = ffmpeg('e:/dlds/test.avi')
    .audioCodec('libopus')
    .audioBitrate(96)
    .outputOptions([
        '-codec: copy',
        '-hls_time 10',
        '-hls_playlist_type vod',
        '-hls_base_url http://localhost:8080/',
        '-hls_segment_filename ~/%03d.ts'
    ])
    .output('outputfile.m3u8')
    .on('progress', function(progress) {
        console.log('Processing: ' + progress.percent + '% done')
    })
    .on('end', function(err, stdout, stderr) {
        console.log('Finished processing!' /*, err, stdout, stderr*/)
    })
    .run() 

That worked!!! Thanks!! Indeed seems the .ts files were going to a temp folder, for anyone else facing this - make sure to specify the path of the -hls_segment_filename (also had to use absolute paths):

const command = ffmpeg(msg.payload.filePath)
     .audioCodec('libopus')
        .audioBitrate(96)
        .outputOptions([
          '-hls_time 10',
          '-hls_playlist_type vod',
          `-hls_segment_filename /absolute/path/%03d.ts`,
          '-hls_base_url http://localhost:8080/'
        ])
        .output('/Users/attila/Desktop/outputfile.m3u8')
        .on('progress', function(progress) {
          console.log('Processing: ' + progress.percent + '% done')
        })
        .on('end', function(err, stdout, stderr) {
          console.log('Finished processing!' /*, err, stdout, stderr*/)
          // console.log(stdout)
        })
        .run()     

Can we close this? @njoyard or @haywirez

Yep, all works 馃憤

@xedsvg can you please convert these commands to ffmpeg fluent?

mkdir segments && ffmpeg -hide_banner -y -i testing123.mp4 \
  -vf scale=w=640:h=360:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod  -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_segment_filename segments/360p_%09d.ts segments/360p.m3u8 \
  -vf scale=w=842:h=480:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 1400k -maxrate 1498k -bufsize 2100k -b:a 128k -hls_segment_filename segments/480p_%09d.ts segments/480p.m3u8 \
  -vf scale=w=1280:h=720:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_segment_filename segments/720p_%09d.ts segments/720p.m3u8 \
  -vf scale=w=1920:h=1080:force_original_aspect_ratio=decrease -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 4 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_segment_filename segments/1080p_%09d.ts segments/1080p.m3u8 \

hi,how to transport ts files to aws S3 by streaming, without local storage.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

odigity picture odigity  路  4Comments

geraldoramos picture geraldoramos  路  3Comments

LauraWebdev picture LauraWebdev  路  3Comments

echo66 picture echo66  路  3Comments

Rubinhuang9239 picture Rubinhuang9239  路  3Comments