Can I download all segments of a m3u8 file as one mp4 file using web ( no ffmpeg )

elti musa picture elti musa · Dec 22, 2014 · Viewed 20.9k times · Source

Is it possible to download all m3u8 segments in one file using javascript or php

I search for this but couldn't find anything;

Answer

SudoPlz picture SudoPlz · Mar 11, 2016

TL/DR: I used the following code to download all the mpeg-ts chunk files from the m3u8 link, and then I convert each one of them into an .mp4 programmatically.

I ended up with many small .mp4 files which I could add into a vlc playlist and play, but I was not able to programmatically concatenate all those mp4 files into one mp4 file using javascript.

I've heard the last part of merging all those ts files into one mp4 file can be done with mux.js, but I haven't done it myself.

Long version:

What I ended up doing was I used m3u8_to_mpegts to download each and every MPEG_TS file that the m3u8 file pointed to into a directory.

var TsFetcher = require('m3u8_to_mpegts');

TsFetcher({
    uri: "http://api.new.livestream.com/accounts/15210385/events/4353996/videos/113444715.m3u8",
       cwd: "destinationDirectory",
       preferLowQuality: true,
   }, 
   function(){
        console.log("Download of chunk files complete");
        convertTSFilesToMp4();
   }
);

Then I converted those .ts files into .mp4 files using mpegts_to_mp4

var concat = require('concatenate-files');


// Read all files and run 
function getFiles(currentDirPath, callback) {
    var fs = require('fs'),
        path = require('path');
    fs.readdir(currentDirPath, function (err, files) {
        if (err) {
            throw new Error(err);
        }

        var fileIt = files.length;
        files.forEach(function (name) {
            fileIt--;
            // console.log(fileIt+" files remaining");
            var filePath = path.join(currentDirPath, name);
            var stat = fs.statSync(filePath);
            if (stat.isFile()) {
                callback(filePath, (fileIt==0));
            }
        });
    });
}




var mpegts_to_mp4 = require('mpegts_to_mp4');
var toConvertIt=0, doneConvertingIt = 0;

function convertTSFilesToMp4(){ 
    getFiles("destinationDirectory/bandwidth-198000", 
        function onFileDiscovered(filePath, noMoreFiles){   //onFileDiscovered runs for each file we discover in the destination directory
            var filenameParts = filePath.split("/"); // if on Windows execute .split("\\");, thanks Chayemor!
            var filename = filenameParts[2];
            if(filename.split(".")[1]=="ts"){   //if its a ts file
                console.log(filename);  

                mpegts_to_mp4(filePath, toConvertIt+'dest.mp4', function (err) {
                    // ... handle success/error ...
                    if(err){
                        console.log("Error: "+err);
                    }
                    doneConvertingIt++
                    console.log("Finished converting file "+toConvertIt);
                    if(doneConvertingIt==toConvertIt){
                        console.log("Done converting vids.");
                    }
                });
                toConvertIt++;
            }
        });
}

Caution: What to change in the given code if you wish to use it:

  • The uri obviously
  • the (cwd) location that you wish to save the ts files (mine was destinationDirectory)
  • preferLowQuality set it to false if you prefer the highest quality it will find
  • the location that you read your ts files from after you've downloaded them (mine was destinationDirectory/bandwidth-198000)

I hope this code helps someone in the future. Special thanks to Tenacex for helping me out on this.