Skip to content

Commit

Permalink
sample config, stream output rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBlackParrot committed Feb 8, 2016
1 parent 5ef1b49 commit 02efbf8
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 59 deletions.
6 changes: 1 addition & 5 deletions SYSTEM/metadata_upd
@@ -1,8 +1,4 @@
#!/bin/bash

sleep 5
curl -u "$ICADMIN_USER:$ICADMIN_PASS" --get --data "mount=/$ICMOUNT&mode=updinfo" --data-urlencode "song=$1" "http://$ICHOST:$ICPORT/admin/metadata"
curl -u "$ICADMIN_USER:$ICADMIN_PASS" --get --data "mount=/$ICMOUNT_LQ&mode=updinfo" --data-urlencode "song=$1" "http://$ICHOST:$ICPORT/admin/metadata"
curl -u "$ICADMIN_USER:$ICADMIN_PASS" --get --data "mount=/$ICMOUNT_OPUS&mode=updinfo" --data-urlencode "song=$1" "http://$ICHOST:$ICPORT/admin/metadata"
curl -u "$ICADMIN_USER:$ICADMIN_PASS" --get --data "mount=/$ICMOUNT_LQ_OPUS&mode=updinfo" --data-urlencode "song=$1" "http://$ICHOST:$ICPORT/admin/metadata"
curl -u "$ICADMIN_USER:$ICADMIN_PASS" --get --data "mount=/$ICMOUNT_EXP&mode=updinfo" --data-urlencode "song=$1" "http://$ICHOST:$ICPORT/admin/metadata"
curl -u "$ICADMIN_USER:$ICADMIN_PASS" --get --data "mount=/$2&mode=updinfo" --data-urlencode "song=$1" "http://$ICHOST:$ICPORT/admin/metadata"
73 changes: 43 additions & 30 deletions SYSTEM/streamer.php
Expand Up @@ -273,28 +273,6 @@ function strimmerLog($line) {
}
curl_close($curl);

$url_str = $row['RETURN_ARG3'] . " - " . $row['RETURN_ARG2'];

putenv("ICHOST=" . $icecast['host']);
putenv("ICPORT=" . $icecast['port']);
putenv("ICMOUNT=" . $icecast['mount']);
putenv("ICMOUNT_LQ=" . $icecast['mountlq']);
putenv("ICMOUNT_OPUS=" . $icecast['mount_opus']);
putenv("ICMOUNT_LQ_OPUS=" . $icecast['mountlq_opus']);
putenv("ICADMIN_USER=" . $icecast['admin_user']);
putenv("ICADMIN_PASS=" . $icecast['admin_pass']);

$icecast['mount_exp'] = "stream_experimental.mp3";
putenv("ICMOUNT_EXP=" . $icecast['mount_exp']);

// anything i'm trying to do involving escaping flat out fails, so i caved and i'm doing this -.-
$original_chars = array('\\','$','"');
$escaped_chars = array('\\\\','\$','\"');
$cmd_str = str_replace($original_chars, $escaped_chars, $url_str);
exec('./metadata_upd "' . $cmd_str . '" > /dev/null 2>&1 &');

strimmerLog("Updated stream metadata: $cmd_str");

$time = time();

$query = 'SELECT TRACKID FROM play_history';
Expand Down Expand Up @@ -330,19 +308,16 @@ function strimmerLog($line) {
// twurl cuts out tweets after ampersands
// hooraaaaay, ruby
$twurl_fix = str_replace("&", "and", $now_playing);

$truncated_np = mb_substr($twurl_fix, 0, 86, 'UTF-8');
$escaped_np = str_replace($original_chars, $escaped_chars, $truncated_np);

exec($twitter['twurl_location'] . '/twurl -q --raw-data "status=#NowPlaying ' . $escaped_np . ' on Strimmer http://' . $icecast['public_url'] . '" /1.1/statuses/update.json');
exec($twitter['twurl_location'] . '/twurl -q -d "status=#NowPlaying ' . $escaped_np . ' on Strimmer http://' . $icecast['public_url'] . '" /1.1/statuses/update.json');
}

