# and video data through icecast2 servers.
# This software is governed by the CeCILL license under French law and
-# abiding by the rules of distribution of free software. You can use,
+# abiding by the rules of distribution of free software. You can use,
# modify and/ or redistribute the software under the terms of the CeCILL
# license as circulated by CEA, CNRS and INRIA at the following URL
-# "http://www.cecill.info".
+# "http://www.cecill.info".
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided only
# with a limited warranty and the software's author, the holder of the
# economic rights, and the successive licensors have only limited
-# liability.
+# liability.
# In this respect, the user's attention is drawn to the risks associated
# with loading, using, modifying and/or developing or reproducing the
# therefore means that it is reserved for developers and experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards their
-# requirements in conditions enabling the security of their systems and/or
-# data to be ensured and, more generally, to use and operate it in the
+# requirements in conditions enabling the security of their systems and/or
+# data to be ensured and, more generally, to use and operate it in the
# same conditions as regards security.
# The fact that you are presently reading this means that you have had
class Mp3:
"""A MP3 file object"""
-
+
def __init__(self, media):
self.media = media
self.item_id = ''
self.extension = self.get_file_extension()
self.size = os.path.getsize(media)
#self.args = self.get_args()
-
+
def get_format(self):
return 'MP3'
-
+
def get_file_extension(self):
return 'mp3'
def get_description(self):
return "MPEG audio Layer III"
-
+
def get_file_metadata(self):
metadata = {}
for key in self.keys2id3.keys():
def write_tags(self):
"""Write all ID3v2.4 tags by mapping dub2id3_dict dictionnary with the
respect of mutagen classes and methods"""
- id3 = id3.ID3(self.media)
+ from mutagen import id3
+ m = MP3(self.media)
+ m.add_tags()
+ m.tags['TIT2'] = id3.TIT2(encoding=2, text=u'text')
+ m.save()
+ media = id3.ID3(self.media)
for tag in self.metadata.keys():
- if tag in self.dub2id3_dict.keys():
- frame_text = self.dub2id3_dict[tag]
+ if tag in self.keys2id3.keys():
+ frame_text = self.keys2id3[tag]
value = self.metadata[tag]
- frame = mutagen.id3.Frames[frame_text](3,value)
+ frame = id3.Frames[frame_text](3,value)
try:
- id3.add(frame)
+ media.add(frame)
except:
raise IOError('ExporterError: cannot tag "'+tag+'"')
try:
- id3.save()
+ 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:
+ if not options is None:
self.options = options
if not ( 'verbose' in self.options and self.options['verbose'] != '0' ):
args.append('-S')
if self.relay_mode == 1:
self.relay_callback('/relay', [1])
- # Twittering
+ # Twitting
# mode = 0 means Off, mode = 1 means On
self.twitter_mode = 0
if 'twitter' in self.station:
self.tinyurl = tinyurl.create_one(self.channel.url + '/m3u/' + self.m3u.split(os.sep)[-1])
self.twitter_callback('/twitter', [1])
- # OSC
+ # Recording
+ # mode = 0 means Off, mode = 1 means On
+ self.record_mode = 0
+ if 'record' in self.station:
+ self.record_mode = int(self.station['record']['mode'])
+ self.record_dir = self.station['record']['dir']
+ if self.record_mode == 1:
+ self.record_callback('/write', [1])
+
+ # OSCing
self.osc_control_mode = 0
# mode = 0 means Off, mode = 1 means On
if 'control' in self.station:
self.osc_controller.add_method('/media/relay', 'i', self.relay_callback)
self.osc_controller.add_method('/twitter', 'i', self.twitter_callback)
self.osc_controller.add_method('/jingles', 'i', self.jingles_callback)
+ self.osc_controller.add_method('/record', 'i', self.record_callback)
+
def media_next_callback(self, path, value):
value = value[0]
message = "Received OSC message '%s' with arguments '%d'" % (path, value)
self.logger.write(message)
+ def record_callback(self, path, value):
+ value = value[0]
+ if value == 1:
+ self.rec_file = self.short_name + '-' + \
+ datetime.datetime.now().strftime("%x-%X").replace('/', '_') + '.' + self.channel.format
+ self.recorder = Recorder(self.record_dir)
+ self.recorder.open(self.rec_file)
+ elif value == 0:
+ self.recorder.close()
+ if self.channel.format == 'mp3':
+ media = Mp3(self.record_dir + os.sep + self.rec_file)
+ if self.channel.format == 'ogg':
+ media = Ogg(self.record_dir + os.sep + self.rec_file)
+ media.metadata = {'artist': self.artist, 'title': self.title, 'date': str(datetime.datetime.now().strftime("%Y"))}
+ media.write_tags()
+ self.record_mode = value
+ message = "Received OSC message '%s' with arguments '%d'" % (path, value)
+ self.logger.write(message)
+
def get_playlist(self):
file_list = []
for root, dirs, files in os.walk(self.media_dir):
self.q.task_done()
self.q.get(1)
+
if self.relay_mode == 1:
self.set_relay_mode()
elif os.path.exists(self.media) and not os.sep+'.' in self.media:
if self.next_media == 1:
break
except:
- self.logger.write('ERROR : Station ' + self.short_name + ' : could not send the buffer... ')
+ self.logger.write('ERROR : Station ' + self.short_name + ' : could not send the buffer to the server ')
self.channel.close()
self.channel.open()
continue
+ try:
+ if self.record_mode == 1:
+ self.recorder.write(self.chunk)
+ except:
+ self.logger.write('ERROR : Station ' + self.short_name + ' : could not write the buffer to the file ')
+ continue
self.q.task_done()
+
self.channel.close()