How to Parse FFmpeg VMAF XML and JSON Output
Assessing video quality using FFmpeg’s VMAF (Video Multi-Method Assessment Fusion) filter is standard practice, but analyzing the resulting XML or JSON log files requires proper parsing techniques. This article provides a straightforward guide on how to extract overall and frame-by-frame VMAF scores from both XML and JSON output files using Python, helping you automate your video quality analysis pipeline.
Generating the VMAF Log Files
To parse the output, you first need to generate it using FFmpeg. You
can specify the output format (xml or json)
and the file path using the log_fmt and
log_path parameters inside the libvmaf
filter:
# Generate JSON output
ffmpeg -i distorted.mp4 -i reference.mp4 -filter_complex "libvmaf=log_path=vmaf_report.json:log_fmt=json" -f null -
# Generate XML output
ffmpeg -i distorted.mp4 -i reference.mp4 -filter_complex "libvmaf=log_path=vmaf_report.xml:log_fmt=xml" -f null -Parsing VMAF JSON Output
JSON is the recommended format for parsing because of its native
compatibility with modern programming languages. The VMAF JSON file
contains a pooled_metrics object for overall scores and a
frames array for individual frame scores.
Here is a Python script to parse the JSON file and extract both the mean (global) VMAF score and the frame-by-frame scores:
import json
def parse_vmaf_json(filepath):
with open(filepath, 'r') as file:
data = json.load(file)
# Extract global pooled VMAF score
# Note: Depending on the libvmaf version, the keys might slightly differ
vmaf_metrics = data.get('pooled_metrics', {}).get('vmaf', {})
mean_score = vmaf_metrics.get('mean')
min_score = vmaf_metrics.get('min')
print(f"--- Global Metrics ---")
print(f"Mean VMAF: {mean_score}")
print(f"Min VMAF: {min_score}\n")
print(f"--- Frame-by-Frame Metrics (First 5 Frames) ---")
frames = data.get('frames', [])
for frame in frames[:5]:
frame_num = frame.get('frameNum')
vmaf_score = frame.get('metrics', {}).get('vmaf')
print(f"Frame {frame_num}: VMAF = {vmaf_score}")
# Usage
parse_vmaf_json('vmaf_report.json')Parsing VMAF XML Output
If your workflow requires XML, you can parse it using standard XML
library parsers like Python’s xml.etree.ElementTree. The
XML file lists individual frames as <frame> elements
and pooled metrics inside <pooled_metrics>
elements.
Here is a Python script to parse the XML file:
import xml.etree.ElementTree as ET
def parse_vmaf_xml(filepath):
tree = ET.parse(filepath)
root = tree.getroot()
# Extract global pooled VMAF score
print(f"--- Global Metrics ---")
# Locate the metric tag where the name attribute is 'vmaf'
for metric in root.findall(".//pooled_metrics/metric"):
if metric.get('name') == 'vmaf':
print(f"Mean VMAF: {metric.get('mean')}")
print(f"Min VMAF: {metric.get('min')}\n")
print(f"--- Frame-by-Frame Metrics (First 5 Frames) ---")
# Locate individual frame tags
frames = root.findall(".//frames/frame")
for frame in frames[:5]:
frame_num = frame.get('frameNum')
vmaf_score = frame.get('vmaf')
print(f"Frame {frame_num}: VMAF = {vmaf_score}")
# Usage
parse_vmaf_xml('vmaf_report.xml')