+++ 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 6970 | aplay -f S16 -r 48000 - arecord -f S16 -r 48000 - | nc -u 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