# -*- 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
+from timeside.decode.api import *
+from timeside.decode.core import *
+from timeside.decode.ogg import *
+from timeside.decode.flac import *
+from timeside.decode.wav import *
+from timeside.decode.mp3 import *
\ No newline at end of file
from timeside.core import Interface, TimeSideError
-class IExporter(Interface):
- """Export driver interface"""
+class IDecoder(Interface):
+ """Decoder 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
# you'll obviously want to include this extra argument.
def get_format():
- """Return the export/encoding format as a short string
+ """Return the decode/encoding format as a short string
Example: "MP3", "OGG", "AVI", ...
"""
def get_description():
- """Return a string describing what this export format provides, is good
+ """Return a string describing what this decode 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"""
+ """Return the filename extension corresponding to this decode format"""
def get_mime_type():
- """Return the mime type corresponding to this export format"""
+ """Return the mime type corresponding to this decode format"""
def set_cache_dir(path):
"""Set the directory where cached files should be stored. Does nothing
- if the exporter doesn't support caching.
+ if the decodeer 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.
+ """Perform the decoding process and stream the result through a generator
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
+ source is the audio/video source file absolute path.
metadata is a tuple containing tuples for each descriptor return by
the dc.Ressource of the item, in the model order :
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
+ It is highly recommended that decode 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):
+class DecodeProcessError(TimeSideError):
def __init__(self, message, command, subprocess):
self.message = message
import subprocess
import mutagen
-from timeside.export import *
+from timeside.decode import *
from timeside.core import *
import xml.dom.minidom
import xml.dom.ext
-class ExporterCore(Component):
- """Defines the main parts of the exporting tools :
+class DecoderCore(Component):
+ """Defines the main parts of the decodeing tools :
paths, metadata parsing, data streaming thru system command"""
def __init__(self):
os.system('normalize-audio '+args+' "'+self.source+'"')
return self.source
except:
- raise IOError('ExporterError: cannot normalize, path does not exist.')
+ raise IOError('DecoderError: cannot normalize, path does not exist.')
def check_md5_key(self):
""" Check if the md5 key is OK and return a boolean """
'" "'+self.dest+'.md5"')
return 'OK' in md5_log.split(':')
except IOError:
- raise IOError('ExporterError: cannot check the md5 key.')
+ raise IOError('DecoderError: cannot check the md5 key.')
def get_file_info(self):
""" Return the list of informations of the dest """
- return self.export.get_file_info()
+ return self.decode.get_file_info()
def get_wav_length_sec(self) :
""" Return the length of the audio source file in seconds """
value = int(int(line_split[1])/(4*44100))
return value
except:
- raise IOError('ExporterError: cannot get the wav length.')
+ raise IOError('DecoderError: cannot get the wav length.')
def compare_md5_key(self, source, dest):
""" Compare source and dest files wih md5 method """
def pre_process(self, item_id, source, metadata, ext,
cache_dir, options=None):
- """ Pre processing : prepare the export path and return it"""
+ """ Pre processing : prepare the decode path and return it"""
self.item_id = str(item_id)
self.source = source
file_name = get_file_name(self.source)
self.options['normalize'] == True:
self.normalize()
- # Define the export directory
+ # Define the decode directory
self.ext = self.get_file_extension()
- export_dir = os.path.join(self.cache_dir,self.ext)
+ decode_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:]:
+ if not os.path.exists(decode_dir):
+ decode_dir_split = decode_dir.split(os.sep)
+ path = os.sep + decode_dir_split[0]
+ for _dir in decode_dir_split[1:]:
path = os.path.join(path,_dir)
if not os.path.exists(path):
os.mkdir(path)
else:
- path = export_dir
+ path = decode_dir
# Set the target file
target_file = self.item_id+'.'+self.ext
mime = line_split[len(line_split)-1]
return mime[:len(mime)-1]
except:
- raise IOError('ExporterError: path does not exist.')
+ raise IOError('DecoderError: path does not exist.')
def get_file_type_desc(path):
""" Return the type of a file given by the 'file' command """
description = description[1].split(', ')
return description
except:
- raise IOError('ExporterError: path does not exist.')
+ raise IOError('DecoderError: path does not exist.')
def iswav(path):
""" Tell if path is a WAV """
mime = get_file_mime_type(path)
return mime == 'audio/x-wav'
except:
- raise IOError('ExporterError: path does not exist.')
+ raise IOError('DecoderError: path does not exist.')
def iswav16(path):
""" Tell if path is a 16 bit WAV """
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.')
+ raise IOError('DecoderError: path does not exist.')
def get_file_name(path):
""" Return the file name targeted in the path """
try:
return os.path.splitext(file)
except:
- raise IOError('ExporterError: path does not exist.')
+ raise IOError('DecoderError: path does not exist.')
def clean_word(word) :
""" Return the word without excessive blank spaces, underscores and
- characters causing problem to exporters"""
+ characters causing problem to decodeers"""
word = re.sub("^[^\w]+","",word) #trim the beginning
word = re.sub("[^\w]+$","",word) #trim the end
word = re.sub("_+","_",word) #squeeze continuous _ to one _
import string
import subprocess
-from timeside.export.core import *
-from timeside.export.api import IExporter
+from timeside.decode.core import *
+from timeside.decode.api import IDecoder
from mutagen.flac import FLAC
from tempfile import NamedTemporaryFile
-class FlacExporter(ExporterCore):
- """Defines methods to export to FLAC"""
+class FlacDecoder(DecoderCore):
+ """Defines methods to decode to FLAC"""
- implements(IExporter)
+ implements(IDecoder)
def __init__(self):
self.item_id = ''
self.info = info
return self.info
except:
- raise IOError('ExporterError: metaflac is not installed or ' + \
+ raise IOError('DecoderError: 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.
+ if the decodeer 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.source = dest
return dest
except:
- raise IOError('ExporterError: decoder is not compatible.')
+ raise IOError('DecoderError: decoder is not compatible.')
def write_tags(self, file):
media = FLAC(file)
try:
media.save()
except:
- raise IOError('ExporterError: cannot write tags.')
+ raise IOError('DecoderError: cannot write tags.')
def get_args(self,options=None):
"""Get process options and return arguments for the encoder"""
import string
import subprocess
-from timeside.export.core import *
-from timeside.export.api import IExporter
+from timeside.decode.core import *
+from timeside.decode.api import IDecoder
#from mutagen.id3 import *
-class Mp3Exporter(ExporterCore):
- """Defines methods to export to MP3"""
+class Mp3Decoder(DecoderCore):
+ """Defines methods to decode to MP3"""
- implements(IExporter)
+ implements(IDecoder)
def __init__(self):
self.item_id = ''
self.info = info
return self.info
except:
- raise IOError('ExporterError: file does not exist.')
+ raise IOError('DecoderError: file does not exist.')
def decode(self):
try:
+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.')
+ raise IOError('DecoderError: decoder is not compatible.')
def write_tags(self):
"""Write all ID3v2.4 tags by mapping dub2id3_dict dictionnary with the
try:
id3.add(frame)
except:
- raise IOError('ExporterError: cannot tag "'+tag+'"')
+ raise IOError('DecoderError: cannot tag "'+tag+'"')
try:
id3.save()
except:
- raise IOError('ExporterError: cannot write tags')
+ raise IOError('DecoderError: cannot write tags')
def get_args(self, options=None):
"""Get process options and return arguments for the encoder"""
import string
import subprocess
-from timeside.export.core import *
-from timeside.export.api import IExporter
+from timeside.decode.core import *
+from timeside.decode.api import IDecoder
from mutagen.oggvorbis import OggVorbis
-class OggExporter(ExporterCore):
- """Defines methods to export to OGG Vorbis"""
+class OggDecoder(DecoderCore):
+ """Defines methods to decode to OGG Vorbis"""
- implements(IExporter)
+ implements(IDecoder)
def __init__(self):
self.item_id = ''
self.info = info
return self.info
except:
- raise IOError('ExporterError: file does not exist.')
+ raise IOError('DecoderError: file does not exist.')
def set_cache_dir(self,path):
self.cache_dir = path
'.wav" "'+self.source+'"')
return self.cache_dir+os.sep+self.item_id+'.wav'
except:
- raise IOError('ExporterError: decoder is not compatible.')
+ raise IOError('DecoderError: decoder is not compatible.')
def write_tags(self):
media = OggVorbis(self.dest)
import os
import string
-from timeside.export.core import *
-from timeside.export.api import IExporter
+from timeside.decode.core import *
+from timeside.decode.api import IDecoder
-class WavExporter(ExporterCore):
- """Defines methods to export to WAV"""
+class WavDecoder(DecoderCore):
+ """Defines methods to decode to WAV"""
- implements(IExporter)
+ implements(IDecoder)
def __init__(self):
self.item_id = ''
self.info = info
return self.info
except:
- raise IOError('ExporterError: wavinfo id not installed or file does not exist.')
+ raise IOError('DecoderError: wavinfo id not installed or file does not exist.')
def set_cache_dir(self,path):
self.cache_dir = path
self.source = dest
return dest
except:
- raise IOError('ExporterError: decoder is not compatible.')
+ raise IOError('DecoderError: decoder is not compatible.')
def write_tags(self):
# Create metadata XML file !
try:
os.system('md5sum -b "'+self.dest+'" >"'+self.dest+'.md5"')
except:
- raise IOError('ExporterError: cannot create the md5 key.')
+ raise IOError('DecoderError: cannot create the md5 key.')
def create_par_key(self):
""" Create the par2 keys of the dest """
try:
os.system('par2 '+args+' "'+self.dest+'"')
except:
- raise IOError('ExporterError: cannot create the par2 key.')
+ raise IOError('DecoderError: cannot create the par2 key.')
def process(self, item_id, source, metadata, options=None):
self.item_id = item_id
# -*- 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
+from timeside.encode.api import *
+from timeside.encode.core import *
+from timeside.encode.ogg import *
+from timeside.encode.flac import *
+from timeside.encode.wav import *
+from timeside.encode.mp3 import *
\ No newline at end of file
from timeside.core import Interface, TimeSideError
-class IExporter(Interface):
- """Export driver interface"""
+class IEncoder(Interface):
+ """Encoder 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
# you'll obviously want to include this extra argument.
def get_format():
- """Return the export/encoding format as a short string
+ """Return the encode/encoding format as a short string
Example: "MP3", "OGG", "AVI", ...
"""
def get_description():
- """Return a string describing what this export format provides, is good
+ """Return a string describing what this encode 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"""
+ """Return the filename extension corresponding to this encode format"""
def get_mime_type():
- """Return the mime type corresponding to this export format"""
+ """Return the mime type corresponding to this encode format"""
def set_cache_dir(path):
"""Set the directory where cached files should be stored. Does nothing
- if the exporter doesn't support caching.
+ if the encodeer 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.
+ """Perform the encoding process and stream the result as a generator.
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
+ source is a raw audio stream coming from the decoder.
metadata is a tuple containing tuples for each descriptor return by
the dc.Ressource of the item, in the model order :
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
+ It is highly recommended that encode 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
import subprocess
import mutagen
-from timeside.export import *
+from timeside.encode import *
from timeside.core import *
import xml.dom.minidom
import xml.dom.ext
-class ExporterCore(Component):
- """Defines the main parts of the exporting tools :
+class EncoderCore(Component):
+ """Defines the main parts of the encodeing tools :
paths, metadata parsing, data streaming thru system command"""
def __init__(self):
os.system('normalize-audio '+args+' "'+self.source+'"')
return self.source
except:
- raise IOError('ExporterError: cannot normalize, path does not exist.')
+ raise IOError('EncoderError: cannot normalize, path does not exist.')
def check_md5_key(self):
""" Check if the md5 key is OK and return a boolean """
'" "'+self.dest+'.md5"')
return 'OK' in md5_log.split(':')
except IOError:
- raise IOError('ExporterError: cannot check the md5 key.')
+ raise IOError('EncoderError: cannot check the md5 key.')
def get_file_info(self):
""" Return the list of informations of the dest """
- return self.export.get_file_info()
+ return self.encode.get_file_info()
def get_wav_length_sec(self) :
""" Return the length of the audio source file in seconds """
value = int(int(line_split[1])/(4*44100))
return value
except:
- raise IOError('ExporterError: cannot get the wav length.')
+ raise IOError('EncoderError: cannot get the wav length.')
def compare_md5_key(self, source, dest):
""" Compare source and dest files wih md5 method """
def pre_process(self, item_id, source, metadata, ext,
cache_dir, options=None):
- """ Pre processing : prepare the export path and return it"""
+ """ Pre processing : prepare the encode path and return it"""
self.item_id = str(item_id)
self.source = source
file_name = get_file_name(self.source)
self.options['normalize'] == True:
self.normalize()
- # Define the export directory
+ # Define the encode directory
self.ext = self.get_file_extension()
- export_dir = os.path.join(self.cache_dir,self.ext)
+ encode_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:]:
+ if not os.path.exists(encode_dir):
+ encode_dir_split = encode_dir.split(os.sep)
+ path = os.sep + encode_dir_split[0]
+ for _dir in encode_dir_split[1:]:
path = os.path.join(path,_dir)
if not os.path.exists(path):
os.mkdir(path)
else:
- path = export_dir
+ path = encode_dir
# Set the target file
target_file = self.item_id+'.'+self.ext
mime = line_split[len(line_split)-1]
return mime[:len(mime)-1]
except:
- raise IOError('ExporterError: path does not exist.')
+ raise IOError('EncoderError: path does not exist.')
def get_file_type_desc(path):
""" Return the type of a file given by the 'file' command """
description = description[1].split(', ')
return description
except:
- raise IOError('ExporterError: path does not exist.')
+ raise IOError('EncoderError: path does not exist.')
def iswav(path):
""" Tell if path is a WAV """
mime = get_file_mime_type(path)
return mime == 'audio/x-wav'
except:
- raise IOError('ExporterError: path does not exist.')
+ raise IOError('EncoderError: path does not exist.')
def iswav16(path):
""" Tell if path is a 16 bit WAV """
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.')
+ raise IOError('EncoderError: path does not exist.')
def get_file_name(path):
""" Return the file name targeted in the path """
try:
return os.path.splitext(file)
except:
- raise IOError('ExporterError: path does not exist.')
+ raise IOError('EncoderError: path does not exist.')
def clean_word(word) :
""" Return the word without excessive blank spaces, underscores and
- characters causing problem to exporters"""
+ characters causing problem to encodeers"""
word = re.sub("^[^\w]+","",word) #trim the beginning
word = re.sub("[^\w]+$","",word) #trim the end
word = re.sub("_+","_",word) #squeeze continuous _ to one _
import string
import subprocess
-from timeside.export.core import *
-from timeside.export.api import IExporter
+from timeside.encode.core import *
+from timeside.encode.api import IEncoder
from mutagen.flac import FLAC
from tempfile import NamedTemporaryFile
-class FlacExporter(ExporterCore):
- """Defines methods to export to FLAC"""
+class FlacEncoder(EncoderCore):
+ """Defines methods to encode to FLAC"""
- implements(IExporter)
+ implements(IEncoder)
def __init__(self):
self.item_id = ''
self.info = info
return self.info
except:
- raise IOError('ExporterError: metaflac is not installed or ' + \
+ raise IOError('EncoderError: 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.
+ if the encodeer 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.source = dest
return dest
except:
- raise IOError('ExporterError: decoder is not compatible.')
+ raise IOError('EncoderError: decoder is not compatible.')
def write_tags(self, file):
media = FLAC(file)
try:
media.save()
except:
- raise IOError('ExporterError: cannot write tags.')
+ raise IOError('EncoderError: cannot write tags.')
def get_args(self,options=None):
"""Get process options and return arguments for the encoder"""
import string
import subprocess
-from timeside.export.core import *
-from timeside.export.api import IExporter
+from timeside.encode.core import *
+from timeside.encode.api import IEncoder
#from mutagen.id3 import *
-class Mp3Exporter(ExporterCore):
- """Defines methods to export to MP3"""
+class Mp3Encoder(EencoderCore):
+ """Defines methods to encode to MP3"""
- implements(IExporter)
+ implements(IEncoder)
def __init__(self):
self.item_id = ''
self.info = info
return self.info
except:
- raise IOError('ExporterError: file does not exist.')
+ raise IOError('EncoderError: file does not exist.')
def decode(self):
try:
+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.')
+ raise IOError('EncoderError: decoder is not compatible.')
def write_tags(self):
"""Write all ID3v2.4 tags by mapping dub2id3_dict dictionnary with the
try:
id3.add(frame)
except:
- raise IOError('ExporterError: cannot tag "'+tag+'"')
+ raise IOError('EncoderError: cannot tag "'+tag+'"')
try:
id3.save()
except:
- raise IOError('ExporterError: cannot write tags')
+ raise IOError('EncoderError: cannot write tags')
def get_args(self, options=None):
"""Get process options and return arguments for the encoder"""
import string
import subprocess
-from timeside.export.core import *
-from timeside.export.api import IExporter
+from timeside.encode.core import *
+from timeside.encode.api import IEncoder
from mutagen.oggvorbis import OggVorbis
-class OggExporter(ExporterCore):
- """Defines methods to export to OGG Vorbis"""
+class OggEncoder(EncoderCore):
+ """Defines methods to encode to OGG Vorbis"""
- implements(IExporter)
+ implements(IEncoder)
def __init__(self):
self.item_id = ''
self.info = info
return self.info
except:
- raise IOError('ExporterError: file does not exist.')
+ raise IOError('EncoderError: file does not exist.')
def set_cache_dir(self,path):
self.cache_dir = path
'.wav" "'+self.source+'"')
return self.cache_dir+os.sep+self.item_id+'.wav'
except:
- raise IOError('ExporterError: decoder is not compatible.')
+ raise IOError('EncoderError: decoder is not compatible.')
def write_tags(self):
media = OggVorbis(self.dest)
import os
import string
-from timeside.export.core import *
-from timeside.export.api import IExporter
+from timeside.encode.core import *
+from timeside.encode.api import IEncoder
-class WavExporter(ExporterCore):
- """Defines methods to export to WAV"""
+class WavEncoder(EncoderCore):
+ """Defines methods to encode to WAV"""
- implements(IExporter)
+ implements(IEncoder)
def __init__(self):
self.item_id = ''
self.info = info
return self.info
except:
- raise IOError('ExporterError: wavinfo id not installed or file does not exist.')
+ raise IOError('EncoderError: wavinfo id not installed or file does not exist.')
def set_cache_dir(self,path):
self.cache_dir = path
self.source = dest
return dest
except:
- raise IOError('ExporterError: decoder is not compatible.')
+ raise IOError('EncoderError: decoder is not compatible.')
def write_tags(self):
# Create metadata XML file !
try:
os.system('md5sum -b "'+self.dest+'" >"'+self.dest+'.md5"')
except:
- raise IOError('ExporterError: cannot create the md5 key.')
+ raise IOError('EncoderError: cannot create the md5 key.')
def create_par_key(self):
""" Create the par2 keys of the dest """
try:
os.system('par2 '+args+' "'+self.dest+'"')
except:
- raise IOError('ExporterError: cannot create the par2 key.')
+ raise IOError('EncoderError: cannot create the par2 key.')
def process(self, item_id, source, metadata, options=None):
self.item_id = item_id