Skip to content

Commit dd2c5f5

Browse files
committed
feat: add audio channels to presets
* Also fixes some issues with MPEG-DASH timings (uses avoid_negative_ts 'make_zero' instead of the asetpts filter). Refs: ARC-11152
1 parent a802096 commit dd2c5f5

File tree

6 files changed

+63
-5
lines changed

6 files changed

+63
-5
lines changed

lib/ffmpeg/presets/aac.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def aac_128k(
1313
metadata: nil,
1414
threads: FFMPEG.threads,
1515
audio_sample_rate: 48_000,
16+
audio_channels: 2,
1617
&
1718
)
1819
AAC.new(
@@ -21,6 +22,7 @@ def aac_128k(
2122
metadata:,
2223
threads:,
2324
audio_sample_rate:,
25+
audio_channels:,
2426
audio_bit_rate: '128k',
2527
&
2628
)
@@ -32,6 +34,7 @@ def aac_192k(
3234
metadata: nil,
3335
threads: FFMPEG.threads,
3436
audio_sample_rate: 48_000,
37+
audio_channels: 2,
3538
&
3639
)
3740
AAC.new(
@@ -40,6 +43,7 @@ def aac_192k(
4043
metadata:,
4144
threads:,
4245
audio_sample_rate:,
46+
audio_channels:,
4347
audio_bit_rate: '192k',
4448
&
4549
)
@@ -51,6 +55,7 @@ def aac_320k(
5155
metadata: nil,
5256
threads: FFMPEG.threads,
5357
audio_sample_rate: 48_000,
58+
audio_channels: 2,
5459
&
5560
)
5661
AAC.new(
@@ -59,6 +64,7 @@ def aac_320k(
5964
metadata:,
6065
threads:,
6166
audio_sample_rate:,
67+
audio_channels:,
6268
audio_bit_rate: '320k',
6369
&
6470
)
@@ -67,12 +73,14 @@ def aac_320k(
6773

6874
# Preset to encode AAC audio files.
6975
class AAC < Preset
70-
attr_reader :threads, :audio_bit_rate, :audio_sample_rate
76+
attr_reader :threads, :audio_bit_rate, :audio_sample_rate, :audio_channels
7177

7278
# @param name [String] The name of the preset.
7379
# @param filename [String] The filename format of the output.
7480
# @param metadata [Object] The metadata to associate with the preset.
7581
# @param audio_bit_rate [String] The audio bit rate to use.
82+
# @param audio_sample_rate [Integer] The audio sample rate to use.
83+
# @param audio_channels [Integer, nil] The number of audio channels to use (nil to preserve source).
7684
# @yield The block to execute to compose the command arguments.
7785
def initialize(
7886
name: nil,
@@ -81,11 +89,13 @@ def initialize(
8189
threads: FFMPEG.threads,
8290
audio_bit_rate: '128k',
8391
audio_sample_rate: 48_000,
92+
audio_channels: 2,
8493
&
8594
)
8695
@threads = threads
8796
@audio_bit_rate = audio_bit_rate
8897
@audio_sample_rate = audio_sample_rate
98+
@audio_channels = audio_channels
8999
preset = self
90100

91101
super(name:, filename:, metadata:) do
@@ -101,6 +111,7 @@ def initialize(
101111
map media.audio_mapping_id do
102112
audio_bit_rate preset.audio_bit_rate
103113
audio_sample_rate preset.audio_sample_rate
114+
audio_channels preset.audio_channels if preset.audio_channels
104115
end
105116
end
106117
end

lib/ffmpeg/presets/dash.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def initialize(
3131
use_template 1
3232
use_timeline 1
3333
segment_duration preset.segment_duration
34+
avoid_negative_ts 'make_zero'
3435

3536
muxing_flags 'frag_keyframe+empty_moov+default_base_moof'
3637
map_chapters '-1'

lib/ffmpeg/presets/dash/aac.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def aac_128k(
1515
threads: FFMPEG.threads,
1616
segment_duration: 4,
1717
audio_sample_rate: 48_000,
18+
audio_channels: 2,
1819
&
1920
)
2021
AAC.new(
@@ -24,6 +25,7 @@ def aac_128k(
2425
threads:,
2526
segment_duration:,
2627
audio_sample_rate:,
28+
audio_channels:,
2729
audio_bit_rate: '128k',
2830
&
2931
)
@@ -36,6 +38,7 @@ def aac_192k(
3638
threads: FFMPEG.threads,
3739
segment_duration: 4,
3840
audio_sample_rate: 48_000,
41+
audio_channels: 2,
3942
&
4043
)
4144
AAC.new(
@@ -45,6 +48,7 @@ def aac_192k(
4548
threads:,
4649
segment_duration:,
4750
audio_sample_rate:,
51+
audio_channels:,
4852
audio_bit_rate: '192k',
4953
&
5054
)
@@ -57,6 +61,7 @@ def aac_320k(
5761
threads: FFMPEG.threads,
5862
segment_duration: 4,
5963
audio_sample_rate: 48_000,
64+
audio_channels: 2,
6065
&
6166
)
6267
AAC.new(
@@ -66,6 +71,7 @@ def aac_320k(
6671
threads:,
6772
segment_duration:,
6873
audio_sample_rate:,
74+
audio_channels:,
6975
audio_bit_rate: '320k',
7076
&
7177
)
@@ -74,12 +80,14 @@ def aac_320k(
7480

7581
# Preset to encode DASH AAC audio files.
7682
class AAC < DASH
77-
attr_reader :audio_bit_rate, :audio_sample_rate
83+
attr_reader :audio_bit_rate, :audio_sample_rate, :audio_channels
7884

7985
# @param name [String] The name of the preset.
8086
# @param filename [String] The filename format of the output.
8187
# @param metadata [Object] The metadata to associate with the preset.
8288
# @param audio_bit_rate [String] The audio bit rate to use.
89+
# @param audio_sample_rate [Integer] The audio sample rate to use.
90+
# @param audio_channels [Integer, nil] The number of audio channels to use (nil to preserve source).
8391
# @yield The block to execute to compose the command arguments.
8492
def initialize(
8593
name: nil,
@@ -89,10 +97,12 @@ def initialize(
8997
segment_duration: 4,
9098
audio_bit_rate: '128k',
9199
audio_sample_rate: 48_000,
100+
audio_channels: 2,
92101
&
93102
)
94103
@audio_bit_rate = audio_bit_rate
95104
@audio_sample_rate = audio_sample_rate
105+
@audio_channels = audio_channels
96106
preset = self
97107

98108
super(
@@ -111,6 +121,7 @@ def initialize(
111121
map media.audio_mapping_id do
112122
audio_bit_rate preset.audio_bit_rate
113123
audio_sample_rate preset.audio_sample_rate
124+
audio_channels preset.audio_channels if preset.audio_channels
114125
end
115126
end
116127
end

lib/ffmpeg/presets/dash/h264.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,9 @@ def initialize(
308308
end
309309

310310
map media.audio_mapping_id do
311-
# Reset the audio stream's timestamps to start from 0.
312-
filter Filter.new(:audio, 'asetpts', expr: 'PTS-STARTPTS')
313311
audio_bit_rate h264_presets.first.audio_bit_rate
314312
audio_sample_rate h264_presets.first.audio_sample_rate
313+
audio_channels h264_presets.first.audio_channels if h264_presets.first.audio_channels
315314
end
316315
end
317316
end

lib/ffmpeg/presets/h264.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def h264_144p(
1515
threads: FFMPEG.threads,
1616
audio_bit_rate: '128k',
1717
audio_sample_rate: 48_000,
18+
audio_channels: 2,
1819
video_preset: 'ultrafast',
1920
video_profile: 'baseline',
2021
frame_rate: 30,
@@ -29,6 +30,7 @@ def h264_144p(
2930
threads:,
3031
audio_bit_rate:,
3132
audio_sample_rate:,
33+
audio_channels:,
3234
video_preset:,
3335
video_profile:,
3436
frame_rate:,
@@ -47,6 +49,7 @@ def h264_240p(
4749
threads: FFMPEG.threads,
4850
audio_bit_rate: '128k',
4951
audio_sample_rate: 48_000,
52+
audio_channels: 2,
5053
video_preset: 'ultrafast',
5154
video_profile: 'baseline',
5255
frame_rate: 30,
@@ -61,6 +64,7 @@ def h264_240p(
6164
threads:,
6265
audio_bit_rate:,
6366
audio_sample_rate:,
67+
audio_channels:,
6468
video_preset:,
6569
video_profile:,
6670
frame_rate:,
@@ -79,6 +83,7 @@ def h264_360p(
7983
threads: FFMPEG.threads,
8084
audio_bit_rate: '128k',
8185
audio_sample_rate: 48_000,
86+
audio_channels: 2,
8287
video_preset: 'ultrafast',
8388
video_profile: 'baseline',
8489
frame_rate: 30,
@@ -93,6 +98,7 @@ def h264_360p(
9398
threads:,
9499
audio_bit_rate:,
95100
audio_sample_rate:,
101+
audio_channels:,
96102
video_preset:,
97103
video_profile:,
98104
frame_rate:,
@@ -111,6 +117,7 @@ def h264_480p(
111117
threads: FFMPEG.threads,
112118
audio_bit_rate: '128k',
113119
audio_sample_rate: 48_000,
120+
audio_channels: 2,
114121
video_preset: 'fast',
115122
video_profile: 'main',
116123
frame_rate: 30,
@@ -125,6 +132,7 @@ def h264_480p(
125132
threads:,
126133
audio_bit_rate:,
127134
audio_sample_rate:,
135+
audio_channels:,
128136
video_preset:,
129137
video_profile:,
130138
frame_rate:,
@@ -143,6 +151,7 @@ def h264_720p(
143151
threads: FFMPEG.threads,
144152
audio_bit_rate: '128k',
145153
audio_sample_rate: 48_000,
154+
audio_channels: 2,
146155
video_preset: 'fast',
147156
video_profile: 'high',
148157
frame_rate: 60,
@@ -157,6 +166,7 @@ def h264_720p(
157166
threads:,
158167
audio_bit_rate:,
159168
audio_sample_rate:,
169+
audio_channels:,
160170
video_preset:,
161171
video_profile:,
162172
frame_rate:,
@@ -175,6 +185,7 @@ def h264_1080p(
175185
threads: FFMPEG.threads,
176186
audio_bit_rate: '128k',
177187
audio_sample_rate: 48_000,
188+
audio_channels: 2,
178189
video_preset: 'fast',
179190
video_profile: 'high',
180191
frame_rate: 60,
@@ -189,6 +200,7 @@ def h264_1080p(
189200
threads:,
190201
audio_bit_rate:,
191202
audio_sample_rate:,
203+
audio_channels:,
192204
video_preset:,
193205
video_profile:,
194206
frame_rate:,
@@ -207,6 +219,7 @@ def h264_1440p(
207219
threads: FFMPEG.threads,
208220
audio_bit_rate: '128k',
209221
audio_sample_rate: 48_000,
222+
audio_channels: 2,
210223
video_preset: 'fast',
211224
video_profile: 'high',
212225
frame_rate: 60,
@@ -221,6 +234,7 @@ def h264_1440p(
221234
threads:,
222235
audio_bit_rate:,
223236
audio_sample_rate:,
237+
audio_channels:,
224238
video_preset:,
225239
video_profile:,
226240
frame_rate:,
@@ -239,6 +253,7 @@ def h264_4k(
239253
threads: FFMPEG.threads,
240254
audio_bit_rate: '128k',
241255
audio_sample_rate: 48_000,
256+
audio_channels: 2,
242257
video_preset: 'fast',
243258
video_profile: 'high',
244259
frame_rate: 60,
@@ -253,6 +268,7 @@ def h264_4k(
253268
threads:,
254269
audio_bit_rate:,
255270
audio_sample_rate:,
271+
audio_channels:,
256272
video_preset:,
257273
video_profile:,
258274
frame_rate:,
@@ -267,14 +283,16 @@ def h264_4k(
267283

268284
# Preset to encode H.264 video files.
269285
class H264 < Preset
270-
attr_reader :threads, :audio_bit_rate, :audio_sample_rate, :video_preset, :video_profile,
286+
attr_reader :threads, :audio_bit_rate, :audio_sample_rate, :audio_channels, :video_preset, :video_profile,
271287
:frame_rate, :constant_rate_factor, :pixel_format,
272288
:max_width, :max_height
273289

274290
# @param name [String] The name of the preset.
275291
# @param filename [String] The filename format of the output.
276292
# @param metadata [Object] The metadata to associate with the preset.
277293
# @param audio_bit_rate [String] The audio bit rate to use.
294+
# @param audio_sample_rate [Integer] The audio sample rate to use.
295+
# @param audio_channels [Integer, nil] The number of audio channels to use (nil to preserve source).
278296
# @param video_preset [String] The video preset to use.
279297
# @param video_profile [String] The video profile to use.
280298
# @param frame_rate [Integer] The frame rate to use.
@@ -290,6 +308,7 @@ def initialize(
290308
threads: FFMPEG.threads,
291309
audio_bit_rate: '128k',
292310
audio_sample_rate: 48_000,
311+
audio_channels: 2,
293312
video_preset: 'fast',
294313
video_profile: 'high',
295314
frame_rate: 30,
@@ -310,6 +329,7 @@ def initialize(
310329
@threads = threads
311330
@audio_bit_rate = audio_bit_rate
312331
@audio_sample_rate = audio_sample_rate
332+
@audio_channels = audio_channels
313333
@video_preset = video_preset
314334
@video_profile = video_profile
315335
@frame_rate = frame_rate
@@ -340,6 +360,7 @@ def initialize(
340360
map media.audio_mapping_id do
341361
audio_bit_rate preset.audio_bit_rate
342362
audio_sample_rate preset.audio_sample_rate
363+
audio_channels preset.audio_channels if preset.audio_channels
343364
end
344365
end
345366
end

lib/ffmpeg/raw_command_args.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,21 @@ def video_quality(value, **kwargs)
583583
stream_arg('q', value, stream_type: 'v', **kwargs)
584584
end
585585

586+
# Sets the video sync in the command arguments.
587+
# This is used to synchronize audio and video streams.
588+
#
589+
# @param value [String, Numeric] The audio sync to set.
590+
# @return [self]
591+
#
592+
# @example
593+
# args = FFMPEG::RawCommandArgs.compose do
594+
# video_sync cfr
595+
# end
596+
# args.to_s # "-vsync cfr"
597+
def video_sync(value)
598+
arg('vsync', value)
599+
end
600+
586601
# Sets a frame rate in the command arguments.
587602
#
588603
# @param value [String, Numeric] The frame rate to set.

0 commit comments

Comments
 (0)