blob: 4ad374a2477e682810b5c6842c83f6efb7646faa
1 | #!/usr/bin/env ruby |
2 | |
3 | require 'open3' |
4 | require 'json' |
5 | |
6 | ffmpeg_bin = 'ffmpeg' |
7 | target_il = -24.0 |
8 | target_lra = +11.0 |
9 | target_tp = -2.0 |
10 | samplerate = '48k' |
11 | |
12 | if ARGF.argv.count != 2 |
13 | puts "Usage: #{$PROGRAM_NAME} input.wav output.wav" |
14 | exit 1 |
15 | end |
16 | |
17 | ff_cmd = Array.new([ |
18 | ffmpeg_bin, |
19 | '-hide_banner', |
20 | '-i', ARGF.argv[0], |
21 | '-af', "loudnorm='I=#{target_il}:LRA=#{target_lra}:tp=#{target_tp}:print_format=json'", |
22 | '-f', 'null', |
23 | '-']); |
24 | |
25 | _stdin, _stdout, stderr, wait_thr = Open3.popen3(*ff_cmd) |
26 | |
27 | if wait_thr.value.success? |
28 | stats = JSON.parse(stderr.read.lines[-12, 12].join) |
29 | loudnorm_string = 'loudnorm=' |
30 | loudnorm_string += 'print_format=summary:' |
31 | loudnorm_string += 'linear=true:' |
32 | loudnorm_string += "I=#{target_il}:" |
33 | loudnorm_string += "LRA=#{target_lra}:" |
34 | loudnorm_string += "tp=#{target_tp}:" |
35 | loudnorm_string += "measured_I=#{stats['input_i']}:" |
36 | loudnorm_string += "measured_LRA=#{stats['input_lra']}:" |
37 | loudnorm_string += "measured_tp=#{stats['input_tp']}:" |
38 | loudnorm_string += "measured_thresh=#{stats['input_thresh']}:" |
39 | loudnorm_string += "offset=#{stats['target_offset']}" |
40 | else |
41 | puts stderr.read |
42 | exit 1 |
43 | end |
44 | |
45 | ff_cmd = Array.new([ |
46 | ffmpeg_bin, |
47 | '-y', '-hide_banner', |
48 | '-i', ARGF.argv[0], |
49 | '-af', loudnorm_string, |
50 | '-ar', samplerate, |
51 | ARGF.argv[1].to_s]); |
52 | |
53 | _stdin, _stdout, stderr, wait_thr = Open3.popen3(*ff_cmd) |
54 | |
55 | if wait_thr.value.success? |
56 | puts stderr.read.lines[-12, 12].join |
57 | exit 0 |
58 | else |
59 | puts stderr.read |
60 | exit 1 |
61 | end |
62 |