Skip to content

Instantly share code, notes, and snippets.

@agrathwohl
Last active December 13, 2022 10:37
Show Gist options
  • Select an option

  • Save agrathwohl/de196546f748ede5b7c5 to your computer and use it in GitHub Desktop.

Select an option

Save agrathwohl/de196546f748ede5b7c5 to your computer and use it in GitHub Desktop.
Using fluent-ffmpeg to quickly create an MP4->WebM transcode with VP8 video. Adds the psnr flag so that we can get the transcode's peak signal-to-noise ratio. Any result greater than 35dB would be acceptable for most streaming use cases.
[fluent_ffmpeg] node ffmpeg.js
ffmpeg version N-75369-g5ba811b Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 5.2.0 (GCC)
configuration: --prefix=/usr --shlibdir=/usr/lib --pkg-config-flags=--static --disable-static --enable-gpl --enable-gnutls --enable-libass --enable-libfdk-aac --enable-libfreetype --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-nonfree --enable-shared --enable-x11grab
libavutil 55. 2.100 / 55. 2.100
libavcodec 57. 2.100 / 57. 2.100
libavformat 57. 2.100 / 57. 2.100
libavdevice 57. 0.100 / 57. 0.100
libavfilter 6. 4.100 / 6. 4.100
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.100 / 2. 0.100
libpostproc 54. 0.100 / 54. 0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'http://grathwohl.me/futbol.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf55.33.100
Duration: 00:00:11.52, start: 0.021333, bitrate: 1586 kb/s
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 854x480 [SAR 1280:1281 DAR 16:9], 1491 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(por): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 92 kb/s (default)
Metadata:
handler_name : SoundHandler
[libvpx @ 0x27968e0] v1.4.0
[libopus @ 0x2c99320] No bit rate set. Defaulting to 96000 bps.
Output #0, webm, to 'futbol.webm':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf57.2.100
Stream #0:0(und): Video: vp8 (libvpx), yuv420p, 854x480 [SAR 1280:1281 DAR 16:9], q=-1--1, 1000 kb/s, 23.98 fps, 1k tbn, 23.98 tbc (default)
Metadata:
handler_name : VideoHandler
encoder : Lavc57.2.100 libvpx
Stream #0:1(por): Audio: opus (libopus), 48000 Hz, stereo, flt, 96 kb/s (default)
Metadata:
handler_name : SoundHandler
encoder : Lavc57.2.100 libopus
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> vp8 (libvpx))
Stream #0:1 -> #0:1 (aac (native) -> opus (libopus))
Press [q] to stop, [?] for help
frame= 276 fps= 33 q=0.0 LPSNR=Y:42.34 U:45.34 V:45.35 *:43.13 size= 1614kB time=00:00:11.55 bitrate=1144.5kbits/s
video:1462kB audio:146kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.404469%
Processing finished.
This WebM transcode scored a PSNR of:
43.13dB
var ffmpeg = require('fluent-ffmpeg');
var vp8_webm = ffmpeg('http://grathwohl.me/futbol.mp4').videoCodec('libvpx') //libvpx-vp9 could be used too
.videoBitrate(1000, true) //Outputting a constrained 1Mbit VP8 video stream
.outputOptions(
'-minrate', '1000',
'-maxrate', '1000',
'-threads', '3', //Use number of real cores available on the computer - 1
'-flags', '+global_header', //WebM won't love if you if you don't give it some headers
'-psnr') //Show PSNR measurements in output. Anything above 40dB indicates excellent fidelity
.on('progress', function(progress) {
console.log('Processing: ' + progress.percent + '% done');
})
.on('error', function(err) {
console.log('An error occurred: ' + err.message);
})
.on('end', function(err, stdout, stderr) {
console.log(stdout);
console.log('Processing finished.');
var regex = /LPSNR=Y:([0-9\.]+) U:([0-9\.]+) V:([0-9\.]+) \*:([0-9\.]+)/
var psnr = stdout.match(regex);
console.log('This WebM transcode scored a PSNR of: ');
console.log(psnr[4] + 'dB');
})
.save('futbol.webm');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment