Skip to content

Commit

Permalink
Merge pull request jiaaro#393 from chussong/master
Browse files Browse the repository at this point in the history
Allow codecs and parameters in wav and raw export
  • Loading branch information
jiaaro committed Jan 30, 2020
2 parents a9b8133 + bc2639c commit 03ce984
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 6 deletions.
20 changes: 14 additions & 6 deletions pydub/audio_segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,15 +774,15 @@ def export(self, out_f=None, format='mp3', codec=None, bitrate=None, parameters=
('mp3', 'wav', 'raw', 'ogg' or other ffmpeg/avconv supported files)
codec (string)
Codec used to encoding for the destination.
Codec used to encode the destination file.
bitrate (string)
Bitrate used when encoding destination file. (64, 92, 128, 256, 312k...)
Each codec accepts different bitrate arguments so take a look at the
ffmpeg documentation for details (bitrate usually shown as -b, -ba or
-a:b).
parameters (string)
parameters (list of strings)
Aditional ffmpeg/avconv parameters
tags (dict)
Expand All @@ -797,6 +797,12 @@ def export(self, out_f=None, format='mp3', codec=None, bitrate=None, parameters=
"""
id3v2_allowed_versions = ['3', '4']

if format == "raw" and (codec is not None or parameters is not None):
raise AttributeError(
'Can not invoke ffmpeg when export format is "raw"; '
'specify an ffmpeg raw format like format="s16le" instead '
'or call export(format="raw") with no codec or parameters')

out_f, _ = _fd_or_path_or_tempfile(out_f, 'wb+')
out_f.seek(0)

Expand All @@ -805,8 +811,10 @@ def export(self, out_f=None, format='mp3', codec=None, bitrate=None, parameters=
out_f.seek(0)
return out_f

# for wav output we can just write the data directly to out_f
if format == "wav":
# wav with no ffmpeg parameters can just be written directly to out_f
easy_wav = format == "wav" and codec is None and parameters is None

if easy_wav:
data = out_f
else:
data = NamedTemporaryFile(mode="wb", delete=False)
Expand All @@ -821,8 +829,8 @@ def export(self, out_f=None, format='mp3', codec=None, bitrate=None, parameters=
wave_data.writeframesraw(self._data)
wave_data.close()

# for wav files, we're done (wav data is written directly to out_f)
if format == 'wav':
# for easy wav files, we're done (wav data is written directly to out_f)
if easy_wav:
return out_f

output = NamedTemporaryFile(mode="w+b", delete=False)
Expand Down
31 changes: 31 additions & 0 deletions test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,27 @@ def test_export_as_wav(self):
len(seg),
percentage=0.01)

def test_export_as_wav_with_codec(self):
seg = self.seg1
exported_wav = seg.export(format='wav', codec='pcm_s32le')
seg_exported_wav = AudioSegment.from_wav(exported_wav)

self.assertWithinTolerance(len(seg_exported_wav),
len(seg),
percentage=0.01)
self.assertEqual(seg_exported_wav.sample_width, 4)

def test_export_as_wav_with_parameters(self):
seg = self.seg1
exported_wav = seg.export(format='wav', parameters=['-ar', '16000', '-ac', '1'])
seg_exported_wav = AudioSegment.from_wav(exported_wav)

self.assertWithinTolerance(len(seg_exported_wav),
len(seg),
percentage=0.01)
self.assertEqual(seg_exported_wav.frame_rate, 16000)
self.assertEqual(seg_exported_wav.channels, 1)

def test_export_as_raw(self):
seg = self.seg1
exported_raw = seg.export(format='raw')
Expand All @@ -570,6 +591,16 @@ def test_export_as_raw(self):
len(seg),
percentage=0.01)

def test_export_as_raw_with_codec(self):
seg = self.seg1
with self.assertRaises(AttributeError):
seg.export(format='raw', codec='pcm_s32le')

def test_export_as_raw_with_parameters(self):
seg = self.seg1
with self.assertRaises(AttributeError):
seg.export(format='raw', parameters=['-ar', '16000', '-ac', '1'])

def test_export_as_ogg(self):
seg = self.seg1
exported_ogg = seg.export(format='ogg')
Expand Down

0 comments on commit 03ce984

Please sign in to comment.