Search code examples
windowsffmpegssim

ffmpeg: How to save SSIM and PSNR to a file?


I'm a ffmpeg newbie. I would like my script (on Windows) to output the average PSNR and average SSIM values to a file. (but not the values for every frame) I can output them to the standard output but not to a file.

I use this line:

ffmpeg -i ref.avi -i compressed.avi -lavfi  "ssim;[0:v][1:v]psnr" -f null -

I understand I have to change something here: "-f null -" , but I cannot make it work.


Solution

  • Using ssim & psnr filters

    On Linux and macOS you can use grep:

    $ ffmpeg -i compressed.avi -i reference.avi -lavfi "[0][1]ssim;[0][1]psnr" -f null - |& grep Parsed_ > ff.log
    

    Simple, but major downside is it won't show you the console output, so you may miss errors. To fix that add tee:

    $ ffmpeg -i compressed.avi -i reference.avi -lavfi "[0][1]ssim;[0][1]psnr" -f null - |& tee >(grep Parsed_ > ff.log)
    

    Example contents of ff.log from either command:

    [Parsed_ssim_0 @ 0x5579d7f17b40] SSIM Y:0.796135 (6.906565) U:0.843488 (8.054531) V:0.822424 (7.506157) All:0.820682 (7.463768)
    [Parsed_psnr_1 @ 0x5579d7f12b00] PSNR y:24.940925 u:23.938192 v:23.641771 average:24.138969 min:23.298059 max:26.880485
    
    • If you want to append to ff.log instead of overwrite use grep Parsed_ >> ff.log instead.
    • If |& does not work for you use 2>&1 instead.

    Or use libvmaf

    libvmaf filter is slower but will output a log file containing the VMAF, SSIM, and PSNR aggregate scores along with the per frame scores in XML or JSON. Your ffmpeg will need to be compiled with --enable-libvmaf to use this filter.

    ffmpeg -i compressed.avi -i reference.avi -lavfi "[0][1]libvmaf=log_path=vmaf.xml:log_fmt=xml:ssim=1:psnr=1" -f null -