We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.

Screenshots and Video Grabs

Home Forums General Questions Screenshots and Video Grabs

Viewing 15 posts - 1 through 15 (of 15 total)
  • Author
    Posts
  • #29500
    grimmy
    Customer

    Is there any way to download screenshots of my app at a size specified by the user and/or download gameplay of my app as a video? (some kind of screen recording functions)

    Cheers

    #29714

    Hi,

    You can download a screenshot of what’s rendered on a 3d scene via the take screenshot and download file puzzles. See here for more info: https://www.soft8soft.com/docs/manual/en/puzzles/HTML.html#download_file.

    EDIT: you also need to enable screenshots in your application via the configure_application puzzle. The option you need is called ‘enabled screenshots’.

    Co-founder and lead developer at Soft8Soft.

    #29722
    grimmy
    Customer

    Cool. And what about grabbing video? Could I theoretically use something like GetDisplayMedia if I created all the functions in Javascript? Or maybe there is another way?

    #29725

    Could I theoretically use something like GetDisplayMedia if I created all the functions in Javascript?

    Actually, yes. You can grab a video stream from the canvas element and download it.

    Here’s a simple snippet which you can add into the runCode function in your app’s js file:

    
    function runCode(app) {
        var isRecording = false;
        var TEXT_START = 'Start Recording';
        var TEXT_STOP = 'Stop Recording';
    
        var button = document.createElement('button');
        button.innerText = TEXT_START;
        button.style.position = 'relative';
        document.body.appendChild(button);
    
        var recorder = new MediaRecorder(app.renderer.domElement.captureStream());
        var videoElem = document.createElement('video');
    
        recorder.addEventListener('dataavailable', function(e) {
            var link = document.createElement('a');
            link.href = URL.createObjectURL(e.data);
            link.download = 'video.webm';
            document.body.appendChild(link);
            link.click();
            URL.revokeObjectURL(link.href);
        });
    
        button.addEventListener('click', function() {
            isRecording = !isRecording;
            button.innerText = isRecording ? TEXT_STOP : TEXT_START;
    
            if (isRecording) {
                recorder.start();
            } else {
                recorder.stop();
            }
        });
    }
    

    It adds a button to start recording and after you stop it automatically downloads the video in the webm format. Although, this snippet may not work in some browsers if some API features that’s used there are not supported, I only tested it in the latest Google Chrome version.

    Co-founder and lead developer at Soft8Soft.

    #56663
    bhobbes
    Participant

    Hello,
    I am an artist with zero coding experience. I came across Verge3D and so far it has been so easy to use (thank you!). I have one last thing I am trying to do with my app before I am ready to get a license and start production. I need to be able to make a video recording of my animation. I came across this thread and the code to record a video stream works when I plug it into the run code puzzle, however I have my verge app inside an iframe in my main html file.

    I would like to be able to alter the code above to record when the user clicks an html button “recordStart” and then to stop the recording when they click a second button “recordStop”. I already have puzzles set up to start and stop the animation when those buttons are clicked and would like to start/stop the recording with the same buttons.

    I have been trying to get that code to work for a while now, but I really have no javascript experience. Any help you could offer would be greatly appreciated.

    Thanks,
    Bobby

    #56672
    kdv
    Participant
    function runCode(app) {
      const type = v3d.Detector.checkIOS() ? 'video/mp4' : 'video/webm;codecs=avc1';
      const stream = app.renderer.domElement.captureStream(30);
      const recorder = new MediaRecorder(stream, {mimeType: type});
    
      recorder.addEventListener('dataavailable', function(e) {
        const link = document.createElement('a');
        link.href = URL.createObjectURL(e.data);
        link.download = 'video.mp4';
        document.body.appendChild(link);
        link.click();
        URL.revokeObjectURL(link.href);
        link.remove();
      });
    
      const start = document.getElementById('recordStart');
      start.addEventListener('click', function() {
        if (recorder.state == 'inactive')
          recorder.start();
      });
    
      const stop = document.getElementById('recordStop');
      stop.addEventListener('click', function() {
        if (recorder.state != 'inactive')
          recorder.stop();
      });
    }

    Puzzles and JS. Fast and expensive.

    If you don’t see the meaning in something it primarily means that you just don’t see it but not the absence of meaning at all.

    #56707
    bhobbes
    Participant

    Perfect. Thank you so much for the help.

    I plugged the code in and it didn’t seem to be working, so I put some buttons inside the project’s main html file that is being loaded into the iframe in my main html file. When I click the buttons inside the iframe it works, but not the buttons outside the iframe in the main index.html.

    The buttons in the index.html work to start the animation (I have those set up with an html “on event of” puzzle). I think I am looking for the code equivalent of ticking on the checkbox for “in parent doc” for the puzzles?

    So sorry to be a bother. I tried to look it up, but couldn’t find a suggestion that worked.

    #56708
    kdv
    Participant
      const start = parent.document.getElementById('recordStart');
      const stop = parent.document.getElementById('recordStop');

    Puzzles and JS. Fast and expensive.

    If you don’t see the meaning in something it primarily means that you just don’t see it but not the absence of meaning at all.

    #56709
    bhobbes
    Participant

    Brilliant! That worked. Thank you sooo much for your help.

    #56739
    kdv
    Participant

    One strange thing with this MediaRecorder: once created it loads CPU as if it’s already active and recording. After start() / stop() the CPU load drops down.

    Puzzles and JS. Fast and expensive.

    If you don’t see the meaning in something it primarily means that you just don’t see it but not the absence of meaning at all.

    #59324
    bhobbes
    Participant

    Thanks to your help, I was able to get this implemented and it works wonderfully. I’ve been testing on my live site and it’s going well.

    The only thing I’ve noticed is the outputted video dimensions vary randomly. I’ve spent the past week trying out different things I found online to try and force a set video width and height with the code and haven’t been able to get anything to work. It’s probably just my lack of coding knowledge, but is it not possible to force the saved video to be a specific width & height?

    #59328
    kdv
    Participant

    he outputted video dimensions vary randomly

    what do you mean? the video dimensions directly depend on the canvas/window size. The canvas is captured 1:1.

    Puzzles and JS. Fast and expensive.

    If you don’t see the meaning in something it primarily means that you just don’t see it but not the absence of meaning at all.

    #59338
    bhobbes
    Participant

    Yeah, that’s what is weird. The canvas is set at 1296×729. I opened the app and saved a bunch of videos back to back and most are saving at 1296×729, but about 1 in 3 videos save at 2073×1166.

    Not a super huge deal. I just thought it was weird and wanted to see if I could force a size on the video to keep it consistent.

    #59339
    kdv
    Participant

    Something in your logic changes the pixel ratio with the factor 1.6. Try to set the pixel ratio to 1 before recording…

    function runCode(app) {
      const type = v3d.Detector.checkIOS() ? 'video/mp4' : 'video/webm;codecs=avc1';
      const stream = app.renderer.domElement.captureStream();
      const recorder = new MediaRecorder(stream, {mimeType: type});
    
      recorder.addEventListener('dataavailable', function(e) {
        const link = document.createElement('a');
        link.href = URL.createObjectURL(e.data);
        link.download = 'video.mp4';
        document.body.appendChild(link);
        link.click();
        URL.revokeObjectURL(link.href);
        link.remove();
      });
    
      const start = parent.document.getElementById('recordStart');
      start.addEventListener('click', function() {
        if (recorder.state == 'inactive') {
          setScreenScale(1);
          setTimeout(function() {
            recorder.start();
          }, 100);
        }
      });
    
      const stop = parent.document.getElementById('recordStop');
      stop.addEventListener('click', function() {
        if (recorder.state != 'inactive')
          recorder.stop();
      });
    
      function setScreenScale(factor) {
        app.renderer.setPixelRatio(factor);
        if (app.postprocessing)
          app.postprocessing.composer.setPixelRatio(factor);
        app.onResize();
      }
    }

    Puzzles and JS. Fast and expensive.

    If you don’t see the meaning in something it primarily means that you just don’t see it but not the absence of meaning at all.

    #59344
    bhobbes
    Participant

    That did the job. Saved 10 videos back to back and they all came out the same size. Thank you very much!

Viewing 15 posts - 1 through 15 (of 15 total)
  • You must be logged in to reply to this topic.