Giter VIP home page Giter VIP logo

pydub's Introduction

Pydub Build Status Build status

Pydub lets you do stuff to audio in a way that isn't stupid.

Stuff you might be looking for:

Quickstart

Open a WAV file

from pydub import AudioSegment

song = AudioSegment.from_wav("never_gonna_give_you_up.wav")

...or a mp3

song = AudioSegment.from_mp3("never_gonna_give_you_up.mp3")

... or an ogg, or flv, or anything else ffmpeg supports

ogg_version = AudioSegment.from_ogg("never_gonna_give_you_up.ogg")
flv_version = AudioSegment.from_flv("never_gonna_give_you_up.flv")

mp4_version = AudioSegment.from_file("never_gonna_give_you_up.mp4", "mp4")
wma_version = AudioSegment.from_file("never_gonna_give_you_up.wma", "wma")
aac_version = AudioSegment.from_file("never_gonna_give_you_up.aiff", "aac")

Slice audio:

# pydub does things in milliseconds
ten_seconds = 10 * 1000

first_10_seconds = song[:ten_seconds]

last_5_seconds = song[-5000:]

Make the beginning louder and the end quieter

# boost volume by 6dB
beginning = first_10_seconds + 6

# reduce volume by 3dB
end = last_5_seconds - 3

Concatenate audio (add one file to the end of another)

without_the_middle = beginning + end

How long is it?

without_the_middle.duration_seconds == 15.0

AudioSegments are immutable

# song is not modified
backwards = song.reverse()

Crossfade (again, beginning and end are not modified)

# 1.5 second crossfade
with_style = beginning.append(end, crossfade=1500)

Repeat

# repeat the clip twice
do_it_over = with_style * 2

Fade (note that you can chain operations because everything returns an AudioSegment)

# 2 sec fade in, 3 sec fade out
awesome = do_it_over.fade_in(2000).fade_out(3000)

Save the results (again whatever ffmpeg supports)

awesome.export("mashup.mp3", format="mp3")

Save the results with tags (metadata)

awesome.export("mashup.mp3", format="mp3", tags={'artist': 'Various artists', 'album': 'Best of 2011', 'comments': 'This album is awesome!'})

You can pass an optional bitrate argument to export using any syntax ffmpeg supports.

awesome.export("mashup.mp3", format="mp3", bitrate="192k")

Any further arguments supported by ffmpeg can be passed as a list in a 'parameters' argument, with switch first, argument second. Note that no validation takes place on these parameters, and you may be limited by what your particular build of ffmpeg/avlib supports.

# Use preset mp3 quality 0 (equivalent to lame V0)
awesome.export("mashup.mp3", format="mp3", parameters=["-q:a", "0"])

# Mix down to two channels and set hard output volume
awesome.export("mashup.mp3", format="mp3", parameters=["-ac", "2", "-vol", "150"])

Debugging

Most issues people run into are related to converting between formats using ffmpeg/avlib. Pydub provides a logger that outputs the subprocess calls to help you track down issues:

>>> import logging

>>> l = logging.getLogger("pydub.converter")
>>> l.setLevel(logging.DEBUG)
>>> l.addHandler(logging.StreamHandler())

>>> AudioSegment.from_file("./test/data/test1.mp3")
subprocess.call(['ffmpeg', '-y', '-i', '/var/folders/71/42k8g72x4pq09tfp920d033r0000gn/T/tmpeZTgMy', '-vn', '-f', 'wav', '/var/folders/71/42k8g72x4pq09tfp920d033r0000gn/T/tmpK5aLcZ'])
<pydub.audio_segment.AudioSegment object at 0x101b43e10>

Don't worry about the temporary files used in the conversion. They're cleaned up automatically.

Bugs & Questions

You can file bugs in our github issues tracker, and ask any technical questions on Stack Overflow using the pydub tag. We keep an eye on both.

Installation

Installing pydub is easy, but don't forget to install ffmpeg/avlib (the next section in this doc)

pip install pydub

Or install the latest dev version from github (or replace @master with a release version like @v0.12.0)…

pip install git+https://github.com/jiaaro/pydub.git@master

-OR-

git clone https://github.com/jiaaro/pydub.git

-OR-

Copy the pydub directory into your python path. Zip here

Dependencies

You can open and save WAV files with pure python. For opening and saving non-wav files – like mp3 – you'll need ffmpeg or libav.

Playback

You can play audio if you have one of these installed (simpleaudio strongly recommended, even if you are installing ffmpeg/libav):

  • simpleaudio
  • pyaudio
  • ffplay (usually bundled with ffmpeg, see the next section)
  • avplay (usually bundled with libav, see the next section)
from pydub import AudioSegment
from pydub.playback import play

sound = AudioSegment.from_file("mysound.wav", format="wav")
play(sound)

Getting ffmpeg set up

You may use libav or ffmpeg.

Mac (using homebrew):

# libav
brew install libav

####    OR    #####

# ffmpeg
brew install ffmpeg

Linux (using aptitude):

# libav
apt-get install libav-tools libavcodec-extra

####    OR    #####

# ffmpeg
apt-get install ffmpeg libavcodec-extra

Windows:

  1. Download and extract libav from Windows binaries provided here.
  2. Add the libav /bin folder to your PATH envvar
  3. pip install pydub

Important Notes

AudioSegment objects are immutable

Ogg exporting and default codecs