$execStart = $icecast['ffmpeg'] . ' -hide_banner -re -i ';
switch($row['SERVICE']) {
case "MODA":
// considering filing an issue for URL support
// $execStart = 'dumbout -s 48000 -v 0.4 -o - \'' . $stream_link . '\' | ' . $execStart . '-';

$execStart = $icecast['ffmpeg'] . ' -hide_banner -re -f libmodplug -i ';
$execStart .= '\'' . $stream_link . '\'';
break;
Expand All @@ -351,8 +326,46 @@ function strimmerLog($line) {
$execStart .= '\'' . $stream_link . '\'';
break;
}
exec($execStart . ' -codec:a libmp3lame -vn -strict -2 -q ' . $icecast['qual'] . ' -content_type "audio/mpeg3" "icecast://source:' . $icecast['pass'] . '@' . $icecast['host'] . ':' . $icecast['port'] . '/' . $icecast['mount'] . '" -codec:a libmp3lame -vn -strict -2 -q ' . $icecast['quallq'] . ' -content_type "audio/mpeg3" "icecast://source:' . $icecast['pass'] . '@' . $icecast['host'] . ':' . $icecast['port'] . '/' . $icecast['mountlq'] . '" -codec:a libopus -vn -strict -2 -vbr on -compression_level 0 -frame_duration 40 -packet_loss 5 -b:a ' . $icecast['qual_opus'] . ' -content_type "audio/ogg" "icecast://source:' . $icecast['pass'] . '@' . $icecast['host'] . ':' . $icecast['port'] . '/' . $icecast['mount_opus'] . '" -codec:a libopus -vn -strict -2 -vbr on -compression_level 0 -frame_duration 40 -packet_loss 5 -b:a ' . $icecast['quallq_opus'] . ' -content_type "audio/ogg" "icecast://source:' . $icecast['pass'] . '@' . $icecast['host'] . ':' . $icecast['port'] . '/' . $icecast['mountlq_opus'] . '" -codec:a libmp3lame -vn -strict -2 -q ' . $icecast['qual'] . ' -content_type "audio/mpeg3" -filter "compand=0|0:0.2|0.2:-90/-900|-70/-70|-30/-9|0/-3:2:2.9:0:0" "icecast://source:' . $icecast['pass'] . '@' . $icecast['host'] . ':' . $icecast['port'] . '/' . $icecast['mount_exp'] . '" 1> /srv/http/strimmer-data/strimmer_ffmpeg_info.txt 2>&1');
// needed to start logging commands as of the YouTube update
//file_put_contents(dirname(__FILE__) . "/ffmpeg_log.txt",$icecast['ffmpeg'] . ' -hide_banner -re -i \'' . $stream_link . '\' -codec:a libmp3lame -vn -strict -2 -q ' . $icecast['qual'] . ' -content_type "audio/mpeg3" "icecast://source:' . $icecast['pass'] . '@' . $icecast['host'] . ':' . $icecast['port'] . '/' . $icecast['mount'] . '" -codec:a libmp3lame -vn -strict -2 -q ' . $icecast['quallq'] . ' -content_type "audio/mpeg3" "icecast://source:' . $icecast['pass'] . '@' . $icecast['host'] . ':' . $icecast['port'] . '/' . $icecast['mountlq'] . '" 1> ../includes/ffmpeg_info.txt 2>&1');

$final_command = $execStart;

$stream_count = count($stream['outputs']);
$stream_output_mounts = array_keys($stream['outputs']);

$url_str = $row['RETURN_ARG3'] . " - " . $row['RETURN_ARG2'];

putenv("ICHOST=" . $icecast['host']);
putenv("ICPORT=" . $icecast['port']);
putenv("ICADMIN_USER=" . $icecast['admin_user']);
putenv("ICADMIN_PASS=" . $icecast['admin_pass']);

// anything i'm trying to do involving escaping flat out fails, so i caved and i'm doing this -.-
$original_chars = array('\\','$','"');
$escaped_chars = array('\\\\','\$','\"');
$cmd_str = str_replace($original_chars, $escaped_chars, $url_str);

strimmerLog("Updated stream metadata: $cmd_str");

if(isset($stream['filter'])) {
if($stream['filter'] != "") {
$filter = $stream['filter'];

$filter = str_replace("%%STREAM_COUNT%%", $stream_count, $filter);
$filter = str_replace("%%STREAM_OUTPUTS_FILTER%%", "[" . implode("][", $stream_output_mounts) . "]", $filter);

$final_command .= " $filter";
}
}

foreach ($stream['outputs'] as $mount => $output) {
$final_output = str_replace("%%MOUNT%%", $mount, $output);
$final_command .= " $final_output";

$final_command .= ' "icecast://source:' . $icecast['pass'] . '@' . $icecast['host'] . ':' . $icecast['port'] . '/' . $mount . '"';

exec('./metadata_upd "' . $cmd_str . '" "' . $mount . '" > /dev/null 2>&1 &');
}

exec($final_command . ' 1> /srv/http/strimmer-data/strimmer_ffmpeg_info.txt 2>&1');
}
?>
78 changes: 78 additions & 0 deletions config.sample.php
@@ -0,0 +1,78 @@
<?php
// -- Program settings --
$prog_title = "Strimmer";
$prog_title_short = "strimmer";
$prog_internal_url = "https://strimmer.example.com";
date_default_timezone_set("America/Chicago");

