8

I have several recordings of lectures, some with powerpoint slides, some with writing on a blackboard. They are several GBytes each. However most of the time the video is a still image (besides maybe some movements of people, occasional shaking/adjustment of the camera).

How can I compress the video effectively without loosing sharpness and the audio? I thought about making the frame rate super low (say 1fps, or even less). Even better would of course be something that analyzes the change in the image and only updates if the image changed by a certain amount.

The output format doesn't necessarily need to be a video, something like a html format or a ppt/libreoffice presentation would be fine too. However the Audio should be in sync with the images, and it should not require an exotic software to play it back.

I think I could program something that does the job, but I would really prefer to just use an existing software, dump my video file into it and get the result out. Who has suggestions? Did anybody try something similar? Cross-platform or Linux solutions are preferred :)

2 Answers 2

4

Modern video codecs are already very good at dealing with temporal redundancy. You probably don't need to do anything extra unless you're targetting an extremely low bitrate. You could probably go down to 10fps without having things look bad, and that should help.

I guess you want to leave the resolution fairly high, so it's easy to read the chalk board. Downscale to maybe 720p or even 480p. Unless you have a really fancy camera, there will probably be noise in the images, and the noise is input data that a video codec will try to faithfully reproduce, costing more bitrate. So downscale as much as you can without starting to lose useful detail, to minimize the non-useful detail in the input. e.g. -vf scale=-1:480 to scale to 480 pixels high, with width to keep aspect ratio the same.

Capture something high bitrate / high quality, then take it home and

ffmpeg -i input.mp4 -c:a opus -b:a 40k -pix_fmt yuv420p -c:v libx264 -preset slower -x264-params keyint=1000:nr=200 -crf 25 output.mkv

(links to docs in Professor Sparkles' answer.)

Use a higher crf for less quality / smaller files. Using a denoise filter on the input before feeding it to x264 could help, too, or just use x264's builtin noise reduction. (which is done in a way that will help compression the most).

Adjust the target bitrate for opus if you want more audio quality. 40kib/s should be ok for speech. If your video player will only seek to keyframes (instead of decoding to the seek target from the previous keyframe), you might find keyint=1000 is a bit too high.

You could play around with -vf mpdecimate to make VFR video and not even send similar frames to the encoder, that doesn't save much unless you turn up the similarity threshold to the point where the video would look like it got stuck for a sec. Or if motion smoothness isn't important, you could use -vf framestep=2 to drop every other frame. And then I think you need to use -r 15 if your input was 30fps, or ffmpeg will be confused.

x265 takes way more CPU to encode and play back, but looks even better than x264.

VP9 is also an option. I was just looking at it, and there's a --enable-vp9-temporal-denoising build option. That might help vp9 decide that the differences between frames in much of the picture are just noise, and not encode them at all.

1
  • Update: downscaling isn't always best. Especially with x265, keeping the important details spread out over more pixels makes the codec keep them better. Unless the video is really noisy, often best to leave at native resolution and let the codec decide which detail to discard as you lower the bitrate / raise the CRF. (Of course, encoding goes much faster at lower resolution.) But if you do downscale, use a scaler that doesn't introduce extra ringing by sharpening. e.g. bicubic, not lanczos. Commented Nov 18, 2020 at 19:09
3

H264 is actually a pretty good codec for such content. Its based on motion vectors and you can define in which intervals the codec should encode a full frame, everything in between will be based on the last and next keyframe (simplifying here).

x264 is probably the best h264 encoder out there and luckily open source. Probably the best way to use it is through ffmpeg (open source, cross-plattform). Here is a good general guide for x264 and ffmpeg: https://trac.ffmpeg.org/wiki/Encode/H.264 Especially take a look at the -tune option, it has a preset for still images, so perfect for you.

And this guide shows some of the advanced options like keyframes/GOPs. https://sites.google.com/site/linuxencoding/x264-ffmpeg-mapping

1
  • -tune stillimage is not for low-motion video, it's for using x264 to compress possibly a single high-quality image from a non-video camera. It just sets -aq-strength 1.2 --deblock -3:-3 --psy-rd 2.0:0.7 Human visual perception works a little differently when studying a single frame in detail, vs. a changing video. Commented Jan 15, 2015 at 14:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.