The Ogg specification (http://tools.ietf.org/html/rfc5334) does not specify the codec to use, this choice is left up to the user. Vorbis and Theora are just some of a number of potential codecs (see page 3 of the rfc) that can be used for the encapsulated data.

When no codec is specified exporting to ogg will default to using vorbis as a convenience. That is:

from pydub import AudioSegment
song = AudioSegment.from_mp3("test/data/test1.mp3")
song.export("out.ogg", format="ogg")  # Is the same as:
song.export("out.ogg", format="ogg", codec="libvorbis")

Example Use

Suppose you have a directory filled with mp4 and flv videos and you want to convert all of them to mp3 so you can listen to them on your mp3 player.

import os
import glob
from pydub import AudioSegment

video_dir = '/home/johndoe/downloaded_videos/'  # Path where the videos are located
extension_list = ('*.mp4', '*.flv')

os.chdir(video_dir)
for extension in extension_list:
    for video in glob.glob(extension):
        mp3_filename = os.path.splitext(os.path.basename(video))[0] + '.mp3'
        AudioSegment.from_file(video).export(mp3_filename, format='mp3')

How about another example?

from glob import glob
from pydub import AudioSegment

playlist_songs = [AudioSegment.from_mp3(mp3_file) for mp3_file in glob("*.mp3")]

first_song = playlist_songs.pop(0)

# let's just include the first 30 seconds of the first song (slicing
# is done by milliseconds)
beginning_of_song = first_song[:30*1000]

playlist = beginning_of_song
for song in playlist_songs:

    # We don't want an abrupt stop at the end, so let's do a 10 second crossfades
    playlist = playlist.append(song, crossfade=(10 * 1000))

# let's fade out the end of the last song
playlist = playlist.fade_out(30)

# hmm I wonder how long it is... ( len(audio_segment) returns milliseconds )
playlist_length = len(playlist) / (1000*60)

# lets save it!
with open("%s_minute_playlist.mp3" % playlist_length, 'wb') as out_f:
    playlist.export(out_f, format='mp3')

License (MIT License)

Copyright © 2011 James Robert, http://jiaaro.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

pydub's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pydub's Issues

Slicing notation in README

Hi,

I'm not sure if this is an issue with the documentation (README file) only, or if pydub actually works this way. The README file suggests the following notation for getting the last five seconds of an AudioSegment:

last_5_seconds = song[5000:]

If I'm not mistaken (which I very well could be), this would actually get all the contents of the segment except the first 5 seconds. Instead, using the starting index -5000 would get the last 5 seconds.

I haven't gotten the chance to test whether the real behavior is as described in the README or the expected, "pythonic" behavior.

I'd greatly appreciate if someone could clear up this issue for me. Perhaps the README file should be changed?

Thanks!

Merging two files .GSM

Hi,

my project is about merging two local files .gsm in order to obtain a .wav file.

I do not how to do, because i see that the function from_gsm is not defined, which

comes directly after the AudioSegment,

Thanks

FFMPEG conversion to anything but .wav file

I am having the same issue as asmedrano
Apparently it is an issue with ffmpeg??
I can't seem to get it to work. I should have DE capabilities for mp3, but it's not working

ffmpeg -y -f wav -i ./mix.wav -f mp3 ./out.mp3FFmpeg version SVN-r26402, Copyright (c) 2000-2011 the FFmpeg developers
built on Jan 2 2013 04:45:44 with llvm_gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
configuration: --disable-yasm
libavutil 50.36. 0 / 50.36. 0
libavcore 0.16. 1 / 0.16. 1
libavcodec 52.108. 0 / 52.108. 0
libavformat 52.93. 0 / 52.93. 0
libavdevice 52. 2. 3 / 52. 2. 3
libavfilter 1.74. 0 / 1.74. 0
libswscale 0.12. 0 / 0.12. 0
[wav @ 0x7f9d8a00b000] max_analyze_duration reached
Input #0, wav, from './mix.wav':
Duration: 00:04:30.53, bitrate: 1411 kb/s
Stream #0.0: Audio: pcm_s16le, 44100 Hz, 2 channels, s16, 1411 kb/s
Output #0, mp3, to './out.mp3':
Stream #0.0: Audio: [0][0][0][0] / 0x0000, 44100 Hz, 2 channels, s16, 64 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Encoder (codec id 86017) not found for output stream #0.0

ffmpeg -formats
FFmpeg version SVN-r26402, Copyright (c) 2000-2011 the FFmpeg developers
built on Jan 2 2013 04:45:44 with llvm_gcc 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
configuration: --disable-yasm
libavutil 50.36. 0 / 50.36. 0
libavcore 0.16. 1 / 0.16. 1
libavcodec 52.108. 0 / 52.108. 0
libavformat 52.93. 0 / 52.93. 0
libavdevice 52. 2. 3 / 52. 2. 3
libavfilter 1.74. 0 / 1.74. 0
libswscale 0.12. 0 / 0.12. 0
File formats:
D. = Demuxing supported
.E = Muxing supported

E 3g2 3GP2 format
E 3gp 3GP format
D 4xm 4X Technologies format
D IFF IFF format
D ISS Funcom ISS format
D MTV MTV format
DE RoQ raw id RoQ format
E a64 a64 - video for Commodore 64
D aac raw ADTS AAC
DE ac3 raw AC-3
E adts ADTS AAC
D aea MD STUDIO audio
DE aiff Audio IFF
DE alaw PCM A-law format
DE amr 3GPP AMR file format
D anm Deluxe Paint Animation
D apc CRYO APC format
D ape Monkey's Audio
D applehttp Apple HTTP Live Streaming format
DE asf ASF format
E asf_stream ASF format
DE ass Advanced SubStation Alpha subtitle format
DE au SUN AU format
DE avi AVI format
E avm2 Flash 9 (AVM2) format
D avs AVS format
D bethsoftvid Bethesda Softworks VID format
D bfi Brute Force & Ignorance
D bink Bink
D c93 Interplay C93
D caf Apple Core Audio Format
DE cavsvideo raw Chinese AVS video
D cdg CD Graphics Format
E crc CRC testing format
DE daud D-Cinema audio format
DE dirac raw Dirac
DE dnxhd raw DNxHD (SMPTE VC-3)
D dsicin Delphine Software International CIN format
DE dts raw DTS
DE dv DV video format
E dvd MPEG-2 PS format (DVD VOB)
D dxa DXA
D ea Electronic Arts Multimedia Format
D ea_cdata Electronic Arts cdata
DE eac3 raw E-AC-3
DE f32be PCM 32 bit floating-point big-endian format
DE f32le PCM 32 bit floating-point little-endian format
DE f64be PCM 64 bit floating-point big-endian format
DE f64le PCM 64 bit floating-point little-endian format
DE ffm FFM (FFserver live feed) format
DE ffmetadata FFmpeg metadata in text format
D film_cpk Sega FILM/CPK format
DE filmstrip Adobe Filmstrip
DE flac raw FLAC
D flic FLI/FLC/FLX animation format
DE flv FLV format
E framecrc framecrc testing format
E framemd5 Per-frame MD5 testing format
DE g722 raw G.722
E gif GIF Animation
D gsm raw GSM
DE gxf GXF format
DE h261 raw H.261
DE h263 raw H.263
DE h264 raw H.264 video format
D idcin id Cinematic format
DE image2 image2 sequence
DE image2pipe piped image2 sequence
D ingenient raw Ingenient MJPEG
D ipmovie Interplay MVE format
E ipod iPod H.264 MP4 format
D iv8 A format generated by IndigoVision 8000 video server
D ivf On2 IVF
D lmlm4 lmlm4 raw format
D lxf VR native stream format (LXF)
DE m4v raw MPEG-4 video format
E matroska Matroska file format
D matroska,webm Matroska/WebM file format
E md5 MD5 testing format
DE mjpeg raw MJPEG video
DE mlp raw MLP
D mm American Laser Games MM format
DE mmf Yamaha SMAF
E mov MOV format
D mov,mp4,m4a,3gp,3g2,mj2 QuickTime/MPEG-4/Motion JPEG 2000 format
E mp2 MPEG audio layer 2
DE mp3 MPEG audio layer 3
E mp4 MP4 format
D mpc Musepack
D mpc8 Musepack SV8
DE mpeg MPEG-1 System format
E mpeg1video raw MPEG-1 video
E mpeg2video raw MPEG-2 video
DE mpegts MPEG-2 transport stream format
D mpegtsraw MPEG-2 raw transport stream format
D mpegvideo raw MPEG video
E mpjpeg MIME multipart JPEG format
D msnwctcp MSN TCP Webcam stream
DE mulaw PCM mu-law format
D mvi Motion Pixels MVI format
DE mxf Material eXchange Format
E mxf_d10 Material eXchange Format, D-10 Mapping
D mxg MxPEG clip file format
D nc NC camera feed format
D nsv Nullsoft Streaming Video
E null raw null video format
DE nut NUT format
D nuv NuppelVideo format
DE ogg Ogg
D oma Sony OpenMG audio
E psp PSP MP4 format
D psxstr Sony Playstation STR format
D pva TechnoTrend PVA file and stream format
D qcp QCP format
D r3d REDCODE R3D format
DE rawvideo raw video format
E rcv VC-1 test bitstream
D rl2 RL2 format
DE rm RealMedia format
D rpl RPL/ARMovie format
DE rso Lego Mindstorms RSO format
DE rtp RTP output format
DE rtsp RTSP output format
DE s16be PCM signed 16 bit big-endian format
DE s16le PCM signed 16 bit little-endian format
DE s24be PCM signed 24 bit big-endian format
DE s24le PCM signed 24 bit little-endian format
DE s32be PCM signed 32 bit big-endian format
DE s32le PCM signed 32 bit little-endian format
DE s8 PCM signed 8 bit format
DE sap SAP output format
D sdp SDP
D shn raw Shorten
D siff Beam Software SIFF
D smk Smacker video
D sol Sierra SOL format
DE sox SoX native format
DE spdif IEC 61937 (used on S/PDIF - IEC958)
DE srt SubRip subtitle format
E svcd MPEG-2 PS format (VOB)
DE swf Flash format
D thp THP
D tiertexseq Tiertex Limited SEQ format
D tmv 8088flex TMV
DE truehd raw TrueHD
D tta True Audio
D tty Tele-typewriter
D txd Renderware TeXture Dictionary
DE u16be PCM unsigned 16 bit big-endian format
DE u16le PCM unsigned 16 bit little-endian format
DE u24be PCM unsigned 24 bit big-endian format
DE u24le PCM unsigned 24 bit little-endian format
DE u32be PCM unsigned 32 bit big-endian format
DE u32le PCM unsigned 32 bit little-endian format
DE u8 PCM unsigned 8 bit format
D vc1 raw VC-1
D vc1test VC-1 test bitstream format
E vcd MPEG-1 System format (VCD)
D vmd Sierra VMD format
E vob MPEG-2 PS format (VOB)
DE voc Creative Voice file format
D vqf Nippon Telegraph and Telephone Corporation (NTT) TwinVQ
D w64 Sony Wave64 format
DE wav WAV format
D wc3movie Wing Commander III movie format
E webm WebM file format
D wsaud Westwood Studios audio format
D wsvqa Westwood Studios VQA format
D wtv Windows Television (WTV)
D wv WavPack
D xa Maxis XA File Format
D yop Psygnosis YOP Format
DE yuv4mpegpipe YUV4MPEG pipe format

Getting an error here running sound.export()

File "jarvis.py", line 53, in wakeup
stt_response = stt_engine.get_text()
File "/home/sriram/projects/Jarvis/src/google_stt.py", line 28, in get_text
sound.export(stt_flac_filename, format="flac")
File "/usr/local/lib/python2.7/dist-packages/pydub/audio_segment.py", line 427, in export
stderr=open(os.devnull)
File "/usr/lib/python2.7/subprocess.py", line 493, in call
return Popen(_popenargs, *_kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 679, in init
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

Not entirely sure what the issue is here. I don't even know where to start to debug this..

Windows issue

Hi!

I'm having trouble under windows. I've narrowed it down to:

shlex.split(' '.join(ffmpeg_call))

Under Windows it converts a path like

c:\\users\\admin\\appdata\\local\\temp\\tmpclb6qy

to

c:usersadminappdatalocaltemptmpclb6qy

Compressed Wave loading fails

Using either from_wav or from_file(name, "wav") gives:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "build\bdist.win32\egg\pydub\audio_segment.py", line 273, in from_file
  File "build\bdist.win32\egg\pydub\audio_segment.py", line 324, in from_wav
  File "build\bdist.win32\egg\pydub\audio_segment.py", line 69, in __init__
  File "C:\Python27\lib\wave.py", line 502, in open
    return Wave_read(f)
  File "C:\Python27\lib\wave.py", line 163, in __init__
    self.initfp(f)
  File "C:\Python27\lib\wave.py", line 143, in initfp
    self._read_fmt_chunk(chunk)
  File "C:\Python27\lib\wave.py", line 270, in _read_fmt_chunk
    raise Error, 'unknown format: %r' % (wFormatTag,)
wave.Error: unknown format: 3

However, using from_file without any hints loads the wave file just fine.

Through a quick browse of the source code (as well as the error), it looks like when using the "wav" format, pydub defaults to using the built-in wave module, which doesn't support compressed wave files. Either pydub should check whether the wave file is compressed or not, or it should default to using whatever makes it work without the "wav" hint.

Hi

I have wrote u yesterday about a bug concerning mixing two files .GSM in order to obtain a wav file.

this is my code :
import os
from glob import glob
from pydub import AudioSegment

son1 = AudioSegment.from_file("/home/yatouzani/exp/1386774519.2101-in.gsm", "GSM")
son2 = AudioSegment.from_file("/home/yatouzani/exp/1386774519.2101-out.gsm", "GSM")

output = son1.overlay(son2, position = 2000)
output.export("Fichies mixés", format="wav")

but it does not work. please needing help

Thankssss a lot

Error: not a WAVE file

Invoking AudioSegment.from_file(filename) from multiple processes at the same time causes it to sometimes raise Error: not a WAVE file.

Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "dejavu/__init__.py", line 69, in _fingerprint_worker
    channels, Fs = decoder.read(filename)
  File "dejavu/decoder.py", line 29, in read
    audiofile = AudioSegment.from_file(filename)
  File "build/bdist.linux-x86_64/egg/pydub/audio_segment.py", line 237, in from_file
    obj = cls.from_wav(output)
  File "build/bdist.linux-x86_64/egg/pydub/audio_segment.py", line 262, in from_wav
    return cls(data=file)
  File "build/bdist.linux-x86_64/egg/pydub/audio_segment.py", line 58, in __init__
    raw = wave.open(StringIO(data), 'rb')
  File "/usr/lib/python2.7/wave.py", line 498, in open
    return Wave_read(f)
  File "/usr/lib/python2.7/wave.py", line 163, in __init__
    self.initfp(f)
  File "/usr/lib/python2.7/wave.py", line 132, in initfp
    raise Error, 'not a WAVE file'
Error: not a WAVE file

Speculation: It seems to occur because the subprocess.call to ffmpeg ignores the resulting returncode of ffmpeg and tries to read the (most likely) empty file.

pydub not finding FFMPEG on Windows Systems

Even though ffmpeg has been installed and added to the PATH environment variable, pydub still gives the warning about not finding ffmpeg. This is probably because executables have a .exe extension on windows, which pydub doesn't check for.

Decoding failed with mp3

When I'm trying to load a mp3 with song = AudioSegment.from_mp3("23935.mp3") I get this:

Traceback (most recent call last):
File "mp3parser.py", line 11, in
sys.exit(main(sys.argv))
File "mp3parser.py", line 7, in main
song = AudioSegment.from_mp3(argv[0])
File "/usr/local/lib/python3.4/dist-packages/pydub/audio_segment.py", line 318, in from_mp3
return cls.from_file(file, 'mp3')
File "/usr/local/lib/python3.4/dist-packages/pydub/audio_segment.py", line 305, in from_file
raise CouldntDecodeError("Decoding failed. ffmpeg returned error code: {0}".format(retcode))
pydub.exceptions.CouldntDecodeError: Decoding failed. ffmpeg returned error code: 1

Problems exporting to mp3

The library mostly works really well, but there's this weird problem with exporting.
Let's say i've loaded the following sound files and concatenated them:

seg1 = AudioSegment.from_mp3("29c4c99d468e0b00fa744db9ce2457c3.mp3")
seg2 = AudioSegment.from_mp3("b211a73912fee239054bd170bb557087.mp3")
segt = seg1 + seg2

If I try to export it in mp3, this way:

segt.export("test.mp3", format = "mp3")
#or this way
segt.segt.export("test.mp3", format = "mp3", codec = "lame")

I don't get any error, yet the file is completely empty (verified with a simple "cat test.mp3").
The weird part is that the export works in vorbis (and ogg, obviously), with the following command:

segt.export("test.ogg", format = "ogg", codec = "libvorbis")

I've thoroughly tested if seg1, seg2 and segt weren't empty to make sure.

Conversion to format='ogg' (Vorbis) results in FLAC if no codec is specicied

When converting an input audio file to Ogg Vorbis if the codec is not specified as libvorbis the resultant output file is in the FLAC format. I tested this loading an input MP3 and WAV file and then exporting it to Ogg, AU, WAV. For the ogg format no error was raised but the resultant file when checked was actually a FLAC.

I could convert to mp3 without specifying a codec. Ogg files only resulted when codec='libvorbis' was added. I'm a bit pressed for time at the minute so wanted to flag it up; I'm unsure if it's a bug with pydub or elsewhere or just a quirk of the process and thus more a documentation update.

In [26]: m = AudioSegment.from_file('/tmp/track.mp3', 'mp3')

In [27]: m = AudioSegment.from_mp3('/tmp/track.mp3')                                                                                                                                                  

In [28]: m.export('/tmp/t.ogg', format='ogg')                                                                                                                                                         
Out[28]: <open file '/tmp/t.ogg', mode 'wb+' at 0x49a4270>

In [29]: !soxi /tmp/t.ogg
soxi FAIL formats: can't open input file `/tmp/t.ogg': Input not an Ogg Vorbis audio stream

In [30]: m.export('/tmp/t.ogg', format='ogg', codec='libvorbis')
Out[30]: <open file '/tmp/t.ogg', mode 'wb+' at 0x49a4300>

In [31]: !soxi /tmp/t.ogg

Input File     : '/tmp/t.ogg'
Channels       : 2
Sample Rate    : 44100
Precision      : 16-bit
Duration       : 00:01:30.02 = 3969856 samples = 6751.46 CDDA sectors
File Size      : 1.21M
Bit Rate       : 108k
Sample Encoding: Vorbis
Comment        : 'encoder=Lavf55.19.104'


In [32]: m.export('/tmp/t.ogg', format='wav')                                                                                                                                                         
Out[32]: <open file '/tmp/t.ogg', mode 'wb+' at 0x49a4390>

In [33]: !soxi /tmp/t.ogg

Input File     : '/tmp/t.ogg' (wav)
Channels       : 2
Sample Rate    : 44100
Precision      : 16-bit
Duration       : 00:01:30.02 = 3969839 samples = 6751.43 CDDA sectors
File Size      : 15.9M

Bug during mp3 write from the temp file

For my side I will need to modify the access to the output file (export method):

change line 262 from:
output = NamedTemporaryFile(mode="w+", delete=False)

to:
output = NamedTemporaryFile(mode="wb+", delete=False)

regards,
-damien

AudioSegment from_file with remote file?

I was trying to use from_file with uri to an .mp3 and I found that this does not work. What do you think about adding the ability to pass in a uri for a remotely located file into the file parameter of from_file?

If this make sense as a feature I'd be willing to try to build it out and submit a pull request.

Songs should be saved with the same tag info they were opened with

Currently, by default a song imported with AudioSegment.from_file and then saved with song.export(name) is saved as the same format it was opened with. It would be very helpful if the tags could remain, too. So if the tags argument isn't provided for the export method, it would use whatever metadata was there originally.

I hope this makes sense.

Problems with convertation

Hello!

I have one bad file https://dl.dropboxusercontent.com/u/12584022/example.aac

When I tried convert it with pydub:
ffmpeg -y -f aac -i /tmp/tmpXjgYWo -vn -f wav /tmp/tmpGOq7p7

I got a message:
[aac @ 0x2ebdf20] More than one AAC RDB per ADTS frame is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.

If I removed -f flag, it working very well:
ffmpeg -y -i /tmp/tmpXjgYWo -vn -f wav /tmp/tmpGOq7p7

What do you think about idea: do convertation again without -f flag if first convertation was unsuccessful? It will be working for files with wrong extensions

Thanks,
Alexey

"File not found" issue

I getting the following error in Python 27:

runfile('C:/Python27/AudioTools.py', wdir=r'C:/Python27')
Traceback (most recent call last):
File "", line 1, in
File "C:\Python27\lib\site-packages\spyderlib\widgets\externalshell\sitecustomize.py", line 540, in runfile
execfile(filename, namespace)
File "C:/Python27/AudioTools.py", line 84, in
makeLouder()
File "C:/Python27/AudioTools.py", line 80, in makeLouder
song = pydub.AudioSegment.from_mp3("Track1.mp3")
File "C:\Python27\lib\pydub\audio_segment.py", line 318, in from_mp3
return cls.from_file(file, 'mp3')
File "C:\Python27\lib\pydub\audio_segment.py", line 302, in from_file
retcode = subprocess.call(convertion_command, stderr=open(os.devnull))
File "C:\Python27\lib\subprocess.py", line 522, in call
return Popen(_popenargs, *_kwargs).wait()
File "C:\Python27\lib\subprocess.py", line 709, in init
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 957, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

I'm simply trying to open an mp3 file... ffmpeg is installed and in my path statement.
Any hints?

thanks

EOFError when loading Mp3

When I try to load audio from an mp3, it throws an EOFError.

>>> from pydub import AudioSegment
>>> audio_fn = 'test.mp3'
>>> audio = AudioSegment.from_mp3(audio_fn)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/project/.env/local/lib/python2.7/site-packages/pydub/audio_segment.py", line 248, in from_mp3
    return cls.from_file(file, 'mp3')
  File "/usr/local/project/.env/local/lib/python2.7/site-packages/pydub/audio_segment.py", line 237, in from_file
    obj = cls.from_wav(output)
  File "/usr/local/project/.env/local/lib/python2.7/site-packages/pydub/audio_segment.py", line 262, in from_wav
    return cls(data=file)
  File "/usr/local/project/.env/local/lib/python2.7/site-packages/pydub/audio_segment.py", line 58, in __init__
    raw = wave.open(StringIO(data), 'rb')
  File "/usr/lib/python2.7/wave.py", line 498, in open
    return Wave_read(f)
  File "/usr/lib/python2.7/wave.py", line 163, in __init__
    self.initfp(f)
  File "/usr/lib/python2.7/wave.py", line 128, in initfp
    self._file = Chunk(file, bigendian = 0)
  File "/usr/lib/python2.7/chunk.py", line 63, in __init__
    raise EOFError
EOFError

The specific file I used is http://gamesplusone.com/thebugle/thebugle035.mp3, which appears to be perfectly valid.

I'm using the current version on PyPI, pydub==0.8.3.

WAVE exporting sometimes fails without format='wav'

With pydub==0.9.5
If I say:

a=pydub.AudioSegment.from_file('myfile.m4a')
outfile = a[:10000].export('xx.wav')
outfile.close()

and then

b=pydub.AudioSegment.from_wav('xx.wav')

I get the error: CouldntDecodeError: Decoding failed. ffmpeg returned error code: 1

Trying to play with sox I get:

FAIL formats: can't open input file `xx.wav': WAVE: RIFF header not found

Am I doing something wrong?

My ffmpeg (if relevant) is:

ffmpeg -v
ffmpeg version 2.5.3 Copyright (c) 2000-2015 the FFmpeg developers
built on Jan 17 2015 12:08:40 with Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
configuration: --prefix=/usr/local/Cellar/ffmpeg/2.5.3 --enable-shared --enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-libx264 --enable-libmp3lame --enable-libvo-aacenc --enable-libxvid --enable-vda
libavutil 54. 15.100 / 54. 15.100
libavcodec 56. 13.100 / 56. 13.100
libavformat 56. 15.102 / 56. 15.102
libavdevice 56. 3.100 / 56. 3.100
libavfilter 5. 2.103 / 5. 2.103
libavresample 2. 1. 0 / 2. 1. 0
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100

MP3 files have incorrect duration meta data

E-mail from a user:

I came across pydub and was testing it out and came upon what might be a small issue based on your example docs.

If I do

song.export("/home/test/1381936135.mp3", format="mp3")

The resulting mp3 will have extra time added in on it's meta tag info

If I add in a bit rate parameter it exports the WAV to mp3 perfect.

song.export("/home/test/1381936135.mp3", format="mp3", bitrate="128k")

Not a huge deal but thought I would pass it along to you.

The resulting file size was 160,723 bytes vs 160,958 bytes…... so ffmpeg is doing something.

Converted mp3 file is of size of zero bytes..

I am trying to convert my wav file to mp3, but its generating mp3 file with zero bytes in size.

Here's my code..

from pydub import AudioSegment
AudioSegment.from_wav("test1.wav").export("test1.mp3", format="mp3")

I have installed pydub on my ubuntu machine(12.04 LTS).

Is latest code broken ?

Error while exporting some wave files

I tried reading a bunch of .wav files with pydub and some of the files are failing.
When searching for a solution, I found this link:
http://stackoverflow.com/questions/17297048/opening-a-wave-file-in-python-unknown-format-49-whats-going-wrong

Seems some .wav files will not work with the python wave module.
Can this issue be solved using ffmpeg for wave files also?

Here is one sample: http://www-mmsp.ece.mcgill.ca/documents/AudioFormats/WAVE/Samples/AFsp/M1F1-Alaw-AFsp.wav

Thanks for the help and your module

Mp3 Export output

The file produced when I use:

sound.export("mashup.mp3", format="mp3)"

is unplayable. Here is the output from $ avplay

avplay mashup.mp3 
avplay version 0.8.3-4:0.8.3-0ubuntu0.12.04.1, Copyright (c) 2003-2012 the Libav developers
  built on Jun 12 2012 16:37:58 with gcc 4.6.3
[mp3 @ 0xb2300480] Format detected only with low score of 25, misdetection possible!
[mp3 @ 0xb2300480] Could not find codec parameters (Audio: mp3, 0 channels, s16)
[mp3 @ 0xb2300480] Estimating duration from bitrate, this may be inaccurate
mashup.mp3: could not find codec parameters

Exporting to wav however does work.

Getting CouldntDecodeError from AudioSegment.from_wav/from_mpeg since recent update

I have not investigated thoroughly but since recent changes to audio_segment.py, I am getting frequent CouldntDecodeError in AudioSegment.from_wav and .from_mpeg where ffmpeg is returning a non-zero code. It does not happen all the time and I have not determined what the file characteristics are that trigger it but prior to the recent update I had not seen this error. This is occurring on Windows 7, python 2.7.2. I haven't had a chance to see if the same error is occurring on Linux.

Implement faster tests

In my machine tests are running very slowly.

$ time python2 test/test.py
........................
----------------------------------------------------------------------
Ran 24 tests in 32.678s

OK

real    0m32.736s
user    0m26.364s
sys 0m2.172s

Any ideas to improve it? I working on something already.

closing exported files

I'm making a real time equalizer, so there's a lot of opening and exporting(overwriting). I noticed, if, after exporting, i try to play the exported file in, say, windows media player, it says the file is still open. This goes away once i close the python shell, but if i change the eq enough times i get this error:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1410, in call
return self.func(_args)
File "C:\Python27\lib\lib-tk\Tkinter.py", line 495, in callit
func(_args)
File "C:\Users\Neil\Desktop\112_Term_Project\deliverable_1\eq_graphics.py", line 149, in f
timerFired(canvas)
File "C:\Users\Neil\Desktop\112_Term_Project\deliverable_1\eq_graphics.py", line 143, in timerFired
adjustVol(canvas)
File "C:\Users\Neil\Desktop\112_Term_Project\deliverable_1\eq_graphics.py", line 65, in adjustVol
canvas.data.pastLevels[i])
File "C:\Users\Neil\Desktop\112_Term_Project\deliverable_1\eq_graphics.py", line 59, in changeVol
song.export(filename, format='wav')
File "C:\Python27\lib\site-packages\pydub\audio_segment.py", line 299, in export
out_f = _fd_or_path_or_tempfile(out_f, 'wb+')
File "C:\Python27\lib\site-packages\pydub\utils.py", line 15, in _fd_or_path_or_tempfile
fd = open(fd, mode=mode)
IOError: [Errno 22] invalid mode ('wb+') or filename: 'C:/Users/Neil/Desktop/112_Term_Project/test/8320-16640.wav'

obj.export(fname, format='wav') returns an open file with type 'wb+', so I think this is associated with the problem.

Size of output mp3 is always 81 byte

Windows 7 32bit, Python 2.7.3

Size of output mp3 is always 81 byte.

Script:

from pydub import AudioSegment
podcast = AudioSegment.from_wav("Recording 1.wav")
podcast.export("podcast_processed.mp3")

Directy from cmd:

ffmpeg -y -f wav -i "Recording 1.wav" -f mp3 podcast_processed.mp3
Result mp3 file OK

If I comment 'stderr=open(os.devnull)' at audio_segment.py output from ffmpeg is the same as from cmd but size of result file is 81 byte.

pydub operating direct to disk vs in memory?

EDIT: All tickets related to large audio files and out-of-memory errors are being merged into #135
-- jiaaro

Original issue after the break


Hey,

Hopefully this is an okay forum to ask about this, but I was wondering if you had any thoughts on adapting pydub to operate direct to disk rather than in memory. From what I can tell, an operation that is overlaying, say, multiple hour-long audio files is going to have quite a massive memory footprint.

If I wanted to adapt pydub to operate directly on-disk, do you have any thoughts on how involved that would be? Is that something that could play nice with audioop?

Just looking for some thoughts here...

Julian

Python 3 Support

I'm working on a little test app dealing with audio files and to me PyDub looks like a great tool to use. I haven't been able to get it to work properly though and, due to some google searches of the errors I'm getting, I suspect it's because I'm trying to use Python 3 rather than Python 2.

I'm still pretty new to Python in general, so first I'd like some confirmation about whether or not PyDub works with Python 3. If it does then I don't have any idea what I'm doing wrong. If not, I guess I could just take a crack at modifying it myself.

Thanks

Problems with AudioSegment.from_mp3

Hello James,
I have Python2.7 (Win) and got latest pydub.
When trying to open mp3 file using:
song = AudioSegment.from_mp3("b.mp3")
(while double checking with os.listdir that I do have the file in current folder),
I'm getting:

song = AudioSegment.from_mp3("b.mp3")

Traceback (most recent call last):
File "<pyshell#5>", line 1, in
song = AudioSegment.from_mp3("b.mp3")
File "build\bdist.win32\egg\pydub\audio_segment.py", line 318, in from_mp3
return cls.from_file(file, 'mp3')
File "build\bdist.win32\egg\pydub\audio_segment.py", line 302, in from_file
retcode = subprocess.call(convertion_command, stderr=open(os.devnull))
File "C:\Python27\lib\subprocess.py", line 486, in call
return Popen(_popenargs, *_kwargs).wait()
File "C:\Python27\lib\subprocess.py", line 672, in init
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 882, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified

What's the problem?
Additionaly while I do first time: from pydub import AudioSegment
I'm getting:
Warning (from warnings module):
File "C:\Python27\lib\site-packages\pydub-0.9.2-py2.7.egg\pydub\utils.py", line 122
RuntimeWarning: Couldn't find ffmpeg or avconv - defaulting to ffmpeg, but may not work

The repeated import goes without warning.

So - what it can be that I can't open plain mp3 file ?

my email is: [email protected]

Mono to stereo error...

I wanted to convert a mono wav file to stereo (as in http://stackoverflow.com/questions/5120555/how-can-i-convert-a-wav-from-stereo-to-mono-in-python), but get an error:

In [9]: sound = AudioSegment.from_wav("/_samples/Impromptu/mono/test.wav")

In [10]: sound
Out[10]: <pydub.audio_segment.AudioSegment at 0x106270650>

In [11]: sound.set_channels(2)
---------------------------------------------------------------------------
error                                     Traceback (most recent call last)
<ipython-input-11-c4c2fe6e079e> in <module>()
----> 1 sound.set_channels(2)

/Users/michele.pasin/Downloads/pydub-master/pydub/audio_segment.py in set_channels(self, channels)
    327 
    328         fn = getattr(audioop, fn)
--> 329         converted = fn(self._data, self.sample_width, 1, 1)
    330 
    331         return self._spawn(data=converted, overrides={'channels': channels,

error: Size should be 1, 2 or 4

WindowsError Error 5 Acces denied when converted wav to mp3

Hi,
I've encountered this error when trying your lib in order to convert wav files to mp3.
Here is my code:

from pydub import AudioSegment
import pydub

pydub.AudioSegment.ffmpeg = "C:/ffmpeg"
song = AudioSegment.from_wav("test.wav")
song.export("test.mp3", format="mp3")

ffmpeg (the static version) is placed in C:/ffmpeg

The returned error is
WindowsError [error 5] Access denied join failed.
Could you please help me on what I'm doing wrong.
Thanks

Problems with AudioSegment.from_mp3

No errors are thrown when using this command, but when using the playback function or exporting without specifying the bitrate the song is either garbled or strangely mixed such that it is no longer the original length, although it still sounds coherent. How do I avoid this problem?

Issue with silent duration being incorrect

Hi guys

Just wanted to say that I've been trying out pydub and noticed an issue with the duration in frames of an audiosegment.silent(duration). Looking at the code it seems that the duration is created at a low frame rate (11025 Hz) and when the frame rate is converted up to 48000 Hz the number of frames is incorrect (ie a 3000 ms silence at 48000 Hz is only 143996 frames not the expected 144000 frames). For my own work I've changed the frame rate the silence is create at to 48000 Hz in the code and this has fixed the issue.
Other than that a great little library.

Many thanks

attenuating sound

So, i'm making a music equalizer, and i've already separated the song into 10 frequency bands, but when I open them as raw data in audacity, the volume is so loud that the song just sounds like static. I can use audacity's amplify effect to bring it down to a reasonable level, and i'm trying to use your module to do this in python. I'm exporting the frequency bands as wav files. I opened them with AudioSegment.from_wav, then tried to apply_gain(), but it gives the error:
Traceback (most recent call last):
File "<pyshell#13>", line 1, in
song.apply_gain(-10)
File "C:\Python27\lib\site-packages\pydub\audio_segment.py", line 449, in apply_gain
db_to_float(float(volume_change))))
error: Size should be 1, 2 or 4

Audacity opens it with 64-bit float encoding and little endian byte order.

Thanks!

Version on pydub.com out of date

I used pip install to install pybdub, but found that I couldn't use the dBFS property with that version (the function doesn't exist.) Can you update the downloadables on the site?
I had a hard time learning that I had to run
python setup.py install
after downloading the code from github.
Love the library!

Problem with append() and missing frames

I can't seem to get the append() function to work. It works when i use the '+' operator, but anytime I use append() I get the following error:

Traceback (most recent call last):
File "./test.py", line 59, in
sound2_quieter.append(quieter)
File "/usr/local/lib/python2.7/site-packages/pydub/audio_segment.py", line 663, in append
xf = seg1[-crossfade:].fade(to_gain=-120, start=0, end=float('inf'))
File "/usr/local/lib/python2.7/site-packages/pydub/audio_segment.py", line 162, in getitem
"missing frames: %s" % missing_frames)
pydub.exceptions.TooManyMissingFrames: You should never be filling in more than 2 ms with silence here, missing frames: 3969

Issue with exporting mp3 files

pydub is an excellent sound manipulation tool. It makes sense and seem quite easy to use. I will certainly be making use of it, together with PHP and a Flash interface. However, I am stuck on finding a solution to what seems to be a simple problem.

I can save a wav file using the code example below:

sound1 = AudioSegment.from_wav("./sounds/1.wav")
sound1 = sound1.reverse()
sound1.export("./sounds/out.wav", format="wav")

But, saving an mp3 file is produces errors with the code below:

sound1 = AudioSegment.from_wav("./sounds/1.wav")
sound1 = sound1.reverse()
sound1.export("./sounds/out.mp3", format="mp3")

The error is:

Traceback (most recent call last):
File "/_test/python/test.py", line 15, in
sound1.export("./sounds/out.mp3", format="mp3")
File "/Library/Python/2.7/site-packages/pydub/audio_segment.py", line 289, in export
stderr=open(os.devnull)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 493, in call
return Popen(_popenargs, *_kwargs).wait()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 679, in init
errread, errwrite)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1228, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory

What seems to occur is an mp3 file is created, but results in a 0Kb file. Additionally, I can run ffmpeg through the CLI and the correct file size for the mp3 conversion from wav is created.

Hoping all of this makes sense and there is a simple answer. Thanks for your time reading this. If there is a solution, please let me know!

Pydub Live

There is the possibility to change the equalization or to reverse the song while it is under playing ?

Option "bitrate=32k" fails silently when exporting to ogg.

I have this script that I use to maintain a music database. So far I have no problems, the files are exported to ogg format and stored in the database, but I've noticed that the quality options (intended to reduce the final size of the DB) are ignored completely. I tried both the bitrate and the parameters options.

preview.export("tmp.ogg", "ogg", codec="libvorbis", parameters=["-aq", "1", "-ab", "32k"])
preview.export("tmp.ogg", "ogg", codec="libvorbis", bitrate="64k")

I've done some tests in mp3, and the quality options work as they should. My question is: Do I need some library (libav seems to be installed), or I found a bug?

In case you were wondering, I prefer to use ogg for its best quality/size ratio compared to mp3.

I'm using python 2.7.6 and pydub 0.9.5. Don't know if relevant, but I'm using a 64-bit GNU/Linux system.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.