// -- Email settings --
$email['alerts_enabled'] = true;
$email['to'] = "strimmer@example.com";
$email['from'] = "no-reply@example.com";

// -- Registration settings --
$register['require_verification'] = true;

// -- Strimmer log settings --
$logging['enabled'] = true;
$logging['dir'] = "SYSTEM/logs";
$logging['compress_old_logs'] = true;

// -- Session settings --
ini_set('session.gc_maxlifetime', 21600);
session_set_cookie_params(21600);

// -- SQL --
// hostname to connect to
$sql['host'] = "localhost";
$sql['port'] = 3306;
// SQL credentials
$sql['user'] = "sqluser";
$sql['pass'] = "hackme";
// database that stores info for the cache list
$sql['db'] = "strimmer";
// defines the SQL connection
$mysqli = new mysqli($sql['host'], $sql['user'], $sql['pass'], $sql['db'], $sql['port']);

// -- Icecast --
$icecast['host'] = "localhost";
// public facing url
$icecast['public_url'] = "radio.example.us";
$icecast['port'] = 8000;
// source password
$icecast['pass'] = "source_password";
$icecast['admin_user'] = "admin";
$icecast['admin_pass'] = "hackme";
// ffmpeg compatible transcoder
$icecast['ffmpeg'] = "ffmpeg";
// ffprobe compatible stream information viewer
$icecast['ffprobe'] = "ffprobe";

// Stream Outputs
$stream['outputs'] = [];
// recommended to use -filter_complex with "asplit=%%STREAM_COUNT%%%%STREAM_OUTPUTS_FILTER%%" at the end
// use "-map '[%%MOUNT%%]'" if using asplit
$stream['filter'] = '-filter_complex "compand=0|0:0.2|0.2:-90/-900|-70/-70|-30/-9|0/-3:2:1.33:0:0,asplit=%%STREAM_COUNT%%%%STREAM_OUTPUTS_FILTER%%"';
$stream['outputs']['mp3q6.mp3'] = "-map '[%%MOUNT%%]' -codec:a libmp3lame -vn -strict -2 -q 6";
$stream['outputs']['mp3q6m.mp3'] = "-map '[%%MOUNT%%]' -codec:a libmp3lame -vn -strict -2 -ar 32000 -ac 1 -q 6";
$stream['outputs']['opus64.opus'] = "-map '[%%MOUNT%%]' -codec:a libopus -vn -strict -2 -vbr on -compression_level 0 -frame_duration 40 -packet_loss 5 -b:a 64k -content_type 'audio/ogg'";
$stream['outputs']['opus48.opus'] = "-map '[%%MOUNT%%]' -codec:a libopus -vn -strict -2 -vbr on -compression_level 0 -frame_duration 40 -packet_loss 5 -b:a 48k -content_type 'audio/ogg'";
$stream['outputs']['opus32.opus'] = "-map '[%%MOUNT%%]' -codec:a libopus -vn -strict -2 -ac 1 -vbr on -compression_level 0 -frame_duration 40 -packet_loss 5 -b:a 32k -cutoff 12000 -content_type 'audio/ogg'";
$stream['outputs']['opus24.opus'] = "-map '[%%MOUNT%%]' -codec:a libopus -vn -strict -2 -ac 1 -vbr on -compression_level 0 -frame_duration 40 -packet_loss 5 -b:a 24k -cutoff 8000 -content_type 'audio/ogg'";
$stream['names'] = [];
$stream['names']['mp3q6.mp3'] = "MP3 VBR Q6";
$stream['names']['mp3q6m.mp3'] = "MP3 VBR Q6 (Mono)";
$stream['names']['opus64.opus'] = "Opus Audio 64k";
$stream['names']['opus48.opus'] = "Opus Audio 48k";
$stream['names']['opus32.opus'] = "Opus Audio 32k (Mono)";
$stream['names']['opus24.opus'] = "Opus Audio 24k (Mono)";

