{"id":13618087,"url":"https://github.com/leandromoreira/docker-ffmpeg-vmaf","last_synced_at":"2025-10-04T00:31:18.425Z","repository":{"id":141425562,"uuid":"264296838","full_name":"leandromoreira/docker-ffmpeg-vmaf","owner":"leandromoreira","description":"Docker FFmpeg VMAF usage example / tips / workflow","archived":false,"fork":false,"pushed_at":"2021-01-05T11:34:00.000Z","size":147,"stargazers_count":26,"open_issues_count":1,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-01-13T22:50:17.412Z","etag":null,"topics":["docker","ffmpeg","ffmpeg-docker","metrics","streaming","video","vmaf","vmaf-docker"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leandromoreira.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-05-15T20:54:49.000Z","updated_at":"2024-09-14T03:47:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"952f1159-34ab-4b3d-81b4-72f4a680ce4a","html_url":"https://github.com/leandromoreira/docker-ffmpeg-vmaf","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandromoreira%2Fdocker-ffmpeg-vmaf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandromoreira%2Fdocker-ffmpeg-vmaf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandromoreira%2Fdocker-ffmpeg-vmaf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandromoreira%2Fdocker-ffmpeg-vmaf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leandromoreira","download_url":"https://codeload.github.com/leandromoreira/docker-ffmpeg-vmaf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235204541,"owners_count":18952330,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","ffmpeg","ffmpeg-docker","metrics","streaming","video","vmaf","vmaf-docker"],"created_at":"2024-08-01T20:01:54.331Z","updated_at":"2025-10-04T00:31:13.147Z","avatar_url":"https://github.com/leandromoreira.png","language":null,"funding_links":[],"categories":["HarmonyOS"],"sub_categories":["Windows Manager"],"readme":"# VMAF\n\n[VMAF](https://github.com/Netflix/vmaf) is a perceptual video quality assessment algorithm developed by **Netflix**. It seeks to reflect the viewer’s perception of the streaming quality.\n\nIt's a valuable quality metric that can be used to computerize the common media workflow quality analysis instead of relying on people's eyes.\n\nIts common usages, best practices, tips are explained here. Most of the information here is based on the [main repository](https://github.com/Netflix/vmaf) and the [latest post from Netflix](https://netflixtechblog.com/vmaf-the-journey-continues-44b51ee9ed12).\n\n# TLDR; how to use\n\n```bash\n# all commands were performed using\n# MacOS 10.15.4 - 2.3 GHz Quad-Core Intel Core i5\n# Docker Desktop 2.3.0 / 4 logical cores / 2 GB RAM\n\n# PLEASE PROVIDE two video files for comparison\n#  ref.mp4 - the reference video file\n#  distor.mp4 - the distorted videoo file (transcoded)\n# both files must be at the root where you ran these commands\n\n# analyzing all frames (from 1m 1080p video)\ntime docker run --rm -v $(pwd):/files five82/ffmpeg-git \\\n  ffmpeg -i /files/ref.mp4 -i /files/distor.mp4 \\\n  -lavfi libvmaf=log_fmt=json -f null -\n\nExec FPS: 14.318552\nVMAF score = 93.130018\n0.08s user 0.16s system 0% cpu 4:13.55 total\n\n# (QUICKER) analyzing 1 out of 5 frames (from 1m 1080p video)\ntime docker run --rm -v $(pwd):/files five82/ffmpeg-git \\\n  ffmpeg -i /files/ref.mp4 -i /files/distor.mp4 \\\n  -lavfi libvmaf=log_fmt=json:n_subsample=5 -f null -\n\nExec FPS: 58.999069\nVMAF score = 93.130807\n0.05s user 0.12s system 0% cpu 1:02.25 total\n# we make it faster (by using subsample) but the VMAF score is almost the same\n\n\n# analyzing different renditions\ndocker run --rm -v $(pwd):/files five82/ffmpeg-git \\\n  ffmpeg -i /files/ref.mp4 -i /files/distor_lower_resolution.mp4 \\\n  -filter_complex \\\n  \"[1:v]scale=1920x1080:flags=bicubic[main];[main][0:v]libvmaf=log_fmt=json:n_subsample=5\" -f null -\n\n\n```\n\n\n## Common workflow\n\nVMAF compares a reference video file against a targe one, usually, the following steps are taken:\n\n1. **fetch** the reference video file\n1. **apply transformations** to target video file\n\t* mostly: \n\t\t* transcode (changing codec),\n\t\t* transize (changing resolution), \n\t\t* and transrating (changing bitrate).\n1. run the vmaf **comparison**\n1. check the **score** (\u003e= 70 good/fair)\n1. if it's not good, go back to step 2, change the transformation's properties\n\n![workflow](/images/common_workflow.png)\n\n## Toolset\n\nAlthough VMAF can be used as standalone software, it's easier and faster to use it as a dockerized FFmpeg filter. \n\n* It's faster because it takes advantage of the FFmpeg's intermediate steps (decoding/scaling) to calc VMAF, avoiding multiple passes and unnecessary storage.\n* It's easier because it's a single step/tool process.\n\nThe docker image we're going to use for FFmpeg/VMAF is [five82/ffmpeg-git](https://github.com/five82/ffmpeg-git) and for FFmpeg/media transformation is [jrottenberg/ffmpeg](https://github.com/jrottenberg/ffmpeg).\n\n## Preping enviroment\n\nTo practice the proposed workflow, we need to have a video file, for that matter let's download the big buck bunny.\n\n```bash\n# download the file we'll use throught the examples\n# HUGE download ahead 330MB\nwget http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_60fps_normal.mp4\n\n# using \"standard\" naming\n# \u003cname/id\u003e_\u003cduration in s\u003e_\u003cfps\u003e_\u003cheight\u003e_\u003cbitrate in k\u003e.\u003cformat\u003e\nmv bbb_sunflower_1080p_60fps_normal.mp4 bunny_634s_60fps_1080p_4487kb.mp4\n```\n\nWorking with a 10m video long, for learning purpose, might be slow/boring, let's generate an 1m short clip.\n\n```bash\n# generating a random 1 minute short clip\n# not changing codec though\ndocker run --rm -v $(pwd):/files jrottenberg/ffmpeg  \\\n  -i /files/bunny_634s_60fps_1080p_4487kb.mp4 \\\n  -ss 00:01:24 -t 00:01:00 -c copy \\\n  /files/bunny_60s_60fps_1080p_4487kb.mp4\n\n```\n\n## Getting the reference\n\nThe reference file `bunny_60s_60fps_1080p_4487kb.mp4` has the following properties.\n\n| Property   |      Value      |\n|----------|:-------------:|\n| codec |  h264 |\n| bitrate |    4487 Kb   |\n| resolution | 1080p |\n| container |  mp4 |\n| duration |  10s |\n\n\n## Applying transformations\n\nToward to deliver video for all devices in diverse network conditions, the media needs to pass through some transformations, mostly related to the number of bits required and the resolution.\n\n#### Transrating\n\n```bash\n# same resolution but different bit rate\ndocker run --rm -v $(pwd):/files jrottenberg/ffmpeg  \\\n  -i /files/bunny_60s_60fps_1080p_4487kb.mp4 \\\n  -c:v libx264 -crf 23 -maxrate 2M -bufsize 4M \\\n  /files/bunny_60s_60fps_1080p_2000kb.mp4\n```\n| Property   |      Value      |\n|----------|:-------------:|\n| codec |  h264 |\n| bitrate |    2000 Kb   |\n| resolution | 1080p |\n| container |  mp4 |\n| duration |  10s |\n\n\n#### Transizing\n\n```bash\n# changing resolution\ndocker run --rm -v $(pwd):/files jrottenberg/ffmpeg \\\n  -i /files/bunny_60s_60fps_1080p_4487kb.mp4 \\\n  -vf scale=640:-1 -sws_flags lanczos \\\n  -c:v libx264 -crf 23 -maxrate 600k -bufsize 1200k \\\n  /files/bunny_60s_60fps_640p_600kb.mp4\n```\n\n| Property   |      Value      |\n|----------|:-------------:|\n| codec |  h264 |\n| bitrate |    600 Kb   |\n| resolution | 640p |\n| container |  mp4 |\n| duration |  10s |\n\n\n## Run VMAF\n\n### All frames - slower\n```bash\ntime docker run --rm -v $(pwd):/files five82/ffmpeg-git \\\n  ffmpeg -i /files/bunny_60s_60fps_1080p_4487kb.mp4 \\\n   -i /files/bunny_60s_60fps_1080p_2000kb.mp4 \\\n   -lavfi libvmaf=log_fmt=json -f null -\n\nExec FPS: 14.318552\nVMAF score = 93.130018\n0.08s user 0.16s system 0% cpu 4:13.55 total\n```\n### Subsampling frames - faster (1 out of 5)\n```bash\ntime docker run --rm -v $(pwd):/files five82/ffmpeg-git \\\n  ffmpeg -i /files/bunny_60s_60fps_1080p_4487kb.mp4 \\\n   -i /files/bunny_60s_60fps_1080p_2000kb.mp4 \\\n  -lavfi libvmaf=log_fmt=json:n_subsample=5 -f null -\n\nExec FPS: 58.999069\nVMAF score = 93.130807\n0.05s user 0.12s system 0% cpu 1:02.25 total\n```\n\nFaster (almost 4x) and still kept the close VMAF score.\n\n### Different resolution\n\n```bash\ntime docker run --rm -v $(pwd):/files five82/ffmpeg-git \\\n  ffmpeg -i /files/bunny_60s_60fps_1080p_4487kb.mp4 \\\n  -i /files/bunny_60s_60fps_640p_600kb.mp4 \\\n  -filter_complex \\\n  \"[1:v]scale=1920x1080:flags=bicubic[main];[main][0:v]libvmaf=log_fmt=json:n_subsample=5\" -f null -\n\n```\n\n### How about different container check?\nYou need to conform the timing information.\n\n```bash\ndocker run --rm -v $(pwd):/files jrottenberg/ffmpeg -w /files \\\n  -i main.mpg -i ref.mkv \\\n  -lavfi \"[0:v]settb=AVTB,setpts=PTS-STARTPTS[main];[1:v]settb=AVTB,setpts=PTS-STARTPTS[ref];[main][ref]libvmaf=psnr=1:log_fmt=json\" -f null -\n```\nExample taken from [FFmpeg's site](https://ffmpeg.org/ffmpeg-all.html#Examples-115).\n### Does it work for mobile, 4k view port?\n\nFor [4k, you can check FAQ](https://github.com/Netflix/vmaf/blob/master/FAQ.md#q-will-vmaf-work-on-4k-videos) and for mobile you can [check the available models](https://github.com/Netflix/vmaf/blob/master/resource/doc/models.md#predict-quality-on-a-cellular-phone-screen).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandromoreira%2Fdocker-ffmpeg-vmaf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleandromoreira%2Fdocker-ffmpeg-vmaf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandromoreira%2Fdocker-ffmpeg-vmaf/lists"}