themcgovern/content/posts/command-line-call.md
2024-06-23 23:55:59 -05:00

126 lines
No EOL
3.3 KiB
Markdown

+++
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
```bash
# 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)
```bash
# 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
```perl
#!/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.
```bash
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