// Twurl
$twitter['enable'] = false;
$twitter['twurl_location'] = "/path/to/twurl/executable";

// API keys
// same key used in GET requests requiring client_id
$sc_api_key = "123ab4c5678de9f0ab1c23456789d0ef";
$jm_api_key = "ab0c1234";
$ma_api_key = "";
34 changes: 11 additions & 23 deletions includes/dialogs/listen.php
Expand Up @@ -6,29 +6,17 @@
<div class="dialog">
<span class="header">Listen</span>
<div class="dialog-buttons">
<form action="http://<?php echo "{$icecast['public_url']}:{$icecast['port']}/{$icecast['mount']}.m3u"; ?>" method="GET" id="mount">
<span class="button" onClick="document.getElementById('mount').submit();">MP3 Q6 (~115kbps)</span>
</form>
<br/>
<form action="http://<?php echo "{$icecast['public_url']}:{$icecast['port']}/{$icecast['mountlq']}.m3u"; ?>" method="GET" id="mount">
<span class="button" onClick="document.getElementById('mount').submit();">MP3 Q9 (~65kbps)</span>
</form>
<br/>
<form action="http://<?php echo "{$icecast['public_url']}:{$icecast['port']}/{$icecast['mount_opus']}.m3u"; ?>" method="GET" id="mount">
<span class="button" onClick="document.getElementById('mount').submit();">Opus Audio (48kbps)</span>
</form>
<br/>
<form action="http://<?php echo "{$icecast['public_url']}:{$icecast['port']}/{$icecast['mountlq_opus']}.m3u"; ?>" method="GET" id="mount">
<span class="button" onClick="document.getElementById('mount').submit();">Opus Audio (24kbps)</span>
</form>
<br/>
<form action="http://<?php echo "{$icecast['public_url']}:{$icecast['port']}/stream_experimental.mp3.m3u"; ?>" method="GET" id="mount">
<span class="button" onClick="document.getElementById('mount').submit();">Experimental (MP3 Q6)</span>
</form>
<br/>
The experimental stream uses dynamic range compression via an ffmpeg filter defined as:<br/>
<span style="font-family: monospace;">-filter "compand=0|0:0.2|0.2:-90/-900|-70/-70|-30/-9|0/-3:2:2.9:0:0"</span><br/>
This is an attempt at getting music much closer to the same volume level and to reduce quality loss artifacts.
<?php
foreach ($stream['names'] as $mount => $name) {
?>
<form action="http://<?php echo "{$icecast['public_url']}:{$icecast['port']}/$mount.m3u"; ?>" method="GET" id="mount">
<span class="button" onClick="document.getElementById('mount').submit();"><?php echo $name; ?></span>
</form>
<br/>
<?php
}
?>

<br/>
<br/>
AAC streams may be available in the future.<br/><br/>
Expand Down
2 changes: 1 addition & 1 deletion includes/settings.php
@@ -1,5 +1,5 @@
<?php
$strimmerVersion = "0.17.1-2";
$strimmerVersion = "0.18.0-1";
if (!@include(dirname(dirname(__FILE__)) . "/config.php"))
{
include dirname(__FILE__) . "/setup-config.php";
Expand Down

0 comments on commit 02efbf8

Please sign in to comment.