4

I am trying to convert an MP4 file to HLS using ffmpeg. Code:

var stream = createReadStream(filePath);
ffmpeg(stream)
    .on('stderr', function(stderrLine) {
        console.log('Stderr output: ' + stderrLine);
    })
    .on('end', function() {
        console.log('done processing input stream');
    })
    .on('error', function(err) {
        console.log('an error happened: ' + err.message);
    })
    .save(join(__basedir, "public", `file.m3u8`));

OutPut:

Stderr output: ffmpeg version git-2020-05-22-38490cb Copyright (c) 2000-2020 the FFmpeg developers
Stderr output:   built with gcc 9.3.1 (GCC) 20200513
Stderr output:   configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --disable-w32threads --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
Stderr output:   libavutil      56. 46.100 / 56. 46.100
Stderr output:   libavcodec     58. 86.101 / 58. 86.101
Stderr output:   libavformat    58. 43.100 / 58. 43.100
Stderr output:   libavdevice    58.  9.103 / 58.  9.103
Stderr output:   libavfilter     7. 82.100 /  7. 82.100
Stderr output:   libswscale      5.  6.101 /  5.  6.101
Stderr output:   libswresample   3.  6.100 /  3.  6.100
Stderr output:   libpostproc    55.  6.100 / 55.  6.100
Stderr output: [mov,mp4,m4a,3gp,3g2,mj2 @ 000001b68c53cb00] overread end of atom 'stsd' by 34 bytes
Stderr output: [mov,mp4,m4a,3gp,3g2,mj2 @ 000001b68c53cb00] stream 0, offset 0x30: partial file
Stderr output: [mov,mp4,m4a,3gp,3g2,mj2 @ 000001b68c53cb00] Could not find codec parameters for stream 0 (Video: h264 (avc1 / 0x31637661), none, 1920x1080, 2528 kb/s): unspecified pixel format
Stderr output: Consider increasing the value for the 'analyzeduration' and 'probesize' options
Stderr output: Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'pipe:0':
Stderr output:   Metadata:
Stderr output:     major_brand     : isom
Stderr output:     minor_version   : 512
Stderr output:     compatible_brands: isomiso2avc1mp41
Stderr output:     encoder         : Lavf56.25.101
Stderr output:   Duration: 00:03:00.97, start: 0.000000, bitrate: N/A
Stderr output:     Stream #0:0(und): Video: h264 (avc1 / 0x31637661), none, 1920x1080, 2528 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 48k tbc (default)
Stderr output:     Metadata:
Stderr output:       handler_name    : VideoHandler
Stderr output:     Stream #0:1(eng): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default)
Stderr output:     Metadata:
Stderr output:       handler_name    : SoundHandler
Stderr output: Stream mapping:
Stderr output:   Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stderr output:   Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Stderr output: [mov,mp4,m4a,3gp,3g2,mj2 @ 000001b68c53cb00] stream 0, offset 0x30: partial file
Stderr output: pipe:0: Invalid data found when processing input
Stderr output: Cannot determine format of input stream 0:0 after EOF
Stderr output: Error marking filters as finished
Stderr output: Conversion failed!
Stderr output:
an error happened: ffmpeg exited with code 1: pipe:0: Invalid data found when processing input
Cannot determine format of input stream 0:0 after EOF
Error marking filters as finished
Conversion failed!

I've also tried with moveflag option .outputOptions("-movflags isml+frag_keyframe") also with -movflags faststart

I've read through How do you use Node.js to stream an MP4 file with ffmpeg?

But i didn't quite understand what and how to do it.

Sankalp Kataria
  • 479
  • 7
  • 24

1 Answers1

0

To achieve HLS from mp4 video we can use the below code.

  • We will pass the video as input with ffmpeg tags options. In this example, I am converting a 480p resolution related playlist. we can use the same code by just updating resolutions for 720p and 360p
  • after creating all three resolutions we will add MASTER PLAYLIST which contains all three versions with different BANDWIDTH options. this bandwidth will switch videos versions automatically based on your internet speed.

MASTER_PLAYLIST_SAMPLE

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
https://PROJECT_PATH/hls/5001/101/hlsThumbs/360/sample_video_360.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1400000,RESOLUTION=842x480
https://PROJECT_PATH/hls/5001/101/hlsThumbs/480/sample_video_480.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1280x720
https://PROJECT_PATH/hls/5001/101/hlsThumbs/720/sample_video_720.m3u8
#EXT-X-ENDLIST

VERSIONING_FILE_SAMPLE

let ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
let ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegPath);

const creatorId = 5001;
const videoId = 101;
const videoFileName = "sample_video.mp4";
const version480Name = "sample_video_480.m3u8"

ffmpeg('public/assets/hls/'+creatorId+'/'+videoId+'/original/'+videoFileName, { timeout: 432000 }).addOptions([
  '-strict -2',
  '-preset:v veryfast', 
  '-profile:v baseline', // baseline profile (level 3.0) for H264 video codec
  '-level 3.0', 
  '-s 842x480',          // 842px width, 480px height output video dimensions
  '-start_number 0',     // start the first .ts segment at index 0
  '-hls_time 10',        // 10 second segment duration
  '-hls_list_size 0',    // Maxmimum number of playlist entries (0 means all entries/infinite)
  '-f hls'               // HLS format
]).output('public/assets/hls/'+creatorId+'/'+videoId+'/hlsThumbs/480/'+version480Name)
.on('error', function(err, stdout, stderr) {
console.log('An error occurred: ' + err);
console.log("ffmpeg stdout:\n" + stdout);
console.log("ffmpeg stderr:\n" + stderr);
console.log("Hls Cannot be converted for this video");
callback(err);
})
.on('progress', function(progress) { 
  console.log('HLS Processing : 480p ----'+ JSON.stringify(progress) + ' done'); })
.on('end', callback1).run();   

You can debug your .m3u8 HLS URL from this link - HLS URL TESTER