I've been using the retroarch front-end for emulators and its built-in recording feature. It's very easy to use, works on a wide variety of emulator cores, and produces lossless quality videos. One flaw is that not all of its emulator cores support the recording function - for example, last I checked you can't use it to record mega drive games. For systems retroarch's recording doesn't work on, I recommend using OBS instead. Another flaw in retroarch is that it has a bit of a problem with audio desync. More on that later.
In retroarch's recording options, choose lossless quality. In directory options, set where you want the video file to go, and in input options set up a button to toggle recording. Record the game at its native resolution - you can play the game upscaled and still record at native resolution. Upscaling the recording in retroarch works well but is very resource-intensive and we can upscale it ourselves later. Start the game, press the record hotkey once and then press it again when you're done. I recommend starting your recording early and ending it late since it's easy to cut out unwanted parts later.
This next part was recommended to me by Perikles. Grab virtualdub, a freeware video editor. Use its rescale video filter to increase your resolution to whatever you want it to be. Nearest neighbor scaling is generally best for upscaling pixel art so go with that. I always upscale by an integer amount (eg 200%, 300%, 400%...). Select which frame rate you want to use, by default it should be the same as your recording, which is generally what you want. If you want to trim part of your video, select the first frame you want to keep and press home, then click the last frame you want and press end. If your video has gradual audio desync, which sometimes happens with retroarch, we can fix that in virtualdub. Select audio->full processing mode, then audio->use advanced filtering, and then audio->filters. Make sure auto-connect is checked and then add an input, time stretch, and output filter in that order. Edit the time stretch filter to fix the audio desync. Use a higher value if audio plays early and a lower value if the audio plays late. My experience is that going from 1 to 1.0001 fixes retroarch's desync perfectly but it's possible that different cores or different games will have different amounts of desync. Once you've done all that, save the avi. Note that if you're saving in lossless quality, the resulting video file will probably be huge, on the order of hundreds of gigabytes.
Now that we've got a good upscaled and synced recording, we need to do something about that absurd file size. For the final step, we'll download handbrake, another freeware program. Open your avi, choose which format you want to save as, what framerate you want, what resolution you want, and what video quality you want. You can downscale here if you want a specific resolution. Higher quality will mean a bigger file size, of course, the default looks plenty good to me. I recommend turning off handbrake's various filters. Once everything's set up, save your video. The resulting file should be fairly small, maybe 2 GB per hour with high quality settings.
Both virtualdub and handbrake can take an hour or more to do their processing, but the amount of time you the user have to spend on all of this is just a few minutes.