dir2ogg-0.11.8/0000755000175000017500000000000011236076236012540 5ustar00jakjak00000000000000dir2ogg-0.11.8/NEWS0000644000175000017500000001571311236076236013246 0ustar00jakjak00000000000000dir2ogg (0.11.8) RELEASED; urgency=low * Process files in alphabetical order (Closes: #536040). * Support converting directories without specifying -d (Closes: #535209). * Introduce support for Monkey's Audio with APEv2 tags (LP: #279834). * Introduce support for Musepack with APEv2 tags. * Introduce support for WavPack files with APEv2 tags. * Make output more readable: - Progress message stating the current file and the decoder. - New command-line option -Q,--quiet to not display progress from oggenc. - Do not show progress from decoder at at all, as it may conflict with the output of oggenc. -- Julian Andres Klode Tue, 04 Aug 2009 20:23:00 +0200 dir2ogg (0.11.7) RELEASED; urgency=low * Recognize the track number in mp3 files * Fix problems with mpg123 and files not using 44100Hz (LP: #272341) * Make --preserve-wav work when using mplayer (Closes: #513566) * Fix problem where tags from one file appear in other files (LP: #276037) * Inform people that converting CDs is not well supported. -- Julian Andres Klode Sun, 03 May 2009 14:45:59 +0200 dir2ogg (0.11.6) RELEASED; urgency=low * The "Marek Palatinus" release [ Marek Palatinus ] * Bugfix: function grab_flac_tags() is missing argument "convert" in calling grab_common. (First reported by Gary Jackson) * Bugfix: When --smart-mp3 was used and some files was not "mp3", they used quality of last tested mp3 file. Currently, when detection fails, default quality given thru cmdline parameter is used instead. * Bugfix: Quality is count as float, not integer (problem in oggenc calling) * Improvement: Added parameter "-T --smart-mp3-correction". You can specify difference between detected quality and used quality. When algorithm detected quality "6" and you specify -T 2, quality 4 (= 6 - 2) is used. It accept also floats and negative numbers. So you can raise quality to 1.5 by adding "-T -1.5". * Improvement: Better regression function. -- Julian Andres Klode Mon, 14 Jul 2008 20:47:17 +0200 dir2ogg (0.11.5) RELEASED; urgency=low * Fix support for files with no headers (LP: #229179) -- Julian Andres Klode Wed, 14 May 2008 17:26:52 +0200 dir2ogg (0.11.4) RELEASED; urgency=medium * Print error message if CD is not in FreeDB (LP: #198845) * Use /dev/stdout instead of - for mpg123. Fixes problems with newer mpg123 versions (problem reported by: drac@gentoo.org) -- Julian Andres Klode Tue, 01 Apr 2008 16:06:58 +0200 dir2ogg (0.11.3) RELEASED; urgency=low * More complete fix for tags with non-ascii values -- Julian Andres Klode Tue, 25 Mar 2008 16:39:38 +0100 dir2ogg (0.11.2) RELEASED; urgency=low * Fix FLAC tags with non-ascii values (Closes: #466107) * Add -f as a shortcut for --convert-flac -- Julian Andres Klode Sun, 17 Feb 2008 11:58:20 +0100 dir2ogg (0.11.1) RELEASED; urgency=low * Fix dir2ogg's wav support, so it works again. * More robust tag handling, fixes support for WMA/ASF -- Julian Andres Klode Sat, 15 Dec 2007 22:56:54 +0100 dir2ogg (0.11) RELEASED; urgency=low * Fix mpg123 (decode all frames again) * Add smart-mp3 feature by Marek Palatinus. (Closes: #437263) * Update __version__ and __date__ * Improve first line of output and the output of -l -- Julian Andres Klode Sun, 25 Nov 2007 13:29:29 +0100 dir2ogg (0.11~rc1) RELEASED; urgency=low * New features: - Heavily Improved MP3 Support (switched to mutagen.id3 from mutagen.easyid3) - Support for ALAC Audio Files (use --m4a-decoder=alac-decoder) * Bug fixes: - MPlayer can now work with comma in filename (LP: #155471) - Convert bool and int tags to string - Convert all tag names to lowercase for filtering purposes * Coding style / Cleanup - Remove duplicated code (e.g.: globally define file extensions) - Rename functions, classes, variables to match pylint - Make MyConfig a function => read_opts * Documentation: - Update man page * Other stuff: - No colorized output anymore, easier to work with - cdparanoia: disable all paranoia checks - Print traceback if tag saving failed -- Julian Andres Klode Sun, 04 Nov 2007 17:27:17 +0100 dir2ogg (0.11~beta1) RELEASED; urgency=low * Add ability to select decoder by --XXX-decoder= switches * CD-Ripper: Support mplayer for ripping * Improved tags support for FLAC, M4A and WMA -- Julian Andres Klode Sun, 30 Sep 2007 17:49:47 +0200 dir2ogg (0.11~alpha3) RELEASED; urgency=low * Bugfix: Enable conversion of MP3 files * FLAC: Fix names of the decoders and add 'flac -d' as an decoder * Bugfix: Check for decoders for files specified on commandline * Rename --clean-up to --delete-input and remove -c * Save decoder commands in a dict, remove exec call * Remove enc.wait() * Warn if there are not tags to save. * NEW: CD-Ripper with MusicBrainz support and FreeDB Fallback * Cleanup: Do not import string (deprecated) and re (unused) -- Julian Andres Klode Fri, 17 Aug 2007 15:03:07 +0200 dir2ogg (0.11~alpha2) RELEASED; urgency=low * NEW Features: - Support for FLAC files - New tags: 'discid', 'musicbrainz_discid', 'musicbrainz_sortname', 'tracktotal' * New commandline and config class - Use optparse to parse options - check which decoders to use at startup * More flexible Convert class: - Use subprocess instead of os.system - Support pipes (except for mplayer) * Removal of unneeded functions and classes: - RM: CleanUp - Filter filenames (not needed anymore by subprocess) - RM: getOptions() - Options parser, replaced with MyConfig - RM: showUsage() - Print options summary, done by optparse * Less code: 90 lines less then alpha1 -- Julian Andres Klode Sun, 05 Aug 2007 12:15:20 +0200 dir2ogg (0.11~alpha1) RELEASED; urgency=low * NEWS: Redesigned, using debian changelog style (easier for me) * Redesigned tag support to support multiple values per key (- ca. 90 lines) * Removed --delete-* options (didn't work) and added --delete-input * more simple code -- Julian Andres Klode Sun, 29 Jul 2007 16:35:50 +0200 dir2ogg (0.10.1) RELEASED; urgency=medium * Use mutagen to write the tags to the OGG File (Fixes problems with unicode values which can't be converted to ascii ones) * Fix the manpage (description for --convert-wma: replaced M4A with WMA) -- Julian Andres Klode Wed, 18 Jul 2007 22:38:55 +0200 dir2ogg (0.10) RELEASED; urgency=low * Took over development * Switch to GNU General Public License * Use mutagen for ID3 Tags, M4A and WMA Informations * Support decoding of M4A files without faad * Fix manpage * Cleanups, improve readability of README -- Julian Andres Klode Sun, 15 Jul 2007 17:28:15 +0200 dir2ogg-0.11.8/README0000644000175000017500000000566411236076236013433 0ustar00jakjak00000000000000dir2ogg: version 0.11 Manifest: README - You're reading it now. COPYING - The License under which dir2ogg is released. NEWS - Changes between the versions install.sh - A bash script to automate installation. dir2ogg - The script itself. dir2ogg.1 - The manpage for dir2ogg Installation: (Not so) new in dir2ogg is the install.sh script, which automates installation of the script. You should only use this if you have root access to the computer you are attempting to install dir2ogg on. If you do not have root access then you will have to use dir2ogg from your home directory (perhaps you have a /home/username/bin directory?). To install simply run: sh install.sh Requirements: - Tag preservation: mutagen (http://www.sacredchao.net/quodlibet/wiki/Development/Mutagen) - M4A Conversion: faad or mplayer (ALAC: alac-decoder) - WMA Conversion: mplayer - MP3 Conversion: mpg123, mpg321, lame or mplayer - FLAC Conversion: no extra software required (ogg123 from vorbis-tools) - CD Ripping: cdparanoia, icedax or mplayer Usage: Read the manpage for detailed instructions: "man dir2ogg", or type "dir2ogg --help" for brief usage details. The script is extremely simple, so you shouldn't have any troubles figuring it out. Dir2ogg can take multiple filenames as arguments, and will Do The Right Thing based on the file extension. If using the '-d' flag, you may only give directories as arguments, not filenames and directories If you wish to convert m4a, wma and/or wav files using -d then the -m, -f and -w flags must be used respectively (FLAC: --convert-flac). Wav files are deleted by default, use -p to keep wav files after conversion. There is also support for CD ripping using the '-c' flag. This functionality is not well supported, and it may be better to use a different program for such a task. Bugs: See the manpage. Please report bugs at https://bugs.launchpad.net/dir2ogg License and Disclaimer: Copyright (c) 2007-2008 Julian Andres Klode Copyright (c) 2003-2006 Darren Kirby This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Authors: Current Developer(s): Julian Andres Klode Inactive Developer(s): Darren Kirby Contributors: Cameron Stone Marek Palatinus Date: February 17, 2008 dir2ogg-0.11.8/install.sh0000755000175000017500000000122311236076236014543 0ustar00jakjak00000000000000#!/bin/bash if [ "$UID" -ne 0 ] then echo "You are not root: terminating" exit 2 fi if [ -e "/usr/bin/dir2ogg" ] then echo "/usr/bin/dir2ogg exists! Overwrite? (y/n): " read answ if [ $answ == "n" ] then exit 1 fi fi cp dir2ogg /usr/bin/dir2ogg chown root:root /usr/bin/dir2ogg chmod 755 /usr/bin/dir2ogg if [ -e "/usr/man/man1/dir2ogg.1" ] then echo "/usr/man/man1/dir2ogg.1 exists! Overwrite? (y/n): " read answ if [ $answ == "n" ] then exit 1 fi fi cp dir2ogg.1 /usr/man/man1/dir2ogg.1 chown root:root /usr/man/man1/dir2ogg.1 chmod 644 /usr/man/man1/dir2ogg.1 echo "dir2ogg is now installed. Enjoy..." dir2ogg-0.11.8/dir2ogg0000755000175000017500000007407311236076236014036 0ustar00jakjak00000000000000#!/usr/bin/python # # Copyright (C) 2007-2009 Julian Andres Klode # Copyright (C) 2003-2006 Darren Kirby # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ''' dir2ogg converts mp3, m4a, and wav files to the free open source OGG format. Oggs are about 20-25% smaller than mp3s with the same relative sound quality. Your mileage may vary. Keep in mind that converting from mp3 or m4a to ogg is a conversion between two lossy formats. This is fine if you just want to free up some disk space, but if you're a hard-core audiophile you may be dissapointed. I really can't notice a difference in quality with 'naked' ears myself. This script converts mp3s to wavs using mpg123 then converts the wavs to oggs using oggenc. m4a conversions require faad. Id3 tag support requires mutagen for mp3s. Scratch tags using the filename will be written for wav files (and mp3s with no tags!) ''' import sys import os, os.path import re import warnings from fnmatch import _cache, translate from optparse import OptionParser from subprocess import Popen, call, PIPE __version__ = '0.11.8' __date__ = '2009-08-04' FILTERS = {'mp3': ('*.mp3',), 'mpc': ('*.mpc','*.mpp', '*.mp+'), 'm4a': ('*.aac', '*.m4a', '*.mp4'), 'wma': ('*.asf', '*.wma', '*.wmf'), 'flac': ('*.flac',), 'ape': ('*.ape',), 'wv': ('*.wv','*.wvc'), 'wav': ('*.wav', ), } def mmatch(names, patterns, rbool=True): '''names/patterns=str/list/tuple''' results = [] if isinstance(names, (str, unicode)): names = [names] if isinstance(patterns, (str, unicode)): patterns = [patterns] for pat in patterns: pat = pat.lower() if not pat in _cache: _cache[pat] = re.compile(translate(pat)) match = _cache[pat].match for name in names: if match(name.lower()): if rbool: return True else: results.append(name) if rbool: return bool(results) else: return results def read_opts(): if not '--version' in sys.argv: show_banner() if len(sys.argv[1:]) == 0: fatal('No arguments specified, see --help for usage.') parser = OptionParser(usage='%prog [options] [arguments]', version='%prog ' + __version__) parser.add_option('-l', '--license', action='callback', callback=show_license, help='display license informations') parser.add_option('-d', '--directory', action='store_true', help='convert files in all directories specified as arguments (not needed anymore)') parser.add_option('-r', '--recursive', action='store_true', help='convert files in all subdirectories of all directories specified as arguments') parser.add_option('-c', '--cdda', action='store_true', help="convert audio cd in all devices specified as arguments (or default: /dev/cdrom) [EXPERIMENTAL]") parser.add_option('-q', '--quality', metavar='N', default=3.0, type='float', help='quality. N is a number from 1-10 (default %default)') parser.add_option('-t', '--smart-mp3', action='store_true', help='try to use similar quality as original mp3 file (overwrites -q)') parser.add_option('-T', '--smart-mp3-correction', metavar='N', default=0.0, type='float', help='decrease detected quality (implies -t)') parser.add_option('-n', '--no-mp3', dest='convert_mp3', action='store_false', default=True, help="don't convert mp3s (use with '-d' or '-r')") parser.add_option('-a', '--convert-all', action='store_true', help="convert all supported formats") parser.add_option('-A', '--convert-ape', action='store_true', help="convert all APE files found in directories.") parser.add_option('-f', '--convert-flac', action='store_true', help="convert all FLAC files found in directories") parser.add_option('-m', '--convert-m4a', action='store_true', help="convert all M4A files found in directories") parser.add_option('-M', '--convert-mpc', action='store_true', help="convert all MPC files found in directories") parser.add_option('-w', '--convert-wav', action='store_true', help="convert all WAV files found in directories") parser.add_option('-W', '--convert-wma', action='store_true', help="convert all WMA files found in directories") parser.add_option('-V', '--convert-wv', action='store_true', help="convert all WV files found in directories") parser.add_option('--delete-input', action='store_true', help='delete input files') parser.add_option('-p', '--preserve-wav', action='store_true', help='keep the wav files (also includes -P)') parser.add_option('-P', '--no-pipe', action='store_true', help='Do not use pipes, use temporary wav files') parser.add_option('-v', '--verbose', action='store_true', help='verbose output') parser.add_option('-Q', '--quiet', action='store_true', help='do not display progress report.') # Setup decoders commands = {'mp3': ('mpg123', 'mpg321', 'lame', 'mplayer'), 'wma': ('mplayer',), 'm4a': ('faad', 'mplayer'), 'flac': ('flac', 'ogg123', 'mplayer'), 'cd': ('cdparanoia', 'icedax','cdda2wav', 'mplayer'), 'ape': ('mac', 'mplayer'), 'wv': ('wvunpack', 'mplayer'), 'mpc': ('mpcdec', 'mplayer'), } for ext, dec in commands.items(): default, choices = None, [] for command in dec: in_path = [prefix for prefix in os.environ['PATH'].split(os.pathsep) if os.path.exists(os.path.join(prefix, command))] if in_path: choices.append(command) default = default or command parser.add_option('--' + ext + '-decoder', type="choice", metavar=default, default=default, choices=choices, help="decoder for %s files (choices: %s)" % (ext, ', '.join(choices))) # End of decoder options options, args = parser.parse_args() options.convert_cd = options.cdda options.filters = [] for ext, pat in FILTERS.items(): # Activate Encoders for files on the commandline if options.convert_all or mmatch(args, pat): setattr(options, 'convert_' + ext, True) if getattr(options, 'convert_' + ext): options.filters += pat # Missing decoders if ext != 'wav' and getattr(options, 'convert_' + ext) and not getattr(options, ext + '_decoder'): fatal('%s was enabled, but no decoder has been found.' % ext) if len(args) == 0 and not options.cdda: fatal('No files/directories specified.') return options, args def info(msg): print 'INFO: %s' % msg def warn(msg): '''print errors to the screen (red)''' print >> sys.stderr, "WARNING: %s" % msg def fatal(msg): '''Fatal error (error + exit)''' print >> sys.stderr, "ERROR: %s" % msg sys.exit(1) def return_dirs(root): mydirs = {} for pdir, dirs, files in os.walk(root): if not pdir in mydirs: mydirs[pdir] = files return mydirs class Id3TagHandler: '''Class for handling meta-tags. (Needs mutagen)''' accept = ['album', 'album_subtitle', 'albumartist', 'albumartistsort', 'albumsort', 'artist', 'artistsort', 'asin', 'bpm', 'comment', 'compilation', 'composer', 'composersort', 'conductor', 'copyright', 'date', 'discid', 'discnumber', 'encodedby', 'engineer', 'gapless', 'genre', 'grouping', 'isrc', 'label', 'lyricist', 'lyrics', 'mood', 'musicbrainz_albumartistid', 'musicbrainz_albumid', 'musicbrainz_artistid', 'musicbrainz_discid', 'musicbrainz_sortname', 'musicbrainz_trackid', 'musicbrainz_trmid', 'musicip_puid', 'podcast', 'podcasturl', 'releasecountry', 'musicbrainz_albumstatus', 'musicbrainz_albumtype', 'remixer', 'show', 'showsort', 'subtitle', 'title', 'titlesort', 'tracknumber', 'tracktotal'] def __init__(self, song): self.song = song self.tags = {} def grab_common(self, handler, convert=None, error=None): '''Common grabber, starts the handler and applies the tags to self.tags''' try: mydict = handler(self.song) except error, msg: import warnings,traceback; warn('Mutagen failed on %s, no tags available' % self.song) traceback.print_exc(0) print >> sys.stderr return if convert: convert = dict([(k.lower(), v.lower()) for k, v in convert.items()]) # Fix convert for key, val in mydict.items(): key = key.lower() key = convert and (key in convert and convert[key] or key) or key if not key in self.accept: continue if not convert: # Hack for FLAC, which uses Vorbis tags pass elif hasattr(val, 'text'): val = val.text if convert: new_val = [] if not isinstance(val, list): val = [val] for i in val: if not isinstance(i, unicode): # Convert all invalid values to unicode try: new_val.append(unicode(i)) except UnicodeDecodeError: warn('Ignoring UnicodeDecodeError in key %s' % key) new_val.append(unicode(i, errors='ignore')) else: new_val.append(i) val = new_val del new_val self.tags[key] = val def grab_ape_tags(self): '''Convert APE tags.''' from mutagen.apev2 import APEv2, error convert = {'year': 'date'} self.grab_common(APEv2, convert, error) grab_mpc_tags = grab_ape_tags # Musepack files use APEv2. grab_wv_tags = grab_ape_tags # WavPack files use APEv2. def grab_m4a_tags(self): '''Import MP4 tags handler, set convert and call commonGrab''' convert = {'----:com.apple.iTunes:ASIN': 'asin', '----:com.apple.iTunes:MusicBrainz Album Artist Id': 'musicbrainz_albumartistid', '----:com.apple.iTunes:MusicBrainz Album Id': 'musicbrainz_albumid', '----:com.apple.iTunes:MusicBrainz Album Release Country': 'releasecountry', '----:com.apple.iTunes:MusicBrainz Album Status': 'musicbrainz_albumstatus', '----:com.apple.iTunes:MusicBrainz Album Type': 'musicbrainz_albumtype', '----:com.apple.iTunes:MusicBrainz Artist Id': 'musicbrainz_artistid', '----:com.apple.iTunes:MusicBrainz Disc Id': 'musicbrainz_discid', '----:com.apple.iTunes:MusicBrainz TRM Id': 'musicbrainz_trmid', '----:com.apple.iTunes:MusicBrainz Track Id': 'musicbrainz_trackid', '----:com.apple.iTunes:MusicIP PUID': 'musicip_puid', 'aART': 'albumartist', 'cpil': 'compilation', 'cprt': 'copyright', 'pcst': 'podcast', 'pgap': 'gapless', 'purl': 'podcasturl', 'soaa': 'albumartistsort', 'soal': 'albumsort', 'soar': 'artistsort', 'soco': 'composersort', 'sonm': 'titlesort', 'sosn': 'showsort', 'trkn': 'tracknumber', 'tvsh': 'show', '\xa9ART': 'artist', '\xa9alb': 'album', '\xa9cmt': 'comment', '\xa9day': 'date', '\xa9gen': 'genre', '\xa9grp': 'grouping', '\xa9lyr': 'lyrics', '\xa9nam': 'title', '\xa9too': 'encodedby','\xa9wrt': 'composer'} try: from mutagen.mp4 import MP4, error except ImportError: from mutagen.m4a import M4A as MP4, error self.grab_common(MP4, convert, error) def grab_wma_tags(self): '''Import ASF tags handler, set convert and call commonGrab''' convert = {'Author': 'artist', 'Description': 'comment', 'MusicBrainz/Album Artist Id': 'musicbrainz_albumartistid', 'MusicBrainz/Album Id': 'musicbrainz_albumid', 'MusicBrainz/Album Release Country': 'releasecountry', 'MusicBrainz/Album Status': 'musicbrainz_albumstatus', 'MusicBrainz/Album Type': 'musicbrainz_albumtype', 'MusicBrainz/Artist Id': 'musicbrainz_artistid', 'MusicBrainz/Disc Id': 'musicbrainz_discid', 'MusicBrainz/TRM Id': 'musicbrainz_trmid', 'MusicBrainz/Track Id': 'musicbrainz_trackid', 'MusicIP/PUID': 'musicip_puid', 'WM/AlbumArtist': 'albumartist', 'WM/AlbumArtistSortOrder': 'albumartistsort', 'WM/AlbumSortOrder': 'albumsort', 'WM/AlbumTitle': 'album', 'WM/ArtistSortOrder': 'artistsort', 'WM/BeatsPerMinute': 'bpm', 'WM/Composer': 'composer', 'WM/Conductor': 'conductor', 'WM/ContentGroupDescription': 'grouping', 'WM/Copyright': 'copyright', 'WM/EncodedBy': 'encodedby', 'WM/Genre': 'genre', 'WM/ISRC': 'isrc', 'WM/Lyrics': 'lyrics', 'WM/ModifiedBy': 'remixer', 'WM/Mood': 'mood', 'WM/PartOfSet': 'discnumber', 'WM/Producer': 'engineer', 'WM/Publisher': 'label', 'WM/SetSubTitle': 'album_subtitle', 'WM/SubTitle': 'subtitle', 'WM/TitleSortOrder': 'titlesort', 'WM/TrackNumber': 'tracknumber', 'WM/Writer': 'lyricist', 'WM/Year': 'date', } from mutagen.asf import ASF, error self.grab_common(ASF, convert, error) def grab_flac_tags(self): '''Import MP3 tags handler, and call commonGrab''' from mutagen.flac import FLAC, error self.grab_common(FLAC, error=error) def grab_mp3_tags(self): '''Import MP3 tags handler, and call commonGrab''' from mutagen.id3 import ID3, error convert = {'TPE1': 'artist', 'TPE2': 'albumartist', 'TPE3': 'conductor', 'TPE4': 'remixer', 'TCOM': 'composer', 'TCON': 'genre', 'TALB': 'album', 'TIT1': 'grouping', 'TIT2': 'title', 'TIT3': 'subtitle', 'TSST': 'discsubtitle', 'TEXT': 'lyricist', 'TCMP': 'compilation', 'TDRC': 'date', 'COMM': 'comment', 'TMOO': 'mood', 'TMED': 'media', 'TBPM': 'bpm', 'WOAR': 'website', 'TSRC': 'isrc', 'TENC': 'encodedby', 'TCOP': 'copyright', 'TSOA': 'albumsort', 'TSOP': 'artistsort', 'TSOT': 'titlesort','TPUB': 'label', 'TRCK': 'tracknumber'} self.grab_common(ID3, convert, error) def list_if_verbose(self): info('Meta-tags I will write:') for key, val in self.tags.items(): if type(val) == list: info(key + ': ' + ','.join(val)) else: info(key + ': ' + val) class Convert(Id3TagHandler): ''' Base conversion Class. __init__ creates some useful attributes, grabs the id3 tags, and sets a flag to remove files. Methods are the conversions we can do ''' def __init__(self, song, conf): self.device = "" self.track = "" Id3TagHandler.__init__(self, song) self.conf = conf song_root = os.path.splitext(song)[0] + "." self.songwav = song_root + 'wav' self.songogg = song_root + 'ogg' self.decoder = '' # (smartmp3) I have to remember default quality for next files original_quality = self.conf.quality for ext, pat in FILTERS.items(): if mmatch(self.song, pat) and ext != 'wav': self.decoder = getattr(self.conf, ext + '_decoder') getattr(self, 'grab_%s_tags' % ext)() if ext == 'mp3' and (self.conf.smart_mp3 or \ self.conf.smart_mp3_correction): self.smart_mp3() self.convert() # (smartmp3) Replacing quality by default value self.conf.quality = original_quality def smart_mp3(self): # initial Code by Marek Palatinus , 2007 # Table of quality = relation between mp3 bitrate and vorbis quality. Source: wikipedia # quality_table = {45:-1, 64:0, 80:1, 96:2, 112:3, 128:4, 160:5, 192:6, 224:7, 256:8, 320:9, 500:10 } # log(0.015*bitrate, 1.19) is logaritmic regression of table above. Useful for mp3s in VBR :-). try: from mutagen.mp3 import MP3, HeaderNotFoundError except ImportError: warn('(smartmp3) You dont have mutagen installed. Bitrate detection failed. Using default quality %.02f' % self.conf.quality) return try: mp3info = MP3(self.song) bitrate = mp3info.info.bitrate except HeaderNotFoundError: info('(smartmp3) File is not an mp3 stream. Using default quality %.02f' % self.conf.quality) return import math self.conf.quality = round(5.383 * math.log(0.01616 * bitrate/1000.) - self.conf.smart_mp3_correction, 2) self.conf.quality = max(self.conf.quality, -1) # Lowest quality is -1 self.conf.quality = min(self.conf.quality, 10) # Highest quality is 10 info("(smartmp3) Detected bitrate: %d kbps" % (bitrate/1000)) info("(smartmp3) Assumed vorbis quality: %.02f" % self.conf.quality) def decode(self): # Used for mplayer tempwav = 'dir2ogg-%s-temp.wav' % os.getpid() if self.decoder not in ('mplayer',) and not self.conf.no_pipe and not self.conf.preserve_wav: outfile, outfile1 = '-', '/dev/stdout' use_pipe = 1 else: outfile = outfile1 = self.songwav use_pipe = 0 decoder = {'mpg123': ['mpg123', '-q', '-w', outfile1, self.song], 'mpg321': ['mpg321', '-q', '-w', outfile, self.song], 'faad': ['faad', '-q', '-o' , outfile1, self.song], 'ogg123': ['ogg123', '-q', '-dwav', '-f' , outfile, self.song], 'flac': ['flac', '-s', '-o', outfile, '-d', self.song], 'lame': ['lame', '--quiet', '--decode', self.song, outfile], 'mac': ['mac', self.song, outfile, '-d'], 'mpcdec': ['mpcdec', self.song, outfile], 'mplayer': ['mplayer', '-really-quiet', '-vo', 'null', '-vc' ,'dummy', '-af', 'resample=44100', '-ao', 'pcm:file=' + tempwav, self.song], 'wvunpack': ['wvunpack', '-q', self.song, '-o', outfile], 'alac-decoder': ['alac-decoder', self.song], 'cd-cdparanoia': ['cdparanoia', '-Z', '-q', '-w', '-d', self.device, str(self.track), outfile], 'cd-icedax': ['icedax', '-H', '-t', str(self.track), '-D',self.device], 'cd-cdda2wav': ['cdda2wav', '-H', '-t', str(self.track), '-D',self.device], 'cd-mplayer': ['mplayer', '-vo', 'null', '-vc' ,'dummy', '-af', 'resample=44100', '-ao', 'pcm:file=temp.wav', '-cdrom-device', self.device, "cdda://" + str(self.track)]} if use_pipe: return True, Popen(decoder[self.decoder], stdout=PIPE) else: decoder['cd-cdparanoia'].remove('-q') decoder['lame'].remove('--quiet') retcode = call(decoder[self.decoder]) if self.decoder == 'mplayer': # Move the file for mplayer (which uses tempwav), so it works # for --preserve-wav. os.rename(tempwav, self.songwav) if retcode != 0: return (False, None) else: return (True, None) def convert(self): ''' Convert wav -> ogg.''' info('Converting "%s" (using %s as decoder)...' % (self.song, self.decoder)) if self.songwav == self.song: success = True dec = None else: success, dec = self.decode() if not success: warn('Decoding of "%s" with %s failed.' % (self.song, self.decoder)) return if dec and self.decoder == 'mpg123': import mutagen opts=['-r', '-R', str(mutagen.File(self.song).info.sample_rate)] else: opts=[] if self.conf.quiet: opts.append("--quiet") if dec: enc = Popen(['oggenc', '-o', self.songogg, '-q', str(self.conf.quality).replace('.', ','), '-'] + opts, stdin=dec.stdout) enc.communicate() dec.wait() if dec.returncode < 0: warn('Decoding of "%s" with %s failed.' % (self.song, self.decoder)) return False elif enc.returncode < 0: warn('Encoding of "%s" failed.' % self.song) return False else: enc = call(['oggenc', '-o', self.songogg, '-q', str(self.conf.quality).replace('.', ','), self.songwav] + opts) if enc != 0: warn('Encoding of "%s" failed.' % self.songwav) return False elif not self.conf.preserve_wav and self.song != self.songwav: os.remove(self.songwav) if self.tags != {}: try: # Add tags to the ogg file from mutagen.oggvorbis import OggVorbis myogg = OggVorbis(self.songogg) myogg.update(self.tags) myogg.save() except: warn('Could not save the tags') import traceback traceback.print_exc() return False elif self.songwav != self.song or 'cd-' in self.decoder: warn('No tags found...') if self.conf.delete_input: os.remove(self.song) return True class ConvertTrack(Convert): '''Wrapper around Convert for CD Tracks''' def __init__(self, device, conf, track, tags): self.device, self.track, self.tags, self.conf = device, track, tags, conf self.song = '' self.songwav = "audio.wav" self.songogg = "%(artist)s/%(album)s/%(ntracknumber)s - %(title)s.ogg" % tags self.conf.preserve_wav = False self.decoder = 'cd-' + self.conf.cd_decoder self.convert() class ConvertDisc: '''Wrapper around ConvertTrack to Convert complete cds Currently uses MusicBrainz, but a CDDB fallback will be added, too.''' def __init__(self, dev, conf): warn("Converting CDs is not well supported, please use another " "solution.") self.dev, self.conf = dev, conf try: self.get_mb() except self.MBError: warn('MusicBrainz failed. Trying FreeDB...') self.get_cddb() class MBError(Exception): '''Empty''' def get_cddb(self): try: import CDDB, DiscID except ImportError: fatal('You need python-cddb (http://cddb-py.sf.net) to convert cds. Please install it.') disc_id = DiscID.disc_id(DiscID.open(self.dev)) query_info = CDDB.query(disc_id)[1] if not query_info: fatal('The disk is not listed in FreeDB, dir2ogg only supports disk listed in MusicBrainz or FreeDB') if isinstance(query_info, list): query_info = query_info[0] read_info = CDDB.read(query_info['category'], query_info['disc_id'])[1] for track in range(disc_id[1]): title = {} title['discid'] = query_info['disc_id'] title['artist'], title['album'] = (track.strip() for track in query_info['title'].split("/")) title['genre'] = read_info['DGENRE'] title['date'] = read_info['DYEAR'] title['title'] = read_info['TTITLE' + str(track)] title['tracktotal'] = str(len(range(disc_id[1])) + 1) title['ntracknumber'] = '0' * (len(title['tracktotal'] ) - len(str(track+1)) ) + str(track+1) title['tracknumber'] = str(track+1) for key, val in title.items(): title[key] = unicode(str(val), "ISO-8859-1") ConvertTrack(self.dev, self.conf, track+1, title) def get_mb(self): try: import musicbrainz2.disc as mbdisc import musicbrainz2.webservice as mbws except ImportError, err: warn('You need python-musicbrainz2 (or python-cddb) to convert cds. Please install it. Trying cddb.') raise self.MBError, err service = mbws.WebService() query = mbws.Query(service) # Read the disc in the drive try: disc = mbdisc.readDisc(self.dev) except mbdisc.DiscError, err: warn(err) raise self.MBError discId = disc.getId() try: myfilter = mbws.ReleaseFilter(discId=discId) results = query.getReleases(myfilter) except mbws.WebServiceError, err: warn(err) raise self.MBError if len(results) == 0: print "Disc is not yet in the MusicBrainz database." print "Consider adding it via", mbdisc.getSubmissionUrl(disc) raise self.MBError try: inc = mbws.ReleaseIncludes(artist=True, tracks=True, releaseEvents=True) release = query.getReleaseById(results[0].release.getId(), inc) except mbws.WebServiceError, err: warn(err) raise self.MBError isSingleArtist = release.isSingleArtistRelease() try: # try to get the CDDB ID import DiscID cddb_id = '%08lx' % long(DiscID.disc_id(DiscID.open(self.dev))[0]) except: cddb_id = False trackn = 1 for track in release.tracks: title = {} title['artist'] = isSingleArtist and release.artist.name or track.artist if cddb_id: title['discid'] = cddb_id title['album'] = release.title title['date'] = release.getEarliestReleaseDate() title['musicbrainz_albumartistid'] = release.artist.id.split("/")[-1] title['musicbrainz_albumid'] = release.id.split("/")[-1] title['musicbrainz_discid'] = discId title['musicbrainz_sortname'] = release.artist.sortName title['musicbrainz_trackid'] = track.id.split("/")[-1] title['title'] = track.title title['tracktotal'] = str(len(release.tracks)) title['ntracknumber'] = "%02d" % trackn title['tracknumber'] = str(trackn) ConvertTrack(self.dev, self.conf, trackn, title) trackn+=1 class ConvertDirectory: ''' This class is just a wrapper for Convert. Grab the songs to convert, then feed them one by one to the Convert class. ''' def __init__(self, conf, directory, files): ''' Decide which files will be converted.''' if os.path.exists(directory) == 0: fatal('Directory: "%s" not found' % directory) self.directory = directory = os.path.normpath(directory) + os.path.sep self.songs = sorted(mmatch(files, conf.filters, False)) if conf.verbose: self.print_if_verbose() for song in self.songs: Convert(directory + song, conf) def print_if_verbose(self): ''' Echo files to be converted if verbose flag is set.''' info('In %s I am going to convert:' % self.directory) for song in self.songs: print " ", song def show_banner(): print 'dir2ogg %s (%s), converts audio files into ogg vorbis.\n' % (__version__, __date__) def show_license(*args, **kwargs): print 'Copyright (C) 2007-2009 Julian Andres Klode ' print 'Copyright (C) 2003-2006 Darren Kirby \n' print 'This program is distributed in the hope that it will be useful,' print 'but WITHOUT ANY WARRANTY; without even the implied warranty of' print 'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the' print 'GNU General Public License for more details.\n' print 'Currently developed by Julian Andres Klode .' sys.exit(0) def main(): conf = read_opts() conf_args, conf = conf[1], conf[0] if conf.cdda: discs = len(conf_args) and conf_args or ("/dev/cdrom",) for disc in discs: ConvertDisc(disc, conf) else: rdirs = {} for path in conf_args: if not os.path.exists(path): fatal('Path %r does not exists' % path) if os.path.isfile(path): dirname = os.path.dirname(os.path.abspath(path)) try: rdirs[dirname].append(os.path.basename(path)) except KeyError: rdirs[dirname] = [os.path.basename(path)] elif not os.path.isdir(path): fatal('%r must be a directory or a file.' % path) elif conf.recursive: rdirs.update(return_dirs(os.path.abspath(path))) else: rdirs[os.path.abspath(path)] = os.listdir(path) for directory, files in rdirs.items(): ConvertDirectory(conf, directory, files) sys.exit(0) if __name__ == '__main__': # mutagen._util sometimes has problems when calling struct.pack(). warnings.filterwarnings("ignore", category=DeprecationWarning, module="mutagen.*", message='.*<= number <=.*') main() dir2ogg-0.11.8/COPYING0000644000175000017500000004310311236076236013574 0ustar00jakjak00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. dir2ogg-0.11.8/dir2ogg.10000644000175000017500000001133211236076236014157 0ustar00jakjak00000000000000.TH DIR2OGG 1 "2009-08-04" "dir2ogg 0.11.8" .SH NAME dir2ogg \- Convert MP3, WAV, and M4A files to OGG format .SH SYNOPSIS \fBdir2ogg\fP [ options ] ( \fIfilename\fP [\fIfilename2\fP] ... || \fIdirectory\fP [\fIdirectory2\fP] ... || [\fIcdrom-device\fP] ... ) .SH DESCRIPTION \fIdir2ogg\fP converts MP3, M4A, WMA and WAV files to the open\-source OGG format. \fIdir2ogg\fP is a python script that simply binds together mpg123, faad, and oggenc making it easier for the user to convert his/her music files. OGGs are about 15 to 20 percent smaller than MP3 files, with the same relative audio quality. \fIdir2ogg\fP can be called with the \fI\-d\fP flag at the command line to convert any number of directories at once, or given MP3, M4A, WMA, and/or WAV filenames as arguments, \fIdir2ogg\fP will convert only those files. If converting WAV, M4A or WMA files with \fI\-d\fP you must add the \fI\-w\fP, \fI\-m\fP or \fI\-W\fP command line flags respectively. These flags are not neccesary unless using \fI\-d\fP. Note that converting M4A files requires you to have faad installed, and converting WMA files requires mplayer. Keep in mind that converting from MP3 or M4A to OGG is a conversion between two lossy formats. This is fine if you just want to free up some disk space, but if you're a hard\-core audiophile you may be disappointed. I really can't notice a difference in quality with 'naked' ears myself. .SS General Options .TP \fB\-h or \-\-help\fP print quick usage details to the screen. .TP \fB\-d or \-\-directory\fP convert all MP3 files in \fIdirectory\fP. WAV and M4A files will be converted if used with the \fI\-w\fP and \fI\-m\fP command line flags. This option is for compatibility purposes only and does not need to be specified anymore. .TP \fB\-r or \-\-recursive\fP like \fI\-d\fP but descends recursively into directories. .TP \fB\-c or \-\-cdda\fP Convert an audio CD into ogg. You may pass the device as an argument to the script (default: /dev/cdrom). Requires cdparanoia orq icedax or mplayer .TP \fB\-p or \-\-preserve-wav\fP preserve all WAV files. By default they are deleted. .TP \fB\-P or \-\-no\-pipe\fP Do not use pipes to send data from the decoder to the encoder, use temporary wav files instead. .TP \fB\-\-delete-input\fP Delete the input file after conversion .TP \fB\-v or \-\-verbose\fP increase \fIdir2ogg\fP's verbosity. .TP \fB\-Q or \-\-quiet\fP Do not display progress messages, except the name of the file which is currently converted. Some decoders provide no way to disable messages and thus may still display some. .SS Conversion options .TP \fB\-\-convert-all\fP Convert all supported audio files found in the directories given on the command-line to Ogg Vorbis. .TP \fB\-f or \-\-convert-ape\fP Convert all APE (Monkey's Audio) files found in the directories given on the command-line to Ogg Vorbis, using either ogg123 or flac or mplayer. .TP \fB\-f or \-\-convert-flac\fP Convert all FLAC (Free Lossless Audio Codec) files found in the directories given on the command-line to Ogg Vorbis, using ogg123 or flac or mplayer. .TP \fB\-m or \-\-convert-m4a\fP convert all M4A (MPEG-4 Audio) files found in the directories given on the command-line to Ogg Vorbis, using faad or mplayer. For decoding ALAC (Apple Lossless) files, 'alac-decoder' may be used. .TP \fB\-m or \-\-convert-mpc\fP convert all MPC (MusePack) files found in the directories given on the command-line to Ogg Vorbis, using mpcdec or mplayer. .TP \fB\-W or \-\-convert-wma\fP Convert all WMA (Windows Media Audio) files found in the directories given on the command-line to Ogg Vorbis, using mplayer. .TP \fB\-w or \-\-convert-wav\fP Convert all WAV files found in the directories given on the command-line to Ogg Vorbis. .TP \fB\-V or \-\-convert-wv\fP Convert all WV (WavPack) files found in the directories given on the command-line to Ogg Vorbis. .TP \fB\-n or \-\-no-mp3\fP ingore all MP3 files found in directories given on the command-line. .TP \fB\-\-(ape|cd|flac|m4a|mp3|mpc|wma|wv)\-decoder=COMMAND\fP Set the decoder you want to use for one filetype, e.g.: \-\-mp3-decoder=lame. Run dir2ogg \-\-help to see the available decoders. .TP \fB\-qN or \-\-quality=N\fP OGG quality. N is a number between \-1 and 10. Default is 3. Decimals are OK (ie: 3.7) .TP \fB\-t or \-\-smart\-mp3 Try to use the same quality as the input file. MP3 input only! .SH "SEE ALSO" \fImpg123\fP(1), \fImplayer\fP(1), \fIoggenc\fP(1) .SH BUGS Enter you bug reports in Launchpad at https://bugs.launchpad.net/dir2ogg .SH AUTHORS .PD 0 .TP \fB0.10 and newer:\fP Julian Andres Klode .TP \fB0.9.3 and older:\fP Darren Kirby .PD .SH CONTRIBUTORS .PD 0 .TP \fBoriginal wma support:\fP Cameron Stone .TP \fBsmart-mp3:\fP Marek Palatinus