简体   繁体   中英

Hls.js record file

Hello and thanks for reading,

I have a Hls stream with an m3u8 playlist. The Video is playing just fine on an Html page with a Video element and https://github.com/video-dev/hls.js

But if I download the segments to join them they are only white pixels. VLC and FFmpeg can't handle them. VLC shows a white pixel for 10seconds and FFmpeg says that there's no stream in the file.

So now I want to know what this hls.js is doing to make it running. To me a non-js developer it all looks a bit confusing. I was able to understand stuff like which function is called when a new segment is loaded. Unfortunately, I was unable to understand stuff about the data. The one character variables are confusing to me.

For now, I capture the stream of the video element and download it later but I don't like this solution at all.

How to help me

It would be very nice if anyone can tell me how to hook into the script and tell it to download directly to the disk so I'm independent of framerate drops.

If anyone can tell how the script is able to convert the data so that the element can use it and I would be able to implement or do it with FFmpeg would be really helpful.

I also thought it might be possible to have a listener when the blob changes to store its contents.

Thanks for everyone helping. I'm trying to find a solution for too many hours now.

I found the solution. After looking at their great event system https://github.com/video-dev/hls.js/ and this issue which I contributed too and not just copied https://github.com/video-dev/hls.js/issues/1322

var arrayRecord = [];

function download(data, filename) {
    console.log('downloading...');
    var blob = new Blob([arrayConcat(data)], {
        type: 'application/octet-stream'
    });
    saveAs(blob, filename);
}

function arrayConcat(inputArray) {
    var totalLength = inputArray.reduce(function (prev, cur) {
        return prev + cur.length
    }, 0);
    var result = new Uint8Array(totalLength);
    var offset = 0;
    inputArray.forEach(function (element) {
        result.set(element, offset);
        offset += element.length;
    });
    return result;
}

function saveAs(blob, filename) {
    var url = URL.createObjectURL(blob);
    var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
    a.href = url;
    a.download = filename;
    a.click();
    window.URL.revokeObjectURL(url);
}

function stopRecord() {
    arrayRecord.forEach(function (item) {
        download(item.data['video'], "video.mp4");
        download(item.data['audio'], "audio.mp4");
        item.hls.destroy();
        return false;
    });
}

function startRecord() {
    var video = document.getElementById('video');
    var dataStream = {
        'video': [],
        'audio': []
    };
    var hls = new Hls();
    hls.loadSource("Your playlist");
    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED, function () {
        video.play();
        hls.on(Hls.Events.BUFFER_APPENDING, function (event, data) {
            console.log("apending");
            dataStream[data.type].push(data.data);
        });
    });
    arrayRecord.push({
        hls: hls,
        data: dataStream
    });
    video.onended = function (e) {
        stopRecord()
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM