3.3 KiB
3.3 KiB
+++ title = 'Command Line Call' date = 2024-05-27T20:15:23-05:00 draft = true +++
Calling from the command line
I was thinking about setting up Jitsi recently and have been researching internet audio and video calling.
One to one example code
# Record audio and send it to whatever's listening on 127.0.0.1:6969
arecord -f S16 -r 48000 - | nc -u 127.0.0.1 6969
# Receive audio from port 6969 and play it
nc -lvp 6969 | aplay -f S16 -r 48000 -
Multiple people chat example
Client(s)
# Record audio and send it to whatever's listening on 127.0.0.1:6969
#arecord -f S16 -r 48000 - | nc -u 127.0.0.1 6969
# Receive audio from port 6969 and play it
#nc -u <server> 6970 | aplay -f S16 -r 48000 -
arecord -f S16 -r 48000 - | nc -u <server> 6969 | aplay -f S16 -r 48000 -
Server
#!/usr/bin/env perl
use v5.36;
use IO::Socket::INET;
use Time::HiRes 'gettimeofday';
my $listen_addr = "0.0.0.0";
my $port = 6969;
my $udp_max_datagram_size = 65535;
my $sample_rate = 48000;
my $sample_template = "s";
my $last_time;
my $buffer;
sub fit_together($audio_in) {
my @temp1 = unpack "$sample_template*", $buffer;
my @temp2 = unpack "$sample_template*", $audio_in;
my $time_diff = gettimeofday() - $last_time;
my $sample_skip = floor($time_diff * $sample_rate);
@temp1 = @temp1[ $sample_skip .. $#temp1 ];
while ($#temp1 < $#temp2) {
push @temp1, 0;
}
while ($#temp2 < $#temp1) {
push @temp2, 0;
}
$last_time = gettimeofday();
return (@temp1, @temp2);
}
sub process_audio_in($peer, $audio_in) {
if(not $last_time) {
$last_time = gettimeofday();
$buffer = $audio_in;
} else {
my (@temp1, @temp2) = fit_together($audio_in);
$buffer = pack "$sample_template*",
map {
my $addition = $temp1[$_]+$temp2[$_];
if($addition > $sample_max) {
$sample_max
} elsif($addition < $sample_min) {
$sample_min
} else {
$addition
}
} 0..$#temp1;
}
}
my $sock = IO::Socket::INET->new(
LocalAddr => "$listen_addr:$port",
Proto => "udp"
) or die "INET Socket no work :( $@";
say "Listening for clients on addr $listen_addr:$port";
while("humanity" != "extinct") {
my $audio_data_in = eval {
$sock->recv($udp_max_datagram_size) or die "INET Socket recv() fail: $!";
};
if ($@) {
say "Peer ".$sock->peername." sent invalid request, skipping: $@";
next;
}
process_audio($sock->peername, $audio_data_in);
eval {
$sock->send($buffer, $#next_packet) or die "INET Socket recv() fail: $!";
}
if ($@) {
say "Failed to send audio packet to ".$sock->peername.": $@";
}
}
The issue with this is that it's not private or anonymous. My attempts to tackle these issues is detailed below:
Making it secure
Anonymity and privacy can be easily added by simply running nc with torsocks
on the sending end and running nc
behind tor
on the receiving end. i2p could also probably be used for this.
arecord -f S16 -r 48000 - | torsocks nc example.onion 6969
The audio will be anonymous due to tor's design. The audio will also be encrypted by the hidden service tunnel.
Authentication
TOR Access Keys