From: yomguy Date: Wed, 22 Aug 2012 13:02:36 +0000 (+0200) Subject: general cleanup X-Git-Tag: 0.9~36 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=6be7175ad9333f4261f6d5ac90d793c0cf0bbf9d;p=telecaster-client.git general cleanup --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..6b192a7 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Guillaume Pellerin diff --git a/INSTALL.rst b/INSTALL.rst deleted file mode 100644 index ac25e21..0000000 --- a/INSTALL.rst +++ /dev/null @@ -1,117 +0,0 @@ -================== -INSTALL TeleCaster -================== - - -1. Operating System -=================== - -TeleCaster now only works on GNU/Linux systems. The installer and the following instructions -are based on Debian like software management so that it should work on Debian (>= Lenny) -or Ubuntu / Kubuntu (>= 10.4). So please install one of these OS before. - - -2. Install dependencies -======================= - -Needed:: - - sudo aptitude update - - sudo aptitude install python python-dev python-xml python-libxml2 python-setuptools python-twitter python-liblo python-mutagen \ - icecast2 apache2 apache2-suexec jackd libjack-dev vorbis-tools procps meterbridge fluxbox \ - vnc4server vncviewer swh-plugins jack-rack libshout3 libshout3-dev libmad0-dev libogg-dev g++ - -Warning: on Debian Squeeze or recent Ubuntu, change libjack-dev to libjack-jackd2-dev - -Optional:: - - sudo aptitude install libfaac-dev libmp3lame-dev libflac-dev - -Note that obtaining and installing a preempt RT kernel is STRONGLY advised to get a good audio (JACK) stability. -Moreover, edit the pam conf file to get RT "su" pam limits at boot:: - - sudo vi /etc/pam.d/su - -Uncomment:: - - session required pam_limits.so - - -3. Install TeleCaster -===================== - -Untar the archive. For example:: - - tar xzf telecaster-0.5.tar.gz - -Run the install script:: - - cd telecaster-0.5/ - sudo python install.py - - -4. Configuration -================ - -Edit the following files to setup TeleCaster. Please be careful with the XML syntax:: - - /etc/telecaster/telecaster.xml - -and, ONLY if needed:: - - /etc/default/jackd - /etc/default/vncserver - - -5. Start audio deamons -====================== - -Just reboot your machine or start the deamons manually:: - - sudo /etc/init.d/jackd start - sudo /etc/init.d/vncserver start - - -6. Configure Apache2 -==================== - -Configure your apache VirtualHost editing /etc/apache2/sites-available/telecaster.conf - -Enable the VirtualHost:: - - sudo a2ensite telecaster.conf - -Maybe remove the default VirtualHost:: - - sudo rm /etc/apache2/sites-enabled/000-default - -Reload Apache:: - - sudo /etc/init.d/apache2 reload - - -7. Usage -======== - -Browse the TeleCaster web control page: - - http://localhost/telecaster/telecaster.py - -Fill in the form and start any free recording and broadcasting stream ! - -To change the form options, just edit the conf file as root:: - - sudo vi /etc/telecaster/telecaster.xml - - -8. Contact -========== - -Any questions, suggestions ? Please post a ticket on the dev platform: - - http://svn.parisson.org/telecaster - -or contact the main developer: - - Guillaume Pellerin diff --git a/conf/home/fluxbox/telecaster/tc_video_only_simple_webm.sh b/conf/home/fluxbox/telecaster/tc_video_only_simple_webm.sh deleted file mode 100755 index 00b093e..0000000 --- a/conf/home/fluxbox/telecaster/tc_video_only_simple_webm.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -# Start TeleCaster video channel - -WIDTH=640 -HEIGHT=480 -#WIDTH=1024 -#HEIGHT=576 - -gst-launch v4l2src device=/dev/video0 ! video/x-raw-yuv, width=$WIDTH, height=$HEIGHT \ - ! queue ! ffmpegcolorspace \ - ! queue ! vp8enc speed=2 threads=4 quality=9.0 ! queue ! muxout. \ - webmmux streamable=true name=muxout \ - ! queue ! tcpserversink host=127.0.0.1 port=9000 protocol=none - diff --git a/setup.py b/setup.py index 97b2993..8fc0082 100644 --- a/setup.py +++ b/setup.py @@ -1,18 +1,17 @@ # -*- coding: utf-8 -*- + from setuptools import setup, find_packages -import os -import telecaster CLASSIFIERS = ['Environment :: Web Environment', 'Framework :: Django', 'Intended Audience :: Science/Research', 'Intended Audience :: Education', 'Programming Language :: Python', 'Programming Language :: JavaScript', 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', 'Topic :: Multimedia :: Sound/Audio', 'Topic :: Multimedia :: Sound/Audio :: Analysis', 'Topic :: Multimedia :: Sound/Audio :: Players', 'Topic :: Scientific/Engineering :: Information Analysis', 'Topic :: System :: Archiving', ] setup( - name = "TeleCaster", + name = "telecaster-client", url = "http://parisson.com", - description = "open web audio CMS", + description = "Audio and video live recording and streaming module for the e-learning system TeleForma (Python, Django, Javascript)", long_description = open('README.rst').read(), author = "Guillaume Pellerin", author_email = "yomguy@parisson.com", - version = '0.6', + version = '0.8', install_requires = [ 'django>=1.4.0', 'django-json-rpc', diff --git a/telecaster/AUTHORS b/telecaster/AUTHORS deleted file mode 100644 index 6b192a7..0000000 --- a/telecaster/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Guillaume Pellerin diff --git a/telecaster/favicon.ico b/telecaster/favicon.ico deleted file mode 100644 index 859b21c..0000000 Binary files a/telecaster/favicon.ico and /dev/null differ diff --git a/telecaster/install.py b/telecaster/install.py deleted file mode 100644 index 1ba6001..0000000 --- a/telecaster/install.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Copyright Guillaume Pellerin (2006-2010) - -# - -# This software is a computer program whose purpose is to stream audio -# 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, -# 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". - -# 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. - -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# 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 -# same conditions as regards security. - -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. - -# Author: Guillaume Pellerin - -# ONLY FOR GNU/LINUX Debian - -import os, sys -import platform -import shutil - -def remove_svn(path): - for root, dirs, files in os.walk(path): - for dir in dirs: - if '.svn' in dir: - shutil.rmtree(root + os.sep + dir) - -app_dir = os.getcwd() - -user = 'telecaster' -home = '/home/' + user -if not os.path.exists(home): - print 'Please give some informations for the new "telecaster" user :' - os.system('adduser ' + user) - -# compiling edcast-jack -os.chdir(app_dir + '/tools/edcast-jack') -os.system('./configure; make; sudo make install') - -# installing deefuzzer -os.chdir(app_dir + '/tools/deefuzzer') -os.system('sudo python install.py') - -os.chdir(app_dir) -install_dir = '/var/www/telecaster' -if os.path.exists(install_dir): - shutil.rmtree(install_dir) -shutil.copytree(app_dir, install_dir,ignore=shutil.ignore_patterns('edcast-jack*', 'deefuzzer*', '*.svn*')) -os.system('chown -R ' + user + ':' + user + ' ' + install_dir) - -conf_dir = '/etc/telecaster' -if not os.path.exists(conf_dir): - os.mkdir(conf_dir) -else: - in_files = os.listdir('conf'+conf_dir) - for file in in_files: - if not os.path.exists(conf_dir+os.sep+file) and not '.svn' in file: - shutil.copy('conf'+conf_dir+os.sep+file, conf_dir+os.sep+file) - - -daemons = ['jackd', 'vncserver'] -dir = '/etc/init.d/' -for daemon in daemons: - path = dir + daemon - shutil.copy('conf'+path, dir) - -dir = '/etc/default/' -for daemon in daemons: - path = dir + daemon - if not os.path.exists(path): - shutil.copy('conf'+path, dir) - -init_link = '/etc/rc2.d/S97jackd' -if not os.path.islink(init_link): - os.symlink('/etc/init.d/jackd ', init_link) - -init_link = '/etc/rc2.d/S99vncserver' -if not os.path.islink(init_link): - os.symlink('/etc/init.d/vncserver ', init_link) - -home_dirs = ['fluxbox', 'vnc'] -for dir in home_dirs: - home_dir = home + '/.' + dir - if not os.path.exists(home_dir): - shutil.copytree('conf/home/'+dir, home_dir, ignore=shutil.ignore_patterns('*.svn*')) - os.system('chown -R ' + user + ':' + user + ' ' + home_dir) - -dir = 'media' -home_dir = home + os.sep + dir -if not os.path.exists(home_dir): - shutil.copytree('conf/home/'+dir, home_dir, ignore=shutil.ignore_patterns('*.svn*')) - os.system('chown -R ' + user + ':' + user + ' ' + home_dir) - -apache_conf = '/etc/apache2/sites-available/telecaster.conf' -if not os.path.exists(apache_conf): - shutil.copy('conf'+apache_conf, apache_conf) -os.system('/etc/init.d/apache2 reload') - -log_dirs = ['/var/log/telecaster', '/var/log/deefuzzer'] -for dir in log_dirs: - if not os.path.exists(dir): - os.mkdir(dir) - os.system('chown -R ' + user + ':' + user + ' ' + dir) - -print """ - Installation successfull ! - - Now, please : - - configure your telecaster editing /etc/telecaster/telecaster.xml - - configure your apache VirtualHost editing /etc/apache2/sites-available/telecaster.conf - - And use the TeleCaster system browsing http://localhost/telecaster/telecaster.py - - See README for more infos. - """ - diff --git a/telecaster/jack/jack.py b/telecaster/jack/jack.py deleted file mode 100644 index 4c73769..0000000 --- a/telecaster/jack/jack.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/python -# Capture 3 seconds of stereo audio from alsa_pcm:capture_1/2; then play it back. -# -# Copyright 2003, Andrew W. Schmeder -# This source code is released under the terms of the GNU Public License. -# See LICENSE for the full text of these terms. - -import Numeric -import jack -import time - -class JackInput: - "A JACK connexion input in TeleOddCast" - - def __init__(self, dict): - self.host = dict['host'] - self.name = dict['name'] - self.jack = jack() - self.buffer_size = self.jack.get_buffer_size() - self.sample_rate = float(self.jack.get_sample_rate()) - print "Buffer Size:", N, "Sample Rate:", Sr - self.power = True - self.capture = Numeric.zeros((2, self.buffer_size), 'f') - - - def attach(self): - jack.attach(self.name) - - def get_ports(self): - return self.jack.get_ports() - - def register_ports(self): - self.jack.register_port("in_1", self.jack.IsInput) - self.jack.register_port("in_2", self.jack.IsInput) - - def activate(self): - self.jack.activate() - - def stop(self): - self.power = False - - def connect(self): - self.jack.connect("alsa_pcm:capture_1", self.name+":in_1") - self.jack.connect("alsa_pcm:capture_2", self.name+":in_2") - #jack.connect(self.name+":out_1", "alsa_pcm:playback_1") - #jack.connect(self.name+":out_2", "alsa_pcm:playback_2") - - def process(self): - while True: - try: - if not self.power: - break - self.jack.process(__chunk, capture[:,self.buffer_size]) - yield __chunk - except self.jack.InputSyncError: - print "Input Sync" - pass - except self.jack.OutputSyncError: - print "Output Sync" - pass - - def desactivate(self): - self.jack.deactivate() - - def detach(self): - self.jack.detach() diff --git a/telecaster/js/rssajax.js b/telecaster/js/rssajax.js deleted file mode 100644 index 84b5cf4..0000000 --- a/telecaster/js/rssajax.js +++ /dev/null @@ -1,275 +0,0 @@ - -//OBJECTS - -//objects inside the RSS2Item object -function RSS2Enclosure(encElement) -{ - if (encElement == null) - { - this.url = null; - this.length = null; - this.type = null; - } - else - { - this.url = encElement.getAttribute("url"); - this.length = encElement.getAttribute("length"); - this.type = encElement.getAttribute("type"); - } -} - -function RSS2Guid(guidElement) -{ - if (guidElement == null) - { - this.isPermaLink = null; - this.value = null; - } - else - { - this.isPermaLink = guidElement.getAttribute("isPermaLink"); - this.value = guidElement.childNodes[0].nodeValue; - } -} - -function RSS2Source(souElement) -{ - if (souElement == null) - { - this.url = null; - this.value = null; - } - else - { - this.url = souElement.getAttribute("url"); - this.value = souElement.childNodes[0].nodeValue; - } -} - -//object containing the RSS 2.0 item -function RSS2Item(itemxml) -{ - //required - this.title; - this.link; - this.description; - - //optional vars - this.author; - this.comments; - this.pubDate; - - //optional objects - this.category; - this.enclosure; - this.guid; - this.source; - - var properties = new Array("title", "link", "description", "author", "comments", "pubDate"); - var tmpElement = null; - for (var i=0; i"; - } - - //populate the items - document.getElementById("chan_items").innerHTML = ""; - for (var i=0; i" + RSS.items[i].link + "" + endTag; - item_html += endTag; - document.getElementById("chan_items").innerHTML += item_html; - } - - //we're done - //document.getElementById("chan").style.visibility = "visible"; - return true; -} - -var xhr; - - -function callExternalScript(url){ - var n = document.createElement("script"); - n.setAttribute("type", "text/javascript"); - n.setAttribute("src", url); - document.getElementsByTagName("head")[0].appendChild(n); -} diff --git a/telecaster/media/silence_mono.mp3 b/telecaster/media/silence_mono.mp3 deleted file mode 100644 index b951496..0000000 Binary files a/telecaster/media/silence_mono.mp3 and /dev/null differ diff --git a/telecaster/media/silence_mono.ogg b/telecaster/media/silence_mono.ogg deleted file mode 100644 index 8647f38..0000000 Binary files a/telecaster/media/silence_mono.ogg and /dev/null differ diff --git a/telecaster/old/station.py b/telecaster/old/station.py deleted file mode 100644 index b05e628..0000000 --- a/telecaster/old/station.py +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# *-* coding: utf-8 *-* -""" - telecaster - - Copyright (c) 2006-2010 Guillaume Pellerin - -# This software is governed by the CeCILL license under French law and -# 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". - -# 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. - -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# 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 -# same conditions as regards security. - -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. - -# Author: Guillaume Pellerin - -""" - -import os -import pwd -import datetime -import time -import urllib -import liblo -from tools import * -from mutagen.oggvorbis import OggVorbis -from mutagen.id3 import ID3, TIT2, TP1, TAL, TDA, TDAT, TDRC, TCO, COM -#import jack - - -class Conference: - """A conference object including metadata""" - - def __init__(self, dict): - self.dict = dict - self.title = dict['title'] - self.department = dict['department'] - self.conference = dict['conference'] - self.session = dict['session'] - self.professor = dict['professor'] - self.comment = dict['comment'] - - def get_info(self): - return self.title, self.department, self.conference, self.session, self.professor, self.comment - - -class Station(Conference): - """Control the Oddcastv3-jack thread which send audio data to the icecast server - and the Streamripper thread which write audio on the hard disk""" - - def __init__(self, conf_file, conference_dict, lock_file): - Conference.__init__(self, conference_dict) - self.date = datetime.datetime.now().strftime("%Y") - self.time = datetime.datetime.now().strftime("%x-%X") - self.time_txt = self.time.replace('/','_').replace(':','_').replace(' ','_') - self.conf = xml2dict(conf_file) - self.lock_file = lock_file - self.conf = self.conf['telecaster'] - self.user = pwd.getpwuid(os.getuid())[0] - self.user_dir = '/home' + os.sep + self.user + os.sep + '.telecaster' - self.rec_dir = self.conf['media']['rec_dir'] - self.deefuzzer_default_conf_file = self.conf['deefuzzer']['conf'] - self.deefuzzer_user_file = self.user_dir + os.sep + 'deefuzzer.xml' - self.bitrate = self.conf['media']['bitrate'] - self.dict['Bitrate'] = str(self.bitrate) + ' kbps' - self.record = str_to_bool(self.conf['media']['record']) - self.rec_dir = self.conf['media']['rec_dir'] - self.play_dir = self.conf['media']['play_dir'] - self.ogg_quality = self.conf['media']['ogg_quality'] - self.format = self.conf['media']['format'] - self.channels = int(self.conf['media']['channels']) - self.description = [self.title, self.department, self.conference, self.session, self.professor, self.comment] - self.server_name = [self.title, self.department, self.conference] - self.ServerDescription = clean_string('-'.join(self.description)) - self.ServerName = clean_string('_-_'.join(self.server_name)) - self.mount_point = self.ServerName - self.filename = clean_string('_-_'.join(self.description[1:])) + '-' + self.time_txt + '.' + self.format - self.output_dir = self.rec_dir + os.sep + self.date + os.sep + self.department - self.file_dir = self.output_dir + os.sep + self.ServerName - self.uid = os.getuid() - self.odd_pid = get_pid('^edcast_jack', self.uid) - self.deefuzzer_pid = get_pid('/usr/bin/deefuzzer '+self.deefuzzer_user_file, self.uid) - self.new_title = clean_string('-'.join(self.server_name)+'-'+self.session+'-'+self.professor+'-'+self.comment) - self.short_title = clean_string('-'.join(self.conference)+'-'+self.session+'-'+self.professor+'-'+self.comment) - self.genre = self.conf['infos']['genre'] - self.encoder = 'TeleCaster by Parisson' - - if not os.path.exists(self.file_dir): - os.makedirs(self.file_dir) - - self.jack_inputs = [] - if 'jack' in self.conf: - jack_inputs = self.conf['jack']['input'] - if len(jack_inputs) > 1: - for jack_input in jack_inputs: - self.jack_inputs.append(jack_input['name']) - else: - self.jack_inputs.append(jack_inputs['name']) - - self.deefuzzer_dict = xml2dict(self.deefuzzer_default_conf_file) - self.deefuzzer_osc_ports = [] - self.server_ports = [] - - for station in self.deefuzzer_dict['deefuzzer']['station']: - if station['control']['mode'] == '1': - self.deefuzzer_osc_ports.append(station['control']['port']) - self.server_ports.append(station['server']['port']) - if station['server']['host'] == 'localhost' or station['server']['host'] == '127.0.0.1': - self.conf['play_port'] = station['server']['port'] - else: - self.conf['play_port'] = '8000' - - def deefuzzer_setup(self): - i = 0 - for station in self.deefuzzer_dict['deefuzzer']['station']: - station['infos']['short_name'] = self.mount_point - station['infos']['name'] = self.ServerName - station['infos']['description'] = self.ServerDescription.replace(' ','_') - station['infos']['genre'] = self.genre - station['media']['bitrate'] = self.bitrate - station['media']['dir'] = self.play_dir - station['media']['voices'] = str(len(self.jack_inputs)) - station['record']['dir'] = self.file_dir - station['relay']['mode'] = '1' - station['relay']['author'] = self.professor - self.deefuzzer_dict['deefuzzer']['station'][i] = station - i += 1 - self.deefuzzer_xml = dicttoxml(self.deefuzzer_dict) - - def deefuzzer_write_conf(self): - conf_file = open(self.deefuzzer_user_file,'w') - conf_file.write(self.deefuzzer_xml) - conf_file.close() - - def deefuzzer_start(self): - command = 'deefuzzer ' + self.deefuzzer_user_file + ' > /dev/null &' - os.system(command) - self.set_lock() - - def set_lock(self): - lock = open(self.lock_file,'w') - lock_text = clean_string('_*_'.join(self.description)) - lock_text = lock_text.replace('\n','') - lock.write(lock_text) - lock.close() - - def del_lock(self): - os.remove(self.lock_file) - - def deefuzzer_stop(self): - if len(self.deefuzzer_pid) != 0: - os.system('kill -9 '+self.deefuzzer_pid[0]) - - def rec_stop(self): - if len(self.deefuzzer_pid) != 0: - for port in self.deefuzzer_osc_ports: - target = liblo.Address(int(port)) - liblo.send(target, '/record', 0) - - def mp3_convert(self): - os.system('oggdec -o - '+ self.file_dir+os.sep+self.filename+' | lame -S -m m -h -b '+ self.bitrate + \ - ' --add-id3v2 --tt "'+ self.new_title + '" --ta "'+self.professor+'" --tl "'+self.title+'" --ty "'+self.date+ \ - '" --tg "'+self.genre+'" - ' + self.file_dir+os.sep+self.ServerDescription + '.mp3 &') - - def write_tags_ogg(self): - file = self.file_dir + os.sep + self.filename - if os.path.exists(file): - audio = OggVorbis(file) - audio['TITLE'] = self.new_title.decode('utf8') - audio['ARTIST'] = self.professor.decode('utf8') - audio['ALBUM'] = self.title.decode('utf8') - audio['DATE'] = self.date.decode('utf8') - audio['GENRE'] = self.genre.decode('utf8') - audio['SOURCE'] = self.title.decode('utf8') - audio['ENCODER'] = self.encoder.decode('utf8') - audio['COMMENT'] = self.comment.decode('utf8') - audio.save() - - def write_tags_mp3(self): - file = self.file_dir + os.sep + self.filename - if os.path.exists(file): - os.system('mp3info -t "a" -a "a" '+file) - audio = ID3(file) - #tag = tags.__dict__['TITLE'] - audio.add(TIT2(encoding=3, text=self.new_title.decode('utf8'))) - #tag = tags.__dict__['ARTIST'] - audio.add(TP1(encoding=3, text=self.professor.decode('utf8'))) - #tag = tags.__dict__['ALBUM'] - audio.add(TAL(encoding=3, text=self.title.decode('utf8'))) - #tag = tags.__dict__['DATE'] - audio.add(TDRC(encoding=3, text=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) - #tag = tags.__dict__['GENRE'] - audio.add(TCO(encoding=3, text=self.genre.decode('utf8'))) - #tag = tags.__dict__['COMMENT'] - #audio.add(COM(encoding=3, text=self.comment)) - audio.save() - - def start(self): - self.set_lock() - self.deefuzzer_setup() - self.deefuzzer_write_conf() - self.deefuzzer_start() - - def stop(self): - self.rec_stop() - time.sleep(2) - self.deefuzzer_stop() - self.del_lock() diff --git a/telecaster/old/telecaster.py b/telecaster/old/telecaster.py deleted file mode 100755 index 392a8e3..0000000 --- a/telecaster/old/telecaster.py +++ /dev/null @@ -1,150 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# *-* coding: utf-8 *-* -""" - telecaster - - Copyright (c) 2006-2010 Guillaume Pellerin - -# This software is governed by the CeCILL license under French law and -# 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". - -# 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. - -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# 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 -# same conditions as regards security. - -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. - -# Author: Guillaume Pellerin -""" - -version = '0.5.2' - - -import os -import sys -import pwd -import cgi -import cgitb -import time -from tools import * -from webview import * -from station import * -cgitb.enable() - - -class TeleCaster: - """Manage the calls of Station and Webview to get the network and - disk streams""" - - def __init__(self, conf_file): - """Main function""" - self.conf_file = conf_file - conf_dict = xml2dict(self.conf_file) - self.conf = conf_dict['telecaster'] - self.title = self.conf['infos']['name'] - self.log_file = self.conf['log'] - self.logger = Logger(self.log_file) - self.uid = os.getuid() - self.url = self.conf['infos']['url'] - self.user = pwd.getpwuid(os.getuid())[0] - self.user_dir = '/home' + os.sep + self.user + os.sep + '.telecaster' - if not os.path.exists(self.user_dir): - os.makedirs(self.user_dir) - self.lock_file = self.user_dir + os.sep + 'telecaster.lock' - - def transition_head(self): - html_file = open('telecaster_starting_head.html', 'r') - html = html_file.read() - html_file.close() - return html - - def transition_foot(self): - html_file = open('telecaster_starting_foot.html', 'r') - html = html_file.read() - html_file.close() - return html - - def main(self): - edcast_pid = get_pid('edcast_jack', self.uid) - deefuzzer_pid = get_pid('/usr/bin/deefuzzer '+self.user_dir+os.sep+'deefuzzer.xml', self.uid) - writing = edcast_pid != [] - casting = deefuzzer_pid != [] - form = WebView(self.conf, version) - - if deefuzzer_pid == [] and form.has_key("action") and \ - form.has_key("department") and form.has_key("conference") and \ - form.has_key("session") and form["action"].value == "start": - - self.conference_dict = {'title': '', - 'department': '', - 'conference': '', - 'session': '', - 'professor': '', - 'comment': ''} - - for data in self.conference_dict: - if not form.has_key(data): - self.conference_dict[data] = 'Inconnu' - else: - value = form.getfirst(data) - if '....' in value: - self.conference_dict[data] = 'Inconnu' - else: - self.conference_dict[data] = value - - self.conference_dict['title'] = self.title - s = Station(self.conf_file, self.conference_dict, self.lock_file) - s.start() - time.sleep(2) - self.logger.write_info('starting') - self.main() - - elif deefuzzer_pid != [] and os.path.exists(self.lock_file) and not form.has_key("action"): - self.conference_dict = get_conference_from_lock(self.lock_file) - form.stop_form(self.conference_dict, writing, casting) - self.logger.write_info('started') - - elif deefuzzer_pid and form.has_key("action") and form["action"].value == "stop": - self.logger.write_info('stopping') - if os.path.exists(self.lock_file): - self.conference_dict = get_conference_from_lock(self.lock_file) - s = Station(self.conf_file, self.conference_dict, self.lock_file) - s.stop() - time.sleep(2) - self.main() - - elif deefuzzer_pid == []: - form.start_form(writing, casting) - self.logger.write_info('stopped') - - elif deefuzzer_pid != []: - os.system('kill -9 '+deefuzzer_pid[0]) - self.main() - - -conf_file = '/etc/telecaster/telecaster.xml' - -if __name__ == '__main__': - sys.stderr = sys.stdout - t = TeleCaster(conf_file) - t.main() - - diff --git a/telecaster/tools/jack.py b/telecaster/tools/jack.py new file mode 100644 index 0000000..4c73769 --- /dev/null +++ b/telecaster/tools/jack.py @@ -0,0 +1,66 @@ +#!/usr/bin/python +# Capture 3 seconds of stereo audio from alsa_pcm:capture_1/2; then play it back. +# +# Copyright 2003, Andrew W. Schmeder +# This source code is released under the terms of the GNU Public License. +# See LICENSE for the full text of these terms. + +import Numeric +import jack +import time + +class JackInput: + "A JACK connexion input in TeleOddCast" + + def __init__(self, dict): + self.host = dict['host'] + self.name = dict['name'] + self.jack = jack() + self.buffer_size = self.jack.get_buffer_size() + self.sample_rate = float(self.jack.get_sample_rate()) + print "Buffer Size:", N, "Sample Rate:", Sr + self.power = True + self.capture = Numeric.zeros((2, self.buffer_size), 'f') + + + def attach(self): + jack.attach(self.name) + + def get_ports(self): + return self.jack.get_ports() + + def register_ports(self): + self.jack.register_port("in_1", self.jack.IsInput) + self.jack.register_port("in_2", self.jack.IsInput) + + def activate(self): + self.jack.activate() + + def stop(self): + self.power = False + + def connect(self): + self.jack.connect("alsa_pcm:capture_1", self.name+":in_1") + self.jack.connect("alsa_pcm:capture_2", self.name+":in_2") + #jack.connect(self.name+":out_1", "alsa_pcm:playback_1") + #jack.connect(self.name+":out_2", "alsa_pcm:playback_2") + + def process(self): + while True: + try: + if not self.power: + break + self.jack.process(__chunk, capture[:,self.buffer_size]) + yield __chunk + except self.jack.InputSyncError: + print "Input Sync" + pass + except self.jack.OutputSyncError: + print "Output Sync" + pass + + def desactivate(self): + self.jack.deactivate() + + def detach(self): + self.jack.detach() diff --git a/telecaster/webview.py b/telecaster/webview.py deleted file mode 100644 index f3d9cee..0000000 --- a/telecaster/webview.py +++ /dev/null @@ -1,318 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# *-* coding: utf-8 *-* -""" - telecaster - - Copyright (c) 2006-2010 Guillaume Pellerin - -# This software is governed by the CeCILL license under French law and -# 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". - -# 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. - -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# 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 -# same conditions as regards security. - -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. - -# Author: Guillaume Pellerin -""" - -import os -import cgi -import datetime -import time -import string -from tools import * -from cgi import FieldStorage - -class WebView(FieldStorage): - """Gives the web CGI frontend""" - - def __init__(self, conf, version): - FieldStorage.__init__(self) - self.conf = conf - self.version = version - self.interfaces = ['eth0', 'eth1', 'eth2', 'eth0-eth2','eth3'] - ip = '' - for interface in self.interfaces: - try: - ip = get_ip_address(interface) - if ip: - self.ip = ip - break - except: - self.ip = 'localhost' - if 'url' in self.conf['infos']: - self.url = 'http://' + self.conf['infos']['url'] - else: - self.url = 'http://' + self.ip - self.rss_url = self.url+'/rss/telecaster.xml' - self.port = '8000' - self.acpi = acpi.Acpi() - self.format = self.conf['media']['format'] - self.short_name = self.conf['infos']['short_name'] - self.title = self.conf['infos']['name'] + ' - ' + self.conf['infos']['description'] - self.departments = self.conf['department'] - self.professors = self.conf['professor'] - self.professors.sort() - self.comments = self.conf['comment'] - self.len_departments = len(self.departments) - self.len_professors = len(self.professors) - self.conference_nb_max = 40 - self.professor_nb_max = 40 - self.refresh = False - self.refresh_value = 20 - self.uid = os.getuid() - self.casting = False - self.writing = False - - def header(self): - # Required header that tells the browser how to render the HTML. - print "Content-Type: text/html\n\n" - print "" - print "" - print "" - print "TeleCaster - "+self.title+"" - print "" - - print "" - - def javascript(self): - print '' - - # rss ajax - #print "" - #print "" - - def sub_header(self): - if self.refresh: - print "" - print "\n" - #print "" - print "" - print "
" - print "
" - print "\"logo_telecaster\"" - print "
 TeleCaster - Audio Web Live Recording
" - print "
" - - def colophon(self): - date = datetime.datetime.now().strftime("%Y") - print "
" - print "TeleCaster "+self.version+" © "+date+" Parisson SARL. Tous droits réservés." - print "
" - - def footer(self): - print "
" - print "" - print "" - - def hardware_data(self): - jackd_pid = get_pid('jackd', self.uid) - if jackd_pid == []: - jackd_pid = get_pid('jackdbus', self.uid) - self.acpi.update() - self.power_state = self.acpi.charging_state() - if self.power_state == 0: - power_info = "batterie" - elif self.power_state == 1 or self.power_state == 2: - power_info = "secteur" - else: - power_info = "" - - if self.acpi.percent() == 127: - batt_charge = '100 %' - else: - percent = self.acpi.percent() - if percent < 10: - batt_charge = ''+str(percent)+' %' - else: - batt_charge = ''+str(percent)+' %' - - if self.ip == 'localhost': - ip_info = ''+self.ip+'' - else: - ip_info = ''+self.ip+'' - - if jackd_pid == []: - jackd_info = 'OFF' - else: - jackd_info = 'On' - - if self.casting: - casting = 'On' - else: - casting = 'OFF' - - print "
" - print "
Status
" - print "" - print "" - print "" % self.conf['infos']['url'] - print "" - print "" % ip_info - print "" - print "" % power_info - print "" - print "" % batt_charge - try: - print "" % self.acpi.temperature(0) - except: - pass - try: - print "" % self.acpi.temperature(1) - except: - pass - print "" - print "" % jackd_info - print "" - print "" % casting - print "" - print "" - print "" - print "
Name : %s
IP address : %s
Power : %s
Battery charge : %s
Temp core 1 : %s
Temp core 2 : %s
JACK audio server : %s
Encoder : %s
" - if self.writing: - print "" - else: - print "" - print "
" - if not self.ip == 'localhost' and self.writing: - print "" - else: - print "" - print "
" - print "
" - print "
" - - - def start_form(self, writing, casting, message=''): - self.casting = writing - self.writing = casting - self.refresh = False - self.mount_point = 'telecaster_live.' + self.format - self.header() - self.javascript() - self.sub_header() - self.hardware_data() - - print "
" - print "
" - print "" - print "" - print "" - print "" - print "" - print "" - print "" - print "" - print "" - print "" - print "" - print "
Titre : "+self.title+"
Département :
Conférence :
Session :
Professeur :
Commentaire :
" - print "
" - print "
" - print "
" - print "" - print "" - print "\"\"Play Live" - print "\"\"Archives" - print "\"\"Trash" - print "
" - print "
" - print "
" - self.colophon() - self.footer() - - def stop_form(self, conference_dict, writing, casting): - department = conference_dict['department'] - conference = conference_dict['conference'] - session = conference_dict['session'] - professor = conference_dict['professor'] - comment = conference_dict['comment'] - self.mount_point ='_-_'.join([self.short_name,department,conference])+'.'+self.format - self.writing = writing - self.casting = casting - self.refresh = True - - self.header() - self.sub_header() - self.hardware_data() - - print "
" - print "
" - print "" - print "" - print "" - print "" - print "" - print "" - print "" - print "
Titre : "+self.title+"
Département : "+department+"
Conference : "+conference+"
Session : "+session+"
Professeur : "+professor+"
Commentaire : "+comment+"
" - print "
" - print "
" - print "
" - print "" - print "\"\"Play" - print "" - print "\"\"Archives" - print "\"\"Trash" - print "
" - print "
" - print "
" - - self.colophon() - self.footer() -