Merge pull request #121 from radiorabe/feature/restore-recording-feature-part-2
Fix recording through ecasound
This commit is contained in:
commit
e73a2941fd
|
@ -73,10 +73,6 @@ class Config {
|
||||||
|
|
||||||
$CC_CONFIG['apiKey'] = array($values['general']['api_key']);
|
$CC_CONFIG['apiKey'] = array($values['general']['api_key']);
|
||||||
|
|
||||||
if (defined('APPLICATION_ENV') && APPLICATION_ENV == "development"){
|
|
||||||
$CC_CONFIG['apiKey'][] = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
$CC_CONFIG['soundcloud-connection-retries'] = $values['soundcloud']['connection_retries'];
|
$CC_CONFIG['soundcloud-connection-retries'] = $values['soundcloud']['connection_retries'];
|
||||||
$CC_CONFIG['soundcloud-connection-wait'] = $values['soundcloud']['time_between_retries'];
|
$CC_CONFIG['soundcloud-connection-wait'] = $values['soundcloud']['time_between_retries'];
|
||||||
|
|
||||||
|
|
|
@ -642,25 +642,6 @@ class ApiController extends Zend_Controller_Action
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function uploadFileAction()
|
|
||||||
{
|
|
||||||
Logging::error("FIXME: Change the show recorder to use the File Upload API and remove this function."); // Albert - April 3, 2014
|
|
||||||
/**
|
|
||||||
$upload_dir = ini_get("upload_tmp_dir");
|
|
||||||
$tempFilePath = Application_Model_StoredFile::uploadFile($upload_dir);
|
|
||||||
$tempFileName = basename($tempFilePath);
|
|
||||||
|
|
||||||
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
|
|
||||||
$result = Application_Model_StoredFile::copyFileToStor($upload_dir, $fileName, $tempFileName);
|
|
||||||
|
|
||||||
if (!is_null($result)) {
|
|
||||||
$this->_helper->json->sendJson(
|
|
||||||
array("jsonrpc" => "2.0", "error" => array("code" => $result['code'], "message" => $result['message']))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
**/
|
|
||||||
}
|
|
||||||
|
|
||||||
public function uploadRecordedAction()
|
public function uploadRecordedAction()
|
||||||
{
|
{
|
||||||
$show_instance_id = $this->_getParam('showinstanceid');
|
$show_instance_id = $this->_getParam('showinstanceid');
|
||||||
|
|
|
@ -87,6 +87,8 @@ yum install -y \
|
||||||
fdk-aac \
|
fdk-aac \
|
||||||
liquidsoap \
|
liquidsoap \
|
||||||
silan \
|
silan \
|
||||||
|
ecasound \
|
||||||
|
alsa-utils \
|
||||||
icecast \
|
icecast \
|
||||||
python-pip \
|
python-pip \
|
||||||
selinux-policy \
|
selinux-policy \
|
||||||
|
@ -155,3 +157,6 @@ systemctl restart httpd
|
||||||
# icecast needs to be available to everyone
|
# icecast needs to be available to everyone
|
||||||
sed -i -e 's@<bind-address>127.0.0.1</bind-address>@<bind-address>0.0.0.0</bind-address>@' /etc/icecast.xml
|
sed -i -e 's@<bind-address>127.0.0.1</bind-address>@<bind-address>0.0.0.0</bind-address>@' /etc/icecast.xml
|
||||||
systemctl enable --now icecast
|
systemctl enable --now icecast
|
||||||
|
|
||||||
|
# let em use alsa
|
||||||
|
usermod -a -G audio apache
|
||||||
|
|
|
@ -10,6 +10,7 @@ import sys
|
||||||
import time
|
import time
|
||||||
import urllib
|
import urllib
|
||||||
import urllib2
|
import urllib2
|
||||||
|
import requests
|
||||||
import socket
|
import socket
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
@ -61,7 +62,7 @@ api_config['reload_metadata_group'] = 'reload-metadata-group/format/json/api_key
|
||||||
api_config['handle_watched_dir_missing'] = 'handle-watched-dir-missing/format/json/api_key/%%api_key%%/dir/%%dir%%'
|
api_config['handle_watched_dir_missing'] = 'handle-watched-dir-missing/format/json/api_key/%%api_key%%/dir/%%dir%%'
|
||||||
#show-recorder
|
#show-recorder
|
||||||
api_config['show_schedule_url'] = 'recorded-shows/format/json/api_key/%%api_key%%'
|
api_config['show_schedule_url'] = 'recorded-shows/format/json/api_key/%%api_key%%'
|
||||||
api_config['upload_file_url'] = 'upload-file/format/json/api_key/%%api_key%%'
|
api_config['upload_file_url'] = 'rest/media'
|
||||||
api_config['upload_retries'] = '3'
|
api_config['upload_retries'] = '3'
|
||||||
api_config['upload_wait'] = '60'
|
api_config['upload_wait'] = '60'
|
||||||
#pypo
|
#pypo
|
||||||
|
@ -278,33 +279,57 @@ class AirtimeApiClient(object):
|
||||||
self.logger.error(str(e))
|
self.logger.error(str(e))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def upload_recorded_show(self, data, headers):
|
def upload_recorded_show(self, files, show_id):
|
||||||
logger = self.logger
|
logger = self.logger
|
||||||
response = ''
|
response = ''
|
||||||
|
|
||||||
retries = int(self.config["upload_retries"])
|
retries = int(self.config["upload_retries"])
|
||||||
retries_wait = int(self.config["upload_wait"])
|
retries_wait = int(self.config["upload_wait"])
|
||||||
|
|
||||||
url = self.construct_url("upload_file_url")
|
url = self.construct_rest_url("upload_file_url")
|
||||||
|
|
||||||
logger.debug(url)
|
logger.debug(url)
|
||||||
|
|
||||||
for i in range(0, retries):
|
for i in range(0, retries):
|
||||||
logger.debug("Upload attempt: %s", i + 1)
|
logger.debug("Upload attempt: %s", i + 1)
|
||||||
|
logger.debug(files)
|
||||||
|
logger.debug(ApiRequest.API_HTTP_REQUEST_TIMEOUT)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
request = urllib2.Request(url, data, headers)
|
request = requests.post(url, files=files, timeout=float(ApiRequest.API_HTTP_REQUEST_TIMEOUT))
|
||||||
response = urllib2.urlopen(request, timeout=ApiClient.API_HTTP_REQUEST_TIMEOUT).read().strip()
|
response = request.json()
|
||||||
|
logger.debug(response)
|
||||||
|
|
||||||
logger.info("uploaded show result %s", response)
|
"""
|
||||||
|
FIXME: We need to tell LibreTime that the uploaded track was recorded for a specific show
|
||||||
|
|
||||||
|
My issue here is that response does not yet have an id. The id gets generated at the point
|
||||||
|
where analyzer is done with it's work. We probably need to do what is below in analyzer
|
||||||
|
and also make sure that the show instance id is routed all the way through.
|
||||||
|
|
||||||
|
It already gets uploaded by this but the RestController does not seem to care about it. In
|
||||||
|
the end analyzer doesn't have the info in it's rabbitmq message and imports the show as a
|
||||||
|
regular track.
|
||||||
|
|
||||||
|
logger.info("uploaded show result as file id %s", response.id)
|
||||||
|
|
||||||
|
url = self.construct_url("upload_recorded")
|
||||||
|
url = url.replace('%%fileid%%', response.id)
|
||||||
|
url = url.replace('%%showinstanceid%%', show_id)
|
||||||
|
request.get(url)
|
||||||
|
logger.info("associated uploaded file %s with show instance %s", response.id, show_id)
|
||||||
|
"""
|
||||||
break
|
break
|
||||||
|
|
||||||
except urllib2.HTTPError, e:
|
except requests.exceptions.HTTPError, e:
|
||||||
logger.error("Http error code: %s", e.code)
|
logger.error("Http error code: %s", e.code)
|
||||||
except urllib2.URLError, e:
|
logger.error("traceback: %s", traceback.format_exc())
|
||||||
|
except requests.exceptions.ConnectionError, e:
|
||||||
logger.error("Server is down: %s", e.args)
|
logger.error("Server is down: %s", e.args)
|
||||||
|
logger.error("traceback: %s", traceback.format_exc())
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logger.error("Exception: %s", e)
|
logger.error("Exception: %s", e)
|
||||||
|
logger.error("traceback: %s", traceback.format_exc())
|
||||||
|
|
||||||
#wait some time before next retry
|
#wait some time before next retry
|
||||||
time.sleep(retries_wait)
|
time.sleep(retries_wait)
|
||||||
|
@ -332,6 +357,19 @@ class AirtimeApiClient(object):
|
||||||
url = url.replace("%%api_key%%", self.config["general"]["api_key"])
|
url = url.replace("%%api_key%%", self.config["general"]["api_key"])
|
||||||
return url
|
return url
|
||||||
|
|
||||||
|
def construct_rest_url(self,config_action_key):
|
||||||
|
"""Constructs the base url for RESTful requests"""
|
||||||
|
if self.config["general"]["base_dir"].startswith("/"):
|
||||||
|
self.config["general"]["base_dir"] = self.config["general"]["base_dir"][1:]
|
||||||
|
url = "%s://%s:@%s:%s/%s/%s" % \
|
||||||
|
(str(("http", "https")[int(self.config["general"]["base_port"]) == 443]),
|
||||||
|
self.config["general"]["api_key"],
|
||||||
|
self.config["general"]["base_url"], str(self.config["general"]["base_port"]),
|
||||||
|
self.config["general"]["base_dir"],
|
||||||
|
self.config[config_action_key])
|
||||||
|
return url
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Caller of this method needs to catch any exceptions such as
|
Caller of this method needs to catch any exceptions such as
|
||||||
ValueError thrown by json.loads or URLError by urllib2.urlopen
|
ValueError thrown by json.loads or URLError by urllib2.urlopen
|
||||||
|
|
|
@ -95,7 +95,7 @@ class ShowRecorder(Thread):
|
||||||
self.logger.info("starting record")
|
self.logger.info("starting record")
|
||||||
self.logger.info("command " + command)
|
self.logger.info("command " + command)
|
||||||
|
|
||||||
self.p = Popen(args,stdout=PIPE)
|
self.p = Popen(args,stdout=PIPE,stderr=PIPE)
|
||||||
|
|
||||||
#blocks at the following line until the child process
|
#blocks at the following line until the child process
|
||||||
#quits
|
#quits
|
||||||
|
@ -129,11 +129,10 @@ class ShowRecorder(Thread):
|
||||||
# Register the streaming http handlers with urllib2
|
# Register the streaming http handlers with urllib2
|
||||||
register_openers()
|
register_openers()
|
||||||
|
|
||||||
# headers contains the necessary Content-Type and Content-Length
|
# files is what requests actually expects
|
||||||
# datagen is a generator object that yields the encoded parameters
|
files = {'file': open(filepath, "rb"), 'name': filename, 'show_instance': str(self.show_instance)}
|
||||||
datagen, headers = multipart_encode({"file": open(filepath, "rb"), 'name': filename, 'show_instance': self.show_instance})
|
|
||||||
|
|
||||||
self.api_client.upload_recorded_show(datagen, headers)
|
self.api_client.upload_recorded_show(files, self.show_instance)
|
||||||
|
|
||||||
def set_metadata_and_save(self, filepath):
|
def set_metadata_and_save(self, filepath):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue