SoupOrWorm's Forum Posts

  • This works fine for me?

    Can you send me that project file? I don't know why it isnt working for me.

  • Yeah, I think I have everything figured out but how to play a video in-game from VideoRecorder.RecordingURL without downloading it. Is this possible?

  • No idea, I'd have to try the project. A different although silly idea I had was to record 30 videos at the same time, all offset by 1 second. So when a highlight is requested you can just save the most recent one. But that's kind of an absurd solution.

    I also found some js implementations of ffmpeg, perhaps something could be done with this?

    1. Here is the project file: dropbox.com/scl/fi/pfykdekmpj93dgk2gh97w/snapshot-project-test.c3p

    2. That actually could work... I'm just wondering what would be the best for performance and it's probably not that lol

    3. I actually wondered if there would be any way to use ffmpeg, but I doubt I could figure out how to use it.

  • I think I'm onto something here, but the video isn't playing. Feedback?

  • Wait. I have an idea for how to stitch together the clips. What if I recorded the 30 1-second chucks in arrays (as shown in my demo project from earlier) and then had construct 3 play those clips back-to-back while I recorded the screen. Then I download the recording of the clips playing. Ima try this out...

  • I gave my idea a shot but unfortunately I'm running into the issue that I cannot just discard older chunks. I'm assuming the first chunk aka the beginning contains some vital information/header, so the recording gets corrupted once the 30 second mark is passed because that first chunk gets removed. Keeping it also does not properly work and just creates some nice visual glitches in the resulting video if it works at all.

    I found very little information on this and no real solutions. Not sure if there is some kind of magic one could employ to get this to work. The only possible solution I saw (although in a different context) was this stackoverflow.com/questions/42127276/trim-or-cut-audio-recorded-with-mediarecorder-js

    But I have no clue how to actually implement this since it's for audio and not video.

    I can't post the c3p right now but here's the relevant js code which almost works but alas.

    > 	export class ReplaySystem {
    	constructor() {
    		this.stream = document.querySelector("canvas").captureStream();
    		this.highlightDuration = 10;
    		
    		this.mediaRecorder = new MediaRecorder(this.stream, {"mimeType": "video/webm"});
    		this.mediaRecorder.ondataavailable = this.dataAvailable.bind(this);
    		
    		this.replay = [];
    	}
    	
    	startRecording() {
    		this.mediaRecorder.start(1000);
    		console.log("Recording started");
    	}
    	
    	stopRecording() {
    		this.mediaRecorder.stop();
    		this.replay = [];
    		console.log("Recording stopped");	
    	}
    	
    	addChunk(chunk) {
    		this.replay.push(chunk);
    		if(this.replay.length > this.highlightDuration) {
    			this.replay.shift();
    		}
    	}
    	
    	dataAvailable(ev) {
    		this.addChunk(ev.data);
    	}
    	
    	captureHighlight(runtime) { 
    		const highlight = new Blob(this.replay, {type: 'video/webm'});
    		const url = URL.createObjectURL(highlight);
    		
    		runtime.callFunction("downloadHighlight", url);
    	}
    }
    

    Yeah, I don't know JS so I can't provide much feedback, but thanks for trying it out. I suppose if this doesn't work I can just make a system where the game records a whole level/session automatically, and you can use a button to download the recorded clip, but that isn't as cool in my opinion so I'll keep my eyes open for a solution.

  • > Interesting idea. That sounds more feasible, but I still need to figure out: 1. How to avoid bombarding the player with download requests, 2. Performance, and 3. How to stitch together the recordings. I'll see what I can do.

    I don't think you need to bombard the player - I was thinking that you might be able to use the AJAX plugin to read the recorded video via its URL. From that plugin's page:

    > Binary data

    > The AJAX object can receive resources as binary, and also post binary data, using the Binary Data object. This is also useful to fetch local resources like canvas snapshot URLs or video recording URLs, and load them in to a Binary Data object to do something else with them, like save it to storage or upload it to a server.

    So:

    1. Create an array with 30 entries
    2. Record 1 second
    3. Store its URL in the array
    4. Delete the last entry (i.e. the 31st) every time a new video is logged
    5. Player clicks the download button
    6. Loop through the 30 entries in the array
    7. Use the AJAX plugin to retrieve each clip via its URL
    8. Some magic here to stitch all the clips together (might need raw JavaScript)
    9. Serve the resulting 30 clip to the user as a download

    That might solve the problem of not wanting to prompt the user to download every video, but you might have a similar problem requesting permission to start the recording. This is from the Video Recorder manual:

    > For security reasons, browsers will prompt the user before the recording starts. To avoid the prompt annoying users, this action may only be allowed in a user input trigger, e.g. On button clicked, On touch start etc.

    And I'm not exactly sure what that implies!

    >

    Thanks for the feedback. I used the list to make a system in a test project that downloads all of the last 30 second clips, but it keeps giving "check internet access" errors, and I still need a way to stich them together (both issues may be related, as the constant downloads may be causing the error while only downloading one file may not).

    I've looked around a bit and I think your best bet is to go the javascript route. It might not be as hard as it seems at first.

    Use the mediarecorder api, which I assume is what the plugin also uses under the hood

    https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder

    Specifically note this part

    > MediaRecorder.start()

    > Begins recording media; this method can optionally be passed a timeslice argument with a value in milliseconds. If this is specified, the media will be captured in separate chunks of that duration, rather than the default behavior of recording the media in a single large chunk.

    So you can specifiy to automatically record chunks of 1 second. Every second from then on will fire the dataavailable event.

    Within this event you can store the created data chunks however you please (e.g. an array of 30 for 30 seconds of recording)

    Then when the user requests the highlight you can combine them like so (and I think this should generate a blob url that you can then invoke a download on)

    > function play() {
    var superBuffer = new Blob(recordedChunks);
    }

    It's basically what citron2010 suggested but handling it in js is going to be much easier than doing some roundabout way in events.

    EDIT: It should also avoid the issue with requesting permission. This should only request permission once, when the recording starts. After that it's just a continous recording, that you can tap in at any given moment to extract the last 30 seconds from.

    Yeah I feared that the use of JS may be inevitable. I have very little experience with text-based coding, but I suppose I can try. I think that if I can use both event sheets (for the main code) and JS (for stitching the files together) I may be able to make it work.

    If anyone wants to see what I have or try a solution themselves here is the sample file: drive.google.com/file/d/1q1x6LwLyEeOzNXZGZTuas6cDnQT5RUMS/view

  • I’m wondering whether you could record in 1 second chunks, delete any older than 30 seconds, then stitch together the last 30 when the user makes the request. No idea if it’s possible though!

    Interesting idea. That sounds more feasible, but I still need to figure out: 1. How to avoid bombarding the player with download requests, 2. Performance, and 3. How to stitch together the recordings. I'll see what I can do.

  • This may be a bit hard to explain so bear with me.

    I want to add a system to my game where if you press a button on the keyboard, it downloads a video clip of the last 30 seconds of gameplay, similar to if you hold the snapshot button on the nintendo switch for a second.

    My idea for how this could work is by using the Video Recorder plugin, I continuously record footage of the game and continuously delte everything 30 seconds or earlier from the present time (or maybe delete it just when you save the video), and then have a button download the 30 second clip. The problem is that I don't know how to delete certain parts of the video.

    So far I have this basic recording system:

    Any ideas?

    Tagged:

  • Hey there. For about 2 years now I've been working on an aquatic metroidvania called 5 Star Fishy. It is about a tiny pink fishy venturing down to the bottom of the ocean on a quest to find the sunken nuclear silo and get revenge on the world for it's neglect.

    Along the way you must rampage through various machines, hazards, and the ocean's wildlife. In doing so you will unlock abilities, meet various creatures, and face off against bosses.

    If that sounds intresting, or you want to support my first commerical game project, be sure to wishlist it on Steam: https://store.steampowered.com/app/2371040/5_Star_Fishy/

    Thanks for reading!

  • Another update: It works now! I have no idea what I changed to make it work, but it works!

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Update: After manually editing the contents of the file it seems to load correctly, so I think it is an issue with saving it.

  • Yes, or at least a screenshot showing their parent events and event numbers.

    That may be the issue because that is all of the code that directly uses the options-saving system in the whole project (none of the events I've shown have any other condition or action, and using debug layout I know that the options works for setting the dictionary to what it should be, and that the game uses the dictionary to apply the settings properly, so it is 100% an issue with the .json save load system).

    Am I missing something in the system?

  • Did you check if the file is being created?

    I hope the events on your first screenshot (Main Menu) are sub-events under some trigger. Because otherwise they will be running on every tick, constantly reading and overwriting the file, which may explain why it's empty.

    Can you make a bigger screenshot showing all these events at once? It's impossible to tell what can be wrong by those fragments.

    Do you mean the full event sheets? I'm a bit confused with what you are asking.

  • When stuck, check the manual:

    https://www.construct.net/en/make-games/manuals/construct-3/plugin-reference/nw-js

    You can't read files like that. Use NWJS.ReadFile expression:

    Dictionary load from JSON string NWJS.ReadFile(path_to_the_file)

    But first you probably need to check if the file exists using NWJS Path Exists condition.

    And definitely don't do this on every tick!

    Thanks for the response. Using your feedback I've changed the code to this:

    (Main Menu)

    (Options)

    (Game)

    However, it still isnt working as I hoped. Looking at Debug Layout shows that the dictionary adds/changes the keys sucessfully, but the json file itself looks like this and isnt working to save/load the options:

    Also, I am uploading to Steam if that changes anything. The dictionary doesnt even seem to work at all in steam, and the json file still doesnt update.