Skip to content

Instantly share code, notes, and snippets.

@Dygear
Last active June 11, 2018 06:39
Show Gist options
  • Save Dygear/11412cc06aab0b40f248956c804c5013 to your computer and use it in GitHub Desktop.
Save Dygear/11412cc06aab0b40f248956c804c5013 to your computer and use it in GitHub Desktop.
MimoCAD's Trunk-Recoder Implamentation
The NCPD.sh script works due to the [SSH (Silky Smooth Hopping)](https://youtu.be/vDbbz-BdyYc?t=9m40s).
The audioplayer.php file is re-written from the group up to ignore the directory structure.
All of the files are placed into the same audio directory underneth that script.
The NCPD.sh file, uploads files to that location.
<?php
$TGS = [
1 => 'KRX583',
2 => 'TAC2',
3 => '280 RPT',
4 => '280 MBR',
1101 => '1/7 Main',
1102 => '1/7 Admin',
1103 => '1/7 Detail',
1201 => '2/8 Main',
1202 => '2/8 Admin',
1203 => '2/8 Detail',
1301 => '3/6 Main',
1302 => '3/6 Admin',
1303 => '3/6 Detail',
1401 => '4/5 Main',
1402 => '4/5 Admin',
1403 => '4/5 Detail',
4001 => 'NCFD Batt 1',
4002 => 'NCFD Batt 2',
4003 => 'NCFD Batt 3',
4004 => 'NCFD Batt 4',
4005 => 'NCFD Batt 5',
4006 => 'NCFD Batt 6',
4007 => 'NCFD Batt 7',
4008 => 'NCFD Batt 8',
4009 => 'NCFD Batt 9',
4010 => 'VEMS Main',
4021 => 'Fire Marshals',
4099 => 'NCFD InterOp',
6001 => 'MEDCOM TG-1',
6002 => 'MEDCOM TG-2',
6003 => 'MEDCOM TG-3',
];
$date = (isset($_GET['date'])) ? new DateTimeImmutable($_GET['date']) : new DateTimeImmutable();
$TG = (empty($_GET['TG'])) ? NULL : $_GET['TG'];
$path = 'audio';
$directory = new DirectoryIterator($path);
$dayStart = $date->setTime( 0, 0, 0);
$dayEnd = $date->setTime(23, 59, 59);
$files = [];
if ($directory->isDir())
{
foreach ($directory as $item)
{
if (!$item->isFile())
continue;
$EXT = '.' . $item->getExtension();
if ($EXT != '.m4a')
continue;
list($TGID, $TIME, $FREQ) = preg_split('/[-_]/', $item->getBasename($EXT));
if ($TGID != $TG AND $TG !== NULL)
continue;
$time = (new DateTime())->createFromFormat('U', $TIME);
if ($time >= $dayStart AND $time <= $dayEnd)
$files[$item->getMTime()] = $item->key();
}
ksort($files);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Trunk Recorder</title>
<base id="myBase" href="/radio/<?=$path?>/">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="viewport" content="user-scalable=no, width=device-width">
<script>
function init() {
var index = 0,
audio = document.getElementById('audio'),
list = document.getElementById('list');
list.addEventListener('click', function (e) {
//e.preventDefault();
var mp3File = e.target.parentElement.getElementsByTagName('a')[0];
for (var i = 0; i < list.getElementsByTagName("a").length; i++) {
if (list.getElementsByTagName("a")[i] == mp3File) {
list.getElementsByTagName("div")[index].style.fontWeight = "normal";
index = i;
list.getElementsByTagName("div")[i].style.fontWeight = "bold";
var sources = document.getElementsByTagName('source');
sources[0].setAttribute('src', mp3File);
audio.load();
audio.play();
}
}
}, false);
audio.volume = 0.75;
audio.addEventListener('ended',function () {
if (index != (list.getElementsByTagName('div').length - 1)) {
list.getElementsByTagName("div")[index].style.fontWeight = "normal";
index++;
var mp3link = list.getElementsByTagName('div')[index];
var mp3File = mp3link.getElementsByTagName('a')[0];
var sources = document.getElementsByTagName('source');
sources[0].setAttribute('src',mp3File);
list.getElementsByTagName("div")[index].style.fontWeight = "bold";
audio.load();
audio.play();
}
}, false);
}
window.onload=init;
</script>
<style>
span {
padding-right: 10px;
display: table-cell;
max-width: 550px;
}
body {
font-family: Arial;
}
.note {
font-weight: bold;
margin-top: 150px;
}
#interface {
position: fixed;
background: white;
top: 0;
width: 100%;
}
#list {
display: table;
}
#list > div {
display: table-row;
}
</style>
</head>
<body>
<div id="interface">
<h1><?=(isset($TGS[$TG]) AND ($TG !== NULL)) ? $TGS[$TG] : "All Calls"?> on <?=$date->format('Y-m-d')?></h1>
<form method="get">
Date:
<input type="date" name="date" value="<?=$date->format('Y-m-d')?>" />
Talk Group:
<select name="TG">
<option value="">All Calls</option>
<?php foreach ($TGS as $TGID => $TGName): ?>
<option value="<?=$TGID?>"<?=($TG == $TGID) ? ' selected="selected"' : ''?>><?=$TGName?></option>
<?php endforeach; ?>
</select>
<input type="submit" value="Go">
</form>
<audio id="audio" preload="none" tabindex="0" controls>
<source type="audio/wav" src="http://www.lalarm.com/en/images/silence.wav" />
Sorry, your browser does not support HTML5 audio.
</audio>
</div>
<p class="note">Click on a row to begin sequential playback, click file size to download</p>
<div id="list">
<?php foreach ($files as $file):
$directory->seek($file);
$directory->current();
list($TGID, $TIME, $FREQ) = preg_split('/[-_]/', $directory->getBasename($EXT));
?>
<div>
<span><?=date("H:i:s", $TIME)?></span>
<span><?=($TGS[$TGID]) ?? $TGID?></span>
<span><?=sprintf("%3.6f", $FREQ / 1000000)?></span>
<span><a href="/radio/audio/<?=$directory?>"><?=round($directory->getSize() / 1024)?>k</a></span>
</div>
<?php endforeach; ?>
</div>
</body>
</html>
#!/bin/bash
#
# Uploads trunk-recorder files to MimoCAD Web Server
#
# Must have execute permission ('chmod +x NCPD.sh') and
# be located in the same directory as the ./recorder executable.
# Variables
FILENAME="$1"
BASENAME="${FILENAME%.*}"
ENCODED="$BASENAME.m4a"
JSON="$BASENAME.json"
echo "Encoding: $FILENAME"
eval "nice -n 19 /home/dygear/bin/ffmpeg -i $FILENAME -c:a libfdk_aac -b:a 32k -cutoff 18000 $ENCODED > /dev/null 2>&1"
echo "Upload: $ENCODED"
eval "scp $JSON $ENCODED MimoCAD:/var/www/mimocad/www/radio/audio/"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment