@@ -3,9 +3,8 @@ defmodule Membrane.Transcoder.Audio do
3
3
4
4
import Membrane.ChildrenSpec
5
5
require Membrane.Logger
6
- alias Membrane . { AAC , ChildrenSpec , Opus , RawAudio , RemoteStream }
6
+ alias Membrane . { AAC , ChildrenSpec , MPEGAudio , Opus , RawAudio , RemoteStream }
7
7
8
- @ opus_sample_rate 48_000
9
8
@ aac_sample_rates [
10
9
96_000 ,
11
10
88_200 ,
@@ -21,13 +20,31 @@ defmodule Membrane.Transcoder.Audio do
21
20
8000
22
21
]
23
22
24
- @ type audio_stream_format :: AAC . t ( ) | Opus . t ( ) | RawAudio . t ( )
23
+ @ type audio_stream_format :: AAC . t ( ) | Opus . t ( ) | Membrane.MPEGAudio . t ( ) | RawAudio . t ( )
25
24
26
25
defguard is_audio_format ( format )
27
26
when is_struct ( format ) and
28
- ( format . __struct__ in [ AAC , Opus , RawAudio ] or
29
- ( format . __struct__ == RemoteStream and format . content_format == Opus and
30
- format . type == :packetized ) )
27
+ ( format . __struct__ in [ AAC , Opus , MPEGAudio , RawAudio ] or
28
+ ( format . __struct__ == RemoteStream and
29
+ format . content_format == Opus and
30
+ format . type == :packetized ) or
31
+ ( format . __struct__ == RemoteStream and format . content_format == MPEGAudio ) )
32
+
33
+ defguard is_opus_compliant ( format )
34
+ when is_map_key ( format , :content_type ) and format . content_type == :s16le and
35
+ is_map_key ( format , :sample_rate ) and format . sample_rate == 48_000
36
+
37
+ defguard is_aac_compliant ( format )
38
+ when is_map_key ( format , :content_type ) and format . content_type == :s16le and
39
+ is_map_key ( format , :sample_rate ) and format . sample_rate in @ aac_sample_rates
40
+
41
+ defguard is_mp3_compliant ( format )
42
+ when is_map_key ( format , :sample_rate ) and format . sample_rate == 44_100 and
43
+ is_map_key ( format , :sample_format ) and format . sample_format == :s32le and
44
+ is_map_key (
45
+ format ,
46
+ :channels
47
+ ) and format . channels == 2
31
48
32
49
@ spec plug_audio_transcoding (
33
50
ChildrenSpec . builder ( ) ,
@@ -99,34 +116,50 @@ defmodule Membrane.Transcoder.Audio do
99
116
builder |> child ( :aac_decoder , AAC.FDK.Decoder )
100
117
end
101
118
119
+ defp maybe_plug_decoder ( builder , % MPEGAudio { } ) do
120
+ builder |> child ( :mp3_decoder , Membrane.MP3.MAD.Decoder )
121
+ end
122
+
123
+ defp maybe_plug_decoder ( builder , % RemoteStream { content_format: MPEGAudio } ) do
124
+ builder |> child ( :mp3_decoder , Membrane.MP3.MAD.Decoder )
125
+ end
126
+
102
127
defp maybe_plug_decoder ( builder , % RawAudio { } ) do
103
128
builder
104
129
end
105
130
106
- defp maybe_plug_resampler ( builder , % { sample_rate: sample_rate } = input_format , % Opus { } )
107
- when sample_rate != @ opus_sample_rate do
131
+ defp maybe_plug_resampler ( builder , input_format , % Opus { } )
132
+ when not is_opus_compliant ( input_format ) do
108
133
builder
109
134
|> child ( :resampler , % Membrane.FFmpeg.SWResample.Converter {
110
135
output_stream_format: % RawAudio {
111
136
sample_format: :s16le ,
112
- sample_rate: @ opus_sample_rate ,
113
- channels: input_format . channels
137
+ sample_rate: 48_000 ,
138
+ channels: 1
114
139
}
115
140
} )
116
141
end
117
142
118
- defp maybe_plug_resampler ( builder , % { sample_rate: sample_rate } = input_format , % AAC { } )
119
- when sample_rate not in @ aac_sample_rates do
143
+ defp maybe_plug_resampler ( builder , input_format , % AAC { } )
144
+ when not is_aac_compliant ( input_format ) do
120
145
builder
121
146
|> child ( :resampler , % Membrane.FFmpeg.SWResample.Converter {
122
147
output_stream_format: % RawAudio {
123
148
sample_format: :s16le ,
124
149
sample_rate: 44_100 ,
125
- channels: input_format . channels
150
+ channels: 1
126
151
}
127
152
} )
128
153
end
129
154
155
+ defp maybe_plug_resampler ( builder , input_format , % MPEGAudio { } )
156
+ when not is_mp3_compliant ( input_format ) do
157
+ builder
158
+ |> child ( :resampler , % Membrane.FFmpeg.SWResample.Converter {
159
+ output_stream_format: % RawAudio { sample_rate: 44_100 , sample_format: :s32le , channels: 2 }
160
+ } )
161
+ end
162
+
130
163
defp maybe_plug_resampler ( builder , _input_format , _output_format ) do
131
164
builder
132
165
end
@@ -139,6 +172,10 @@ defmodule Membrane.Transcoder.Audio do
139
172
builder |> child ( :aac_encoder , AAC.FDK.Encoder )
140
173
end
141
174
175
+ defp maybe_plug_encoder ( builder , % MPEGAudio { } ) do
176
+ builder |> child ( :mp3_encoder , Membrane.MP3.Lame.Encoder )
177
+ end
178
+
142
179
defp maybe_plug_encoder ( builder , % RawAudio { } ) do
143
180
builder
144
181
end
0 commit comments