question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Export high quality video?

See original GitHub issue

Thanks for this great library and to the citizens of the UK for diligently paying their TV License to the BBC.

This closed issue touches on the question of exporting video from VideoContext: https://github.com/bbc/VideoContext/issues/76

This does seem like something there could be significant demand for.

So far I’ve been able to export jerky, low frame rate video using WebMWriter: https://github.com/thenickdude/webm-writer-js

I’ve done it successfully like this:

import VideoContext from "videocontext"
import WebMWriter from "webm-writer"
import { exportLocation } from "../utils/paths";

       const canvas = this.refs.canvas
        const ctx = new VideoContext(canvas);
        const videoNode1 = ctx.video(path.join(__static,
            '/landroid_example-I8JoRYblU.mp4'), 0, 2, { muted: true, loop: true });
        videoNode1.start(0);
        videoNode1.stop(5);
        var videoNode2 = ctx.video(path.join(__static, '/soccert-transparent.webm'), 0, 2, { muted: true, loop: true });
        videoNode2.start(2);
        videoNode2.stop(5);
        var videoNode3 = ctx.video(path.join(__static, '/200-puuWV_57.webm'), 0, 2, { muted: true, loop: true });
        videoNode3.start(3);
        videoNode3.stop(5);
        var combineEffect = ctx.compositor(combineDescription);
        videoNode1.connect(combineEffect);
        videoNode2.connect(combineEffect);
        videoNode3.connect(combineEffect);
        combineEffect.connect(ctx.destination);
        ctx.registerCallback("update", function () {
            console.log("new frame");
            videoWriter.addFrame(canvas);
        });
        const exportPath = exportLocation("testExport.webm")
        console.log(exportPath)
        ctx.registerCallback("ended", function () {
            console.log("Playback ended");
            videoWriter.complete().then(function (webMBlob) {
                 var reader = new FileReader()
                reader.onload = function () {
                    var buffer = new Buffer(reader.result)
                    fs.writeFile(exportPath, buffer, {}, (err, res) => {
                        if (err) {
                            console.error(err)
                            return
                        }
                        console.log('video saved')
                    })
                }
                reader.readAsArrayBuffer(webMBlob)
            });
        });
        var videoWriter = new WebMWriter({
            quality: 0.95,    // WebM image quality from 0.0 (worst) to 1.0 (best)
            fileWriter: null, // FileWriter in order to stream to a file instead of buffering to memory (optional)
            fd: null,         // Node.js file handle to write to instead of buffering to memory (optional)
            // You must supply one of:
            frameDuration: null, // Duration of frames in milliseconds
            frameRate: 24,     // Number of frames per second
        });

        ctx.play();

I’m doing this within an Electron application, so I have access to all the node file system stuff.

So as a proof of concept, this is encouraging. My next challenge is to get a high frame rate, high quality export.

Definitely the export is going to have to be “offline”, or, put another way, it’s not going to be “realtime.”

In the closed issue referenced above, this library is mentioned:

https://github.com/spite/ccapture.js/

It doesn’t work yet as a NPM package, see this issue:

https://github.com/spite/ccapture.js/issues/78

And I’ve been unable to even test it due to this issue:

https://github.com/spite/ccapture.js/issues/87

…But, given access to the Node APIs, I am wondering if this is even the right approach?

There are probably lots of ways to go about this, but I am wondering if anyone here has found the way to make this work reliabily and at full frame rate?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:18 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
MysteryPancakecommented, May 19, 2019

It may still be possible to use MediaRecorder:

Using MediaRecorder sounds like a great approach. To me there are a few problems that remain unsolved with that way of doing things:

What happens if there is buffering?

This could be overcome with requestFrame. “Applications that need to carefully control the timing of rendering and frame capture can use requestFrame() to directly specify when it’s time to capture a frame.” If requestFrame could be hooked into each canvas update, buffering could be avoided (in theory).

It does not capture audio.

Audio can be captured via MediaStream.addTrack(). It may be possible to render the audio and video separately (perhaps using an OfflineAudioContext), then connect them together via addTrack to keep the timing synchronized.

1reaction
kingpalethecommented, Feb 6, 2019

@Unsigno Thanks. I am wondering if this will work. One of the developers here, @gsouquet, wrote on this issue:

Video Context does not provide any ways to know when a frame has been rendered

… and you seem to be suggesting that you have found a stable way to know when a frame has been rendered… you seem to trying to do so with


 function nodesReady(){
                for (var i in videoContext._sourceNodes) {
                    if (!videoContext._sourceNodes[i]._ready && videoContext._sourceNodes[i].state < 4) return false;
                }
                return true;
            }

I am suspicious that this may not reliable, because if it were this straightforward, surely @gsouquet would have pointed this out.

But I will definitely be trying this soon and will post back here with my findings when I do.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Export broadcast-quality video projects - Adobe Support
Learn how to export high resolution videos in Adobe After Effects from compositions using the Render Queue and the Pro-Res and DNxHD codecs....
Read more >
Pro Tip: Exporting a Finished Video from Premiere Pro
To export a video in Premiere Pro, go to File > Export > Media. You could also press the shortcut key Ctrl +...
Read more >
The 4 Best Video Formats for Exporting - RocketStock
Here are some of the most reliable video codecs you can export with from the Adobe Suite. · H.264 · Quicktime MOV ·...
Read more >
How to Export Video From Premiere Pro
A good rule is that if size isn't an issue, export to the highest settings and quality you can. If size is an...
Read more >
How To Export High Quality Video For Instagram - EasyEdit.pro
Go to composition and add to Adobe Media Encoder Queue.Choose H.264 format. Check the box Render at Maximum Depth.Change level to 3.2. Change...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found