Commit b6362ad8 authored by Gottfried Gaisbauer's avatar Gottfried Gaisbauer
Browse files

minor fixes. added licence

parent ca62e57a
Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
\ No newline at end of file
This diff is collapsed.
......@@ -6,6 +6,8 @@ AURA Engine does:
* requesting the programme from an external Source
* switches the soundserver at the correct time to a given source for a specific show
* records what is broadcasted
* streams to an icecast server
* plays to lineout
## Installation
......@@ -13,7 +15,7 @@ AURA Engine does:
#### Operating System
Any sound supporting linux system should work. It is tested and coded on a **debian stretch**
Any linux system with ALSA, pulseaudio or Jack2 support should work. It is tested and coded on a **debian stretch**
#### Packages
......@@ -41,10 +43,14 @@ sudo pip3 install \
#### Grab the code
```bash
git clone https://gitlab.servus.at/autoradio/engine
```
#### Set up a database
##### Command line way
```bash
mysql -u root -p
......@@ -53,9 +59,13 @@ CREATE USER 'aura'@'localhost' IDENTIFIED BY 'secure-password';
GRANT ALL PRIVILEGES ON aura_engine.* TO 'aura'@'localhost';
```
##### phpmyadmin / adminer way
Log into your phpmyadmin or adminer with correct privileges and create a database and a user for the aura engine.
#### Files and Folders
Create the audio folder defined in your aura.ini
* Create the audio folder defined in your aura.ini
```bash
mkdir /var/audio
......@@ -64,25 +74,30 @@ cp {where you cloned the repo}/configuration/engine.ini /etc/aura/engine.ini
edit engine.ini to your needs
```
edit installation dir and database settings in aura.ini
* Edit settings in aura.ini. Take your time for that.
#### aura.py
It is the server which is connected to the external programme source, to liquidsoap and is listening for redis pubsub messages.
It is the server which is connected to the external programme source (e.g. aura steering and tank), to liquidsoap and is listening for redis pubsub messages. This precious little server is telling liquidsoap what to play and when.
#### Guru
The commandline tool for interacting with the server.
The commandline tool for interacting with the server. Also provides the communication from Liquidsoap to the python (Command-)Server.
#### Liquidsoap
The heart of AURA Engine. It uses the built in mixer, to switch between different sources. A source can be a stream, the filesystem or linein
The heart of AURA Engine. It uses the built in mixer, to switch between different sources.
#### Find Help
LiquidSoap Reference: http://savonet.sourceforge.net/doc-svn/reference.html
Python3.5 Reference: https://docs.python.org/3.5/
### Hardware
#### Soundcard
AURA Engine ist tested with an ASUS Xonar DGX. It should work with every by ALSA supported soundcard. PulseAudio support is planned.
AURA Engine ist tested with a ASUS Xonar DGX and a Roland Duo-Capture Ex. Both work well with jack and pulseaudio. For good experience with ALSA, you may need better hardware.
#### Hard/Soft
......@@ -90,18 +105,18 @@ When you use ALSA, you will have to play around with ALSA settings. In the folde
### Recordings
You can configure up to five recorders. You find the settings in the main config file engine.ini. You can choose between wav, flac, ogg or mp3 output
You can configure up to five recorders. You find the settings in the main config file engine.ini. You can choose between different output formats.
### Streams
You can configure up to five streams. You find the settings in the engine.ini. You can choose between aac, aacplus, fdkaac, flac, mp3, ogg, opus stream
You can configure up to five streams. You find the settings in the engine.ini. You can choose between different streaming formats.
If you experience 'hangs' on the stream
* reduce the quality or
* invest in better hardware or
* install the realtime kernel
* install the realtime kernel with
```bash
apt install linux-image-rt-amd64
reboot
```
Should be sufficient.
\ No newline at end of file
or
* invest in better hardware
\ No newline at end of file
#!/usr/bin/python3.5
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
import os
import sys
import signal
......
[configfile]
scheduler_config_file="/etc/aura/scheduler.xml"
###################
# engine Settings #
###################
[database]
db_user="engine"
......@@ -8,23 +9,24 @@ db_pass="engine"
db_host="localhost"
[monitoring]
# how often should i check the diskspace
diskspace_check_interval=10
# how often should i check the diskspace. defaults to 600s = 10m
diskspace_check_interval=20
# under which value should i start sending admin mails. possible values k, M, G, T or no metric prefix. defaults to 2G
diskspace_warning_value=1G
# under which value should i stop recording. defaults to 200M
diskspace_critical_value=10g0M
diskspace_critical_value=100M
[mail]
mail_server=""
mail_server_port=""
mail_user=""
mail_pass=""
# multiple adminmails => space separated
# if you want to send multiple adminmails, make them space separated
admin_mail="gogo@servus.at gottfried@servus.at"
#
from_mail="monitor@aura.py"
# The beginning of the subject
mail_prefix="[AURA]"
# The beginning of the subject. With that you can easily apply filter rules
mailsubject_prefix="[AURA]"
[dataurls]
calendarurl="http://localhost:8000/api/v1/playout"
......@@ -136,7 +138,7 @@ rec_2="y"
rec_2_folder="/var/audio/rec/mp3"
rec_2_duration="30"
rec_2_encoding="mp3"
rec_2_bitrate="128"
rec_2_bitrate="32"
rec_2_channels="2"
# ogg example
......
#!/usr/bin/python3.5
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
import time
import sys
import redis
......
"""
Common aura functions
"""
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
from modules.base.config import ConfigReader
......
"""
Aura logger functions
"""
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
import logging
......
__author__ = 'gg'
# -*- coding: utf-8 -*-
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
import sys
import time
......@@ -10,7 +31,7 @@ from sqlalchemy import orm, func, Boolean, Column, DateTime, Integer, String, Fo
from sqlalchemy.orm import relationship
from sqlalchemy.sql.expression import false, true
from libraries.database.database import DB
from libraries.enum.scheduleentrytype import ScheduleEntryType
from libraries.enum.auraenumerations import ScheduleEntryType
class AuraDatabaseModel:
......@@ -123,6 +144,7 @@ class ScheduleEntry(DB.Model, AuraDatabaseModel):
volume = Column(Integer, default=100)
fallback_type = Column(Integer, default=0)
cleansource = ""
cleanprotocol = ""
entry_start_unix = 0
programme_index = -1
type = None
......@@ -133,6 +155,7 @@ class ScheduleEntry(DB.Model, AuraDatabaseModel):
def __init__(self, **kwargs):
super(ScheduleEntry, self).__init__(**kwargs)
self.calc_unix_times()
self.define_clean_source()
# constructor like - called from sqlalchemy
@orm.reconstructor
......@@ -141,13 +164,25 @@ class ScheduleEntry(DB.Model, AuraDatabaseModel):
self.set_entry_type()
def define_clean_source(self):
if self.source.startswith("http") or self.source.startswith("live") or self.source.startswith("linein"):
if self.source.startswith("http"):
self.cleanprotocol = self.source[:7]
self.cleansource = self.source
if self.source.startswith("pool") or self.source.startswith("file"):
elif self.source.startswith("linein"):
self.cleanprotocol = self.source[:9]
self.cleansource = self.source[9:]
elif self.source.startswith("pool") or self.source.startswith("file") or self.source.startswith("live"):
self.cleanprotocol = self.source[:7]
self.cleansource = self.source[7:]
if self.source.startswith("playlist"):
elif self.source.startswith("playlist"):
self.cleanprotocol = self.source[:11]
self.cleansource = self.source[11:]
else:
self.logger.error("Unknown source protocol")
def calc_unix_times(self):
if self.entry_start is not None:
self.entry_start_unix = time.mktime(self.entry_start.timetuple())
......@@ -173,6 +208,21 @@ class ScheduleEntry(DB.Model, AuraDatabaseModel):
return all_entries
@staticmethod
def select_act_programme(include_act_playing = True):
# fetching all from today to ..
today = datetime.date.today()
all_entries = DB.session.query(ScheduleEntry).filter(ScheduleEntry.entry_start >= today, ScheduleEntry.fallback_type == 0).order_by(ScheduleEntry.entry_start).all()
cnt = 0
for entry in all_entries:
entry.programme_index = cnt
cnt = cnt + 1
return all_entries
# ------------------------------------------------------------------------------------------ #
@staticmethod
def truncate():
......@@ -209,6 +259,17 @@ class ScheduleEntry(DB.Model, AuraDatabaseModel):
def select_playlist(playlist_id):
return DB.session.query(ScheduleEntry).filter(ScheduleEntry.playlist_id == playlist_id).all()
def getChannel(self):
if self.type == self.type.FILESYSTEM:
return "fs"
if self.type == self.type.LIVE:
return "aura_linein_"+self.cleansource # .cleanprotocol[8]
if self.type == self.type.STREAM:
return "http"
# ------------------------------------------------------------------------------------------ #
def __str__(self):
return "ScheduleID: #" + str(self.schedule_id) + " Showname: " + self.schedule.show_name + " starts @ " + str(self.entry_start) + " and plays " + self.source
......
"""
Database conn
"""
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
from sqlalchemy.ext.declarative import declarative_base
from flask_sqlalchemy import SQLAlchemy
......
# -*- coding: utf-8 -*-
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
import redis
import time
......
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
from enum import Enum
class TerminalColors(Enum):
HEADER = "\033[95m"
RED = "\033[31m"
GREEN = "\033[32m"
ORANGE = "\033[33m"
BLUE = "\033[34m"
PINK = "\033[35m"
CYAN = "\033[36m"
WARNING = "\033[31m"
FAIL = "\033[41m"
BOLD = "\033[1m"
UNDERLINE = "\033[4m"
ENDC = "\033[0m"
class RedisChannel(Enum):
STANDARD = "aura"
DPE_REPLY = "delete_playlist_entry_reply"
FNP_REPLY = "fetch_new_programme_reply"
GAP_REPLY = "get_act_programme_reply"
GCS_REPLY = "get_connection_status_reply"
IPE_REPLY = "insert_playlist_entry_reply"
IP_REPLY = "init_player_reply"
MPE_REPLY = "move_playlist_entry_reply"
PMQ_REPLY = "print_message_queue_reply"
RDB_REPLY = "recreate_database_reply"
SNF_REPLY = "get_next_file_reply"
class ScheduleEntryType(Enum):
FILESYSTEM = "fs"
STREAM = "http"
LIVE = "live"
\ No newline at end of file
from enum import Enum
class TerminalColors(Enum):
HEADER = "\033[95m"
RED = "\033[31m"
GREEN = "\033[32m"
ORANGE = "\033[33m"
BLUE = "\033[34m"
PINK = "\033[35m"
CYAN = "\033[36m"
WARNING = "\033[31m"
FAIL = "\033[41m"
BOLD = "\033[1m"
UNDERLINE = "\033[4m"
ENDC = "\033[0m"
\ No newline at end of file
from enum import Enum
class RedisChannel(Enum):
STANDARD = "aura"
DPE_REPLY = "delete_playlist_entry_reply"
FNP_REPLY = "fetch_new_programme_reply"
GAP_REPLY = "get_act_programme_reply"
GCS_REPLY = "get_connection_status_reply"
IPE_REPLY = "insert_playlist_entry_reply"
IP_REPLY = "init_player_reply"
MPE_REPLY = "move_playlist_entry_reply"
PMQ_REPLY = "print_message_queue_reply"
RDB_REPLY = "recreate_database_reply"
SNF_REPLY = "get_next_file_reply"
from enum import Enum
class ScheduleEntryType(Enum):
FILESYSTEM = "fs"
STREAM = "http"
LIVE = "live"
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
class NoProgrammeLoadedException(Exception):
pass
......
#
# engine
#
# Playout Daemon for autoradio project
#
#
# Copyright (C) 2017-2018 Gottfried Gaisbauer <gottfried.gaisbauer@servus.at>
#
# This file is part of engine.
#
# engine 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 3 of the License, or
# any later version.
#
# engine 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 engine. If not, see <http://www.gnu.org/licenses/>.
#
import simplejson
import logging
......