+++ /dev/null
-# -*- coding: utf-8 -*-
-
-from timeside.export.api import *
-from timeside.export.core import *
-from timeside.export.ogg import *
-from timeside.export.flac import *
-from timeside.export.wav import *
-from timeside.export.mp3 import *
\ No newline at end of file
+++ /dev/null
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2007-2009 Parisson
-# Copyright (c) 2007 Olivier Guilyardi <olivier@samalyse.com>
-# Copyright (c) 2007-2009 Guillaume Pellerin <pellerin@parisson.com>
-#
-# This file is part of TimeSide.
-
-# TimeSide 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.
-
-# TimeSide 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 TimeSide. If not, see <http://www.gnu.org/licenses/>.
-
-from timeside.core import Interface, TimeSideError
-
-class IExporter(Interface):
- """Export driver interface"""
-
- # Remark: the method prototypes do not include any self or cls argument
- # because an interface is meant to show what methods a class must expose
- # from the caller's point of view. However, when implementing the class
- # you'll obviously want to include this extra argument.
-
- def get_format():
- """Return the export/encoding format as a short string
- Example: "MP3", "OGG", "AVI", ...
- """
-
- def get_description():
- """Return a string describing what this export format provides, is good
- for, etc... The description is meant to help the end user decide what
- format is good for him/her
- """
-
- def get_file_extension():
- """Return the filename extension corresponding to this export format"""
-
- def get_mime_type():
- """Return the mime type corresponding to this export format"""
-
- def set_cache_dir(path):
- """Set the directory where cached files should be stored. Does nothing
- if the exporter doesn't support caching.
-
- The driver shouldn't assume that this method will always get called. A
- temporary directory should be used if that's not the case.
- """
-
- def process(item_id, source, metadata, options=None):
- """Perform the exporting process and return the absolute path
- to the resulting file.
-
- item_id is the media item id that uniquely identifies this audio/video
- resource
-
- source is the audio/video source file absolute path. For audio that
- should be a WAV file
-
- metadata is a tuple containing tuples for each descriptor return by
- the dc.Ressource of the item, in the model order :
- ((name1, value1),(name2, value2),(name1, value3), ...)
-
- The returned file path is not meant to be permanent in any way, it
- should be considered temporary/volatile by the caller.
-
- It is highly recommended that export drivers implement some sort of
- cache instead of re-encoding each time process() is called.
-
- It should be possible to make subsequent calls to process() with
- different items, using the same driver instance.
- """
-
-class ExportProcessError(TimeSideError):
-
- def __init__(self, message, command, subprocess):
- self.message = message
- self.command = str(command)
- self.subprocess = subprocess
-
- def __str__(self):
- if self.subprocess.stderr != None:
- error = self.subprocess.stderr.read()
- else:
- error = ''
- return "%s ; command: %s; error: %s" % (self.message,
- self.command,
- error)
+++ /dev/null
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2007-2009 Guillaume Pellerin <yomguy@parisson.com>
-
-# This file is part of TimeSide.
-
-# TimeSide 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.
-
-# TimeSide 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 TimeSide. If not, see <http://www.gnu.org/licenses/>.
-
-# Author: Guillaume Pellerin <yomguy@parisson.com>
-
-import os
-import re
-import md5
-import string
-import subprocess
-import mutagen
-
-from timeside.export import *
-from timeside.core import *
-import xml.dom.minidom
-import xml.dom.ext
-
-class ExporterCore(Component):
- """Defines the main parts of the exporting tools :
- paths, metadata parsing, data streaming thru system command"""
-
- def __init__(self):
- self.source = ''
- self.collection = ''
- self.verbose = ''
- self.dest = ''
- self.metadata = []
- self.cache_dir = 'cache'
- self.buffer_size = 0xFFFF
-
- def set_cache_dir(self,path):
- self.cache_dir = path
-
- def normalize(self):
- """ Normalize the source and return its path """
- args = ''
- if self.verbose == '0':
- args = '-q'
- try:
- os.system('normalize-audio '+args+' "'+self.source+'"')
- return self.source
- except:
- raise IOError('ExporterError: cannot normalize, path does not exist.')
-
- def check_md5_key(self):
- """ Check if the md5 key is OK and return a boolean """
- try:
- md5_log = os.popen4('md5sum -c "'+self.dest+ \
- '" "'+self.dest+'.md5"')
- return 'OK' in md5_log.split(':')
- except IOError:
- raise IOError('ExporterError: cannot check the md5 key.')
-
- def get_file_info(self):
- """ Return the list of informations of the dest """
- return self.export.get_file_info()
-
- def get_wav_length_sec(self) :
- """ Return the length of the audio source file in seconds """
- try:
- file1, file2 = os.popen4('wavinfo "'+self.source+ \
- '" | grep wavDataSize')
- for line in file2.readlines():
- line_split = line.split(':')
- value = int(int(line_split[1])/(4*44100))
- return value
- except:
- raise IOError('ExporterError: cannot get the wav length.')
-
- def compare_md5_key(self, source, dest):
- """ Compare source and dest files wih md5 method """
- f_source = open(source).read()
- f_dest = open(dest).read()
- return md5.new(f_source).digest() == md5.new(f_dest).digest()
-
- def write_metadata_xml(self,path):
- doc = xml.dom.minidom.Document()
- root = doc.createElement('timeside')
- doc.appendChild(root)
- for tag in self.metadata.keys() :
- value = self.metadata[tag]
- node = doc.createElement(tag)
- node.setAttribute('value', str(value))
- #node.setAttribute('type', get_type(value))
- root.appendChild(node)
- xml_file = open(path, "w")
- xml.dom.ext.PrettyPrint(doc, xml_file)
- xml_file.close()
-
- def pre_process(self, item_id, source, metadata, ext,
- cache_dir, options=None):
- """ Pre processing : prepare the export path and return it"""
- self.item_id = str(item_id)
- self.source = source
- file_name = get_file_name(self.source)
- file_name_wo_ext, file_ext = split_file_name(file_name)
- self.cache_dir = cache_dir
- self.metadata = metadata
- #self.collection = self.metadata['Collection']
- #self.artist = self.metadata['Artist']
- #self.title = self.metadata['Title']
-
- # Normalize if demanded
- if not options is None:
- self.options = options
- if 'normalize' in self.options and \
- self.options['normalize'] == True:
- self.normalize()
-
- # Define the export directory
- self.ext = self.get_file_extension()
- export_dir = os.path.join(self.cache_dir,self.ext)
-
- if not os.path.exists(export_dir):
- export_dir_split = export_dir.split(os.sep)
- path = os.sep + export_dir_split[0]
- for _dir in export_dir_split[1:]:
- path = os.path.join(path,_dir)
- if not os.path.exists(path):
- os.mkdir(path)
- else:
- path = export_dir
-
- # Set the target file
- target_file = self.item_id+'.'+self.ext
- dest = os.path.join(path,target_file)
- return dest
-
- def core_process(self, command, buffer_size, dest):
- """Encode and stream audio data through a generator"""
-
- __chunk = 0
- file_out = open(dest,'w')
-
- proc = subprocess.Popen(command.encode('utf-8'),
- shell = True,
- bufsize = buffer_size,
- stdin = subprocess.PIPE,
- stdout = subprocess.PIPE,
- close_fds = True)
-
- # Core processing
- while True:
- __chunk = proc.stdout.read(buffer_size)
- status = proc.poll()
- if status != None and status != 0:
- raise ExportProcessError('Command failure:', command, proc)
- if len(__chunk) == 0:
- break
- yield __chunk
- file_out.write(__chunk)
-
- file_out.close()
-
- def post_process(self, item_id, source, metadata, ext,
- cache_dir, options=None):
- """ Post processing : write tags, print infos, etc..."""
- #self.write_tags()
- if not options is None:
- if 'verbose' in self.options and self.options['verbose'] != '0':
- print self.dest
- print self.get_file_info()
-
-
-# External functions
-
-def get_type(value):
- """ Return a String with the type of value """
- types = {bool : 'bool', int : 'int', str : 'str'}
- # 'bool' type must be placed *before* 'int' type, otherwise booleans are
- # detected as integers
- for type in types.keys():
- if isinstance(value, type) :
- return types[type]
- raise TypeError(str(value) + ' has an unsupported type')
-
-def get_cast(value, type) :
- """ Return value, casted into type """
- if type == 'bool' :
- if value == 'True' :
- return True
- return False
- elif type == 'int' :
- return int(value)
- elif type == 'str' :
- return str(value)
- raise TypeError(type + ' is an unsupported type')
-
-def get_file_mime_type(path):
- """ Return the mime type of a file """
- try:
- file_out1, file_out2 = os.popen4('file -i "'+path+'"')
- for line in file_out2.readlines():
- line_split = line.split(': ')
- mime = line_split[len(line_split)-1]
- return mime[:len(mime)-1]
- except:
- raise IOError('ExporterError: path does not exist.')
-
-def get_file_type_desc(path):
- """ Return the type of a file given by the 'file' command """
- try:
- file_out1, file_out2 = os.popen4('file "'+path+'"')
- for line in file_out2.readlines():
- description = line.split(': ')
- description = description[1].split(', ')
- return description
- except:
- raise IOError('ExporterError: path does not exist.')
-
-def iswav(path):
- """ Tell if path is a WAV """
- try:
- mime = get_file_mime_type(path)
- return mime == 'audio/x-wav'
- except:
- raise IOError('ExporterError: path does not exist.')
-
-def iswav16(path):
- """ Tell if path is a 16 bit WAV """
- try:
- file_type_desc = get_file_type_desc(path)
- return iswav(path) and '16 bit' in file_type_desc
- except:
- raise IOError('ExporterError: path does not exist.')
-
-def get_file_name(path):
- """ Return the file name targeted in the path """
- return os.path.split(path)[1]
-
-def split_file_name(file):
- """ Return main file name and its extension """
- try:
- return os.path.splitext(file)
- except:
- raise IOError('ExporterError: path does not exist.')
-
-def clean_word(word) :
- """ Return the word without excessive blank spaces, underscores and
- characters causing problem to exporters"""
- word = re.sub("^[^\w]+","",word) #trim the beginning
- word = re.sub("[^\w]+$","",word) #trim the end
- word = re.sub("_+","_",word) #squeeze continuous _ to one _
- word = re.sub("^[^\w]+","",word) #trim the beginning _
- #word = string.replace(word,' ','_')
- #word = string.capitalize(word)
- dict = '&[];"*:,'
- for letter in dict:
- word = string.replace(word,letter,'_')
- return word
-
-def recover_par_key(path):
- """ Recover a file with par2 key """
- os.system('par2 r "'+path+'"')
-
-def verify_par_key(path):
- """ Verify a par2 key """
- os.system('par2 v "'+path+'.par2"')
-
-
+++ /dev/null
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2007-2009 Guillaume Pellerin <yomguy@parisson.com>
-
-# This file is part of TimeSide.
-
-# TimeSide 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.
-
-# TimeSide 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 TimeSide. If not, see <http://www.gnu.org/licenses/>.
-
-# Author: Guillaume Pellerin <yomguy@parisson.com>
-
-import os
-import string
-import subprocess
-
-from timeside.export.core import *
-from timeside.export.api import IExporter
-from mutagen.flac import FLAC
-from tempfile import NamedTemporaryFile
-
-class FlacExporter(ExporterCore):
- """Defines methods to export to FLAC"""
-
- implements(IExporter)
-
- def __init__(self):
- self.item_id = ''
- self.source = ''
- self.metadata = {}
- self.options = {}
- self.description = ''
- self.dest = ''
- self.quality_default = '-5'
- self.info = []
- self.buffer_size = 0xFFFF
-
- def get_format(self):
- return 'FLAC'
-
- def get_file_extension(self):
- return 'flac'
-
- def get_mime_type(self):
- return 'application/flac'
-
- def get_description(self):
- return 'FIXME'
-
- def get_file_info(self):
- try:
- file1, file2 = os.popen4('metaflac --list "'+self.dest+'"')
- info = []
- for line in file2.readlines():
- info.append(clean_word(line[:-1]))
- self.info = info
- return self.info
- except:
- raise IOError('ExporterError: metaflac is not installed or ' + \
- 'file does not exist.')
-
- def set_cache_dir(self,path):
- """Set the directory where cached files should be stored. Does nothing
- if the exporter doesn't support caching.
-
- The driver shouldn't assume that this method will always get called. A
- temporary directory should be used if that's not the case.
- """
- self.cache_dir = path
-
- def decode(self):
- try:
- file_name, ext = get_file_name(self.source)
- dest = self.cache_dir+os.sep+file_name+'.wav'
- os.system('flac -d -o "'+dest+'" "'+self.source+'"')
- self.source = dest
- return dest
- except:
- raise IOError('ExporterError: decoder is not compatible.')
-
- def write_tags(self, file):
- media = FLAC(file)
- for tag in self.metadata:
- name = tag[0]
- value = clean_word(tag[1])
- if name == 'COMMENT':
- media['DESCRIPTION'] = unicode(value)
- else:
- media[name] = unicode(value)
- try:
- media.save()
- except:
- raise IOError('ExporterError: cannot write tags.')
-
- def get_args(self,options=None):
- """Get process options and return arguments for the encoder"""
- args = []
- if not options is None:
- self.options = options
- if not ('verbose' in self.options and self.options['verbose'] != '0'):
- args.append('-s')
- if 'flac_quality' in self.options:
- args.append('-f ' + self.options['flac_quality'])
- else:
- args.append('-f ' + self.quality_default)
- else:
- args.append('-s -f ' + self.quality_default)
-
- #for tag in self.metadata.keys():
- #value = clean_word(self.metadata[tag])
- #args.append('-c %s="%s"' % (tag, value))
- #if tag in self.dub2args_dict.keys():
- #arg = self.dub2args_dict[tag]
- #args.append('-c %s="%s"' % (arg, value))
-
- return args
-
- def process(self, item_id, source, metadata, options=None):
- self.item_id = item_id
- self.source = source
- self.metadata = metadata
- self.args = self.get_args(options)
- self.ext = self.get_file_extension()
- self.args = ' '.join(self.args)
- self.command = 'sox "%s" -s -q -b 16 -r 44100 -t wav -c2 - | flac -c %s - ' % (self.source, self.args)
-
- # Pre-proccessing
- self.dest = self.pre_process(self.item_id,
- self.source,
- self.metadata,
- self.ext,
- self.cache_dir,
- self.options)
-
- # Processing (streaming + cache writing)
- stream = self.core_process(self.command, self.buffer_size, self.dest)
-
- for chunk in stream:
- pass
-
- self.write_tags(self.dest)
- file = open(self.dest,'r')
-
- while True:
- chunk = file.read(self.buffer_size)
- if len(chunk) == 0:
- break
- yield chunk
-
- file.close()
-
- # Post-proccessing
- #self.post_process(self.item_id,
- #self.source,
- #self.metadata,
- #self.ext,
- #self.cache_dir,
- #self.options)
-
+++ /dev/null
-# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2007 Parisson SARL
-# Copyright (c) 2006-2007 Guillaume Pellerin <pellerin@parisson.com>
-
-# This file is part of TimeSide.
-
-# TimeSide 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.
-
-# TimeSide 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 TimeSide. If not, see <http://www.gnu.org/licenses/>.
-
-# Author: Guillaume Pellerin <yomguy@parisson.com>
-
-import os
-import string
-import subprocess
-
-from timeside.export.core import *
-from timeside.export.api import IExporter
-#from mutagen.id3 import *
-
-class Mp3Exporter(ExporterCore):
- """Defines methods to export to MP3"""
-
- implements(IExporter)
-
- def __init__(self):
- self.item_id = ''
- self.metadata = {}
- self.description = ''
- self.info = []
- self.source = ''
- self.dest = ''
- self.options = {}
- self.bitrate_default = '192'
- self.buffer_size = 0xFFFF
- self.dub2id3_dict = {'title': 'TIT2', #title2
- 'creator': 'TCOM', #composer
- 'creator': 'TPE1', #lead
- 'identifier': 'UFID', #Unique ID...
- 'identifier': 'TALB', #album
- 'type': 'TCON', #genre
- 'publisher': 'TPUB', #comment
- #'date': 'TYER', #year
- }
- self.dub2args_dict = {'title': 'tt', #title2
- 'creator': 'ta', #composerS
- 'relation': 'tl', #album
- #'type': 'tg', #genre
- 'publisher': 'tc', #comment
- 'date': 'ty', #year
- }
- def get_format(self):
- return 'MP3'
-
- def get_file_extension(self):
- return 'mp3'
-
- def get_mime_type(self):
- return 'audio/mpeg'
-
- def get_description(self):
- return "FIXME"
-
- def set_cache_dir(self,path):
- self.cache_dir = path
-
- def get_file_info(self):
- try:
- file_out1, file_out2 = os.popen4('mp3info "'+self.dest+'"')
- info = []
- for line in file_out2.readlines():
- info.append(clean_word(line[:-1]))
- self.info = info
- return self.info
- except:
- raise IOError('ExporterError: file does not exist.')
-
- def decode(self):
- try:
- os.system('sox "'+self.source+'" -s -q -r 44100 -t wav "' \
- +self.cache_dir+os.sep+self.item_id+'"')
- return self.cache_dir+os.sep+self.item_id+'.wav'
- except:
- raise IOError('ExporterError: decoder is not compatible.')
-
- def write_tags(self):
- """Write all ID3v2.4 tags by mapping dub2id3_dict dictionnary with the
- respect of mutagen classes and methods"""
- from mutagen import id3
- id3 = id3.ID3(self.dest)
- for tag in self.metadata.keys():
- if tag in self.dub2id3_dict.keys():
- frame_text = self.dub2id3_dict[tag]
- value = self.metadata[tag]
- frame = mutagen.id3.Frames[frame_text](3,value)
- try:
- id3.add(frame)
- except:
- raise IOError('ExporterError: cannot tag "'+tag+'"')
- try:
- id3.save()
- except:
- raise IOError('ExporterError: cannot write tags')
-
- def get_args(self, options=None):
- """Get process options and return arguments for the encoder"""
- args = []
- if not options is None:
- self.options = options
- if not ( 'verbose' in self.options and self.options['verbose'] != '0' ):
- args.append('-S')
- if 'mp3_bitrate' in self.options:
- args.append('-b ' + self.options['mp3_bitrate'])
- else:
- args.append('-b '+self.bitrate_default)
- #Copyrights, etc..
- args.append('-c -o')
- else:
- args.append('-S -c -o')
-
- for tag in self.metadata:
- name = tag[0]
- value = clean_word(tag[1])
- if name in self.dub2args_dict.keys():
- arg = self.dub2args_dict[name]
- args.append('--' + arg + ' "' + value + '"')
- return args
-
- def process(self, item_id, source, metadata, options=None):
- self.item_id = item_id
- self.source = source
- self.metadata = metadata
- self.args = self.get_args(options)
- self.ext = self.get_file_extension()
- self.args = ' '.join(self.args)
- self.command = 'sox "%s" -q -b 16 -r 44100 -t wav - | lame %s -' % (self.source, self.args)
- #self.command = 'lame %s "%s" -' % (self.args, self.source)
-
- # Pre-proccessing
- self.dest = self.pre_process(self.item_id,
- self.source,
- self.metadata,
- self.ext,
- self.cache_dir,
- self.options)
-
- # Processing (streaming + cache writing)
- stream = self.core_process(self.command, self.buffer_size, self.dest)
- for chunk in stream:
- yield chunk
-
- # Post-proccessing
- #self.post_process(self.item_id,
- #self.source,
- #self.metadata,
- #self.ext,
- #self.cache_dir,
- #self.options)
-
+++ /dev/null
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2007-2009 Guillaume Pellerin <yomguy@parisson.com>
-
-# This file is part of TimeSide.
-
-# TimeSide 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.
-
-# TimeSide 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 TimeSide. If not, see <http://www.gnu.org/licenses/>.
-
-# Author: Guillaume Pellerin <yomguy@parisson.com>
-
-import os
-import string
-import subprocess
-
-from timeside.export.core import *
-from timeside.export.api import IExporter
-from mutagen.oggvorbis import OggVorbis
-
-class OggExporter(ExporterCore):
- """Defines methods to export to OGG Vorbis"""
-
- implements(IExporter)
-
- def __init__(self):
- self.item_id = ''
- self.metadata = {}
- self.description = ''
- self.info = []
- self.source = ''
- self.dest = ''
- self.options = {}
- self.bitrate_default = '192'
- self.buffer_size = 0xFFFF
- self.dub2args_dict = {'creator': 'artist',
- 'relation': 'album'
- }
-
- def get_format(self):
- return 'OGG'
-
- def get_file_extension(self):
- return 'ogg'
-
- def get_mime_type(self):
- return 'application/ogg'
-
- def get_description(self):
- return 'FIXME'
-
- def get_file_info(self):
- try:
- file_out1, file_out2 = os.popen4('ogginfo "'+self.dest+'"')
- info = []
- for line in file_out2.readlines():
- info.append(clean_word(line[:-1]))
- self.info = info
- return self.info
- except:
- raise IOError('ExporterError: file does not exist.')
-
- def set_cache_dir(self,path):
- self.cache_dir = path
-
- def decode(self):
- try:
- os.system('oggdec -o "'+self.cache_dir+os.sep+self.item_id+
- '.wav" "'+self.source+'"')
- return self.cache_dir+os.sep+self.item_id+'.wav'
- except:
- raise IOError('ExporterError: decoder is not compatible.')
-
- def write_tags(self):
- media = OggVorbis(self.dest)
- for tag in self.metadata.keys():
- media[tag] = str(self.metadata[tag])
- media.save()
-
- def get_args(self,options=None):
- """Get process options and return arguments for the encoder"""
- args = []
- if not options is None:
- self.options = options
- if not ('verbose' in self.options and self.options['verbose'] != '0'):
- args.append('-Q ')
- if 'ogg_bitrate' in self.options:
- args.append('-b '+self.options['ogg_bitrate'])
- elif 'ogg_quality' in self.options:
- args.append('-q '+self.options['ogg_quality'])
- else:
- args.append('-b '+self.bitrate_default)
- else:
- args.append('-Q -b '+self.bitrate_default)
-
- for tag in self.metadata:
- name = tag[0]
- value = clean_word(tag[1])
- args.append('-c %s="%s"' % (name, value))
- if name in self.dub2args_dict.keys():
- arg = self.dub2args_dict[name]
- args.append('-c %s="%s"' % (arg, value))
- return args
-
- def process(self, item_id, source, metadata, options=None):
- self.item_id = item_id
- self.source = source
- self.metadata = metadata
- self.args = self.get_args(options)
- self.ext = self.get_file_extension()
- self.args = ' '.join(self.args)
- self.command = 'sox "%s" -s -q -b 16 -r 44100 -t wav -c2 - | oggenc %s -' % (self.source, self.args)
-
- # Pre-proccessing
- self.dest = self.pre_process(self.item_id,
- self.source,
- self.metadata,
- self.ext,
- self.cache_dir,
- self.options)
-
- # Processing (streaming + cache writing)
- stream = self.core_process(self.command, self.buffer_size, self.dest)
- for chunk in stream:
- yield chunk
-
- # Post-proccessing
- #self.post_process(self.item_id,
- #self.source,
- #self.metadata,
- #self.ext,
- #self.cache_dir,
- #self.options)
-
+++ /dev/null
-# -*- coding: utf-8 -*-
-#
-# Copyright (c) 2007-2009 Guillaume Pellerin <yomguy@parisson.com>
-
-# This file is part of TimeSide.
-
-# TimeSide 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.
-
-# TimeSide 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 TimeSide. If not, see <http://www.gnu.org/licenses/>.
-
-# Author: Guillaume Pellerin <yomguy@parisson.com>
-
-import os
-import string
-
-from timeside.export.core import *
-from timeside.export.api import IExporter
-
-class WavExporter(ExporterCore):
- """Defines methods to export to WAV"""
-
- implements(IExporter)
-
- def __init__(self):
- self.item_id = ''
- self.metadata = {}
- self.description = ''
- self.info = []
- self.source = ''
- self.dest = ''
- self.options = {}
- self.buffer_size = 0xFFFF
-
- def get_format(self):
- return 'WAV'
-
- def get_file_extension(self):
- return 'wav'
-
- def get_mime_type(self):
- return 'audio/x-wav'
-
- def get_description(self):
- return 'FIXME'
-
- def get_file_info(self):
- try:
- file1, file2 = os.popen4('wavinfo "'+self.dest+'"')
- info = []
- for line in file2.readlines():
- info.append(clean_word(line[:-1]))
- self.info = info
- return self.info
- except:
- raise IOError('ExporterError: wavinfo id not installed or file does not exist.')
-
- def set_cache_dir(self,path):
- self.cache_dir = path
-
- def decode(self):
- try:
- file_name, ext = get_file_name(self.source)
- dest = self.cache_dir+os.sep+file_name+'.wav'
- os.system('sox "'+self.source+'" -s -r 44100 -t wav -c2 "'+ \
- dest+'.wav"')
- self.source = dest
- return dest
- except:
- raise IOError('ExporterError: decoder is not compatible.')
-
- def write_tags(self):
- # Create metadata XML file !
- self.write_metadata_xml(self.dest+'.xml')
-
- def create_md5_key(self):
- """ Create the md5 keys of the dest """
- try:
- os.system('md5sum -b "'+self.dest+'" >"'+self.dest+'.md5"')
- except:
- raise IOError('ExporterError: cannot create the md5 key.')
-
- def create_par_key(self):
- """ Create the par2 keys of the dest """
- args = 'c -n1 '
- if 'verbose' in self.options and self.options['verbose'] != '0':
- args = args
- else:
- args = args + '-q -q '
-
- try:
- os.system('par2 '+args+' "'+self.dest+'"')
- except:
- raise IOError('ExporterError: cannot create the par2 key.')
-
- def process(self, item_id, source, metadata, options=None):
- self.item_id = item_id
- self.source = source
- self.metadata = metadata
- self.options = {}
-
- if not options is None:
- self.options = options
-
- # Pre-proccessing
- self.ext = self.get_file_extension()
- self.dest = self.pre_process(self.item_id,
- self.source,
- self.metadata,
- self.ext,
- self.cache_dir,
- self.options)
-
- # Initializing
- file_in = open(self.source,'rb')
- file_out = open(self.dest,'w')
-
- # Core Processing
- while True:
- chunk = file_in.read(self.buffer_size)
- if len(chunk) == 0:
- break
- yield chunk
- file_out.write(chunk)
-
- file_in.close()
- file_out.close()
-
- # Create the md5 key
- #if 'md5' in self.metadata and self.metadata['md5']:
- self.create_md5_key()
-
- # Create the par2 key
- #if 'par2' in self.metadata and self.metadata['par2']:
- #self.create_par_key()
-
- # Pre-proccessing
- self.post_process(self.item_id,
- self.source,
- self.metadata,
- self.ext,
- self.cache_dir,
- self.options)
-
-
-
- #if self.compare_md5_key():
- #os.system('cp -a "'+self.source+'" "'+ self.dest+'"')
- #print 'COPIED